changeset 3:5a977ccbc7a9 default tip

Empty changelog
author darius
date Sat, 06 Dec 1997 05:41:29 +0000 (1997-12-06)
parents fba0b6e6cdc7
children
files defs.h defwin.c detonate.c distress.c dmessage.c emph_planet_seq.h emph_player_seq.h emph_player_seql.h enter.c expire.c feature.c findslot.c gameconf.c gameconf.h getname.c getship.c gppackets.h helpwin.c hockey.c hullbitmaps.h icon.xbm inform.c input.c interface.c keymap.c macros.c macrowin.c main.c motdwin.c netrek.paradise newwin.c oldbitmaps.h option.c packets.c packets.h paradise.sndsrv.freebsd.c paradise.sndsrv.hp.c paradise.sndsrv.linux.c paradise.sndsrv.sun.c parsemeta.c ping.c pingstats.c planetbitmaps.h planetlist.c planets.c playerlist.c proto.h puck.h rabbitbitmaps.h ranklist.c ratings.c recorder.c redraw.c reserved.c rotate.c sample.xtrekrc senddist.c shipbitmaps.c shortcomm.c sintab.c smessage.c socket.c sound.c sound.h spopt.c starbitmaps.h stats.c struct.h time.c tools.c udpopt.c util.c varydamage.c war.c warning.c wide_plist.c wtext.h x11window.c zlib/ChangeLog zlib/Makefile zlib/Makefile.bor zlib/Makefile.msc zlib/Makefile.tc zlib/README zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/deflate.c zlib/deflate.h zlib/example.c zlib/gzio.c zlib/infblock.c zlib/infblock.h zlib/infcodes.c zlib/infcodes.h zlib/inffast.c zlib/inffast.h zlib/inflate.c zlib/inftrees.c zlib/inftrees.h zlib/infutil.c zlib/infutil.h zlib/minigzip.c zlib/trees.c zlib/uncompr.c zlib/zconf.h zlib/zlib.h zlib/zutil.c zlib/zutil.h
diffstat 109 files changed, 44146 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/defs.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,415 @@
+/* $Id: defs.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * defs.h
+ */
+
+#ifndef defs_h_
+#define defs_h_
+
+#include "copyright.h"
+
+#define MAX_PLAYER 257		/* Maximum number of players we can configure
+				   the game for, not the server's max
+				   players.  */
+
+#ifdef HOCKEY
+/* defs for hockey [BDyess] */
+#define NUM_HOCKEY_LINES 13
+#endif /*HOCKEY*/
+
+#ifdef SIZE_LOGGING
+/* redefine EXIT as print totals followed by a normal exit [BDyess] */
+#define EXIT(x) {print_totals();exit(x);}
+#else
+#define EXIT exit
+#endif				/* SIZE_LOGGING */
+
+/* defs for new message window data structure [BDyess] */
+#define WREVIEW		0
+#define WTEAM		1
+#define WINDIV		2
+#define WKILL		3
+#define WPHASER		4
+#define WALL		5
+#define WNUM		6
+/* message window allow mask */
+#define WA_TEAM		1
+#define WA_INDIV	2
+#define WA_KILL		4
+#define WA_PHASER	8
+#define WA_ALL		16
+#define WA_REVIEW	32
+#define WA_MACRO        64
+
+/* defs for updatePlayer [BDyess] */
+#define NO_UPDATE	0
+#define SMALL_UPDATE	1	/* update non-blk_bozo players */
+#define LARGE_UPDATE	2	/* update blk_bozo players     */
+#define ALL_UPDATE	(SMALL_UPDATE|LARGE_UPDATE)	/* update both */
+
+/* defs for terrain */
+#define TERRAIN_STARTED 1
+#define TERRAIN_DONE    2
+
+/* defs for timer [BDyess] */
+#define T_NONE		0	/* no timer */
+#define T_DAY		1	/* time of day */
+#define T_SERVER	2	/* time on server */
+#define T_SHIP		3	/* time in ship */
+#define T_USR		4	/* user reset timer */
+#define T_TOTAL		5	/* number of T_ defs */
+#define TIMESTRLEN	10	/* used in db_timer(), timeString() */
+				/* */
+
+/* defs for mapmode */
+#define GMAP_NEVER	0
+#define GMAP_FREQUENT 	1
+#define GMAP_INFREQUENT	2
+
+#ifdef METASERVER
+/* metaserver window defs */
+#define LINE 80
+#define METASERVERADDRESS "metaserver.ecst.csuchico.edu"	/* new metaserver */
+#define METAPORT 3521		/* HAVE to use nicely formated version */
+#define KEY 3
+#endif				/* METASERVER */
+
+#define MAX_PLANETS 257
+
+#define WINSIDE 500		/* Size of strategic and tactical windows */
+#define BORDER 4		/* border width for option windows */
+#define PSEUDOSIZE 16
+#define CLOAK_PHASES 7		/* number of drawing phases in a cloak
+				   engage/disengage */
+#define NUMRANKS 9		/* old netrek ranks */
+/*#define NUMRANKS2 18*/
+
+/* These are configuration definitions */
+
+#define GWIDTH 200000		/* galaxy is 200000 spaces on a side */
+#define WARP1 20		/* warp one will move 20 spaces per update */
+#define SCALE 40		/* Window will be one pixel for 20 spaces */
+#define EXPDIST 350		/* At this range a torp will explode */
+#define GRIDSIZE 33333
+
+#define DETDIST 1600		/* At this range a player can detonate a torp */
+
+#define PHASEDIST 6000		/* At this range a player can do damage with
+				   phasers */
+#define ENTORBDIST 900		/* At this range a player can orbit a planet */
+#define ORBDIST 800		/* A player will orbit at this radius */
+#define ORBSPEED 2		/* This is the fastest a person can go into
+				   orbit */
+#define PFIREDIST 1500		/* At this range a planet will shoot at a
+				   player */
+#define UPDATE 100000		/* Update time is 100000 micro-seconds */
+
+#define AUTOQUIT 60		/* auto logout in 60 secs */
+
+#define VACANT -1		/* indicates vacant port on a starbase */
+#define DOCKDIST 600
+#define DOCKSPEED 2		/* If base is moving, there will be some
+				   finesse involved to dock */
+#define NUMPORTS 4
+#define SBFUELMIN 10000		/* If starbase's fuel is less than this, it
+				   will not refuel docked vessels */
+#define TRACTDIST   6000	/* maximum effective tractor beam range */
+#define TRACTEHEAT  5		/* ammount tractor beams heat engines */
+#define TRACTCOST   20		/* fuel cost of activated tractor beam */
+
+/* These are memory sections */
+#define PLAYER 1
+#define MAXMESSAGE 50
+#define MAXREVIEWMESSAGE 20
+
+#ifdef SVR4
+#define MCOPY(b1,b2,l) memcpy(b2,b1,l)
+#else
+#define MCOPY(b1,b2,l) bcopy(b1,b2,l)
+#endif
+#define rosette(x, ndiv)   (( (((x)&0xff) + 0x100/(2*(ndiv))) * (ndiv)/0x100 ) % ndiv)
+
+/* These are the teams */
+/* Note that I used bit types for these mostly for messages and
+   war status.  This was probably a mistake.  It meant that Ed
+   had to add the 'remap' area to map these (which are used throughout
+   the code as the proper team variable) into a nice four team deep
+   array for his color stuff.  Oh well.
+*/
+#define NOBODY 0x0
+#define FEDi 0
+#define ROMi 1
+#define KLIi 2
+#define ORIi 3
+ /* #define ALLTEAMi 4 *//* replaced by number_of_teams */
+#define FEDm 0x1
+#define ROMm 0x2
+#define KLIm 0x4
+#define ORIm 0x8
+#define ALLTEAM ( (1<<number_of_teams) - 1)
+ /*#define MAXTEAM 3 *//* number_of_teams -1 */
+ /*#define NUMTEAM 4 *//* number_of_teams */
+/*
+** These are random configuration variables
+*/
+#define VICTORY 3		/* Number of systems needed to conquer the
+				   galaxy */
+#define WARNTIME 30		/* Number of updates to have a warning on the
+				   screen */
+#define MESSTIME 30		/* Number of updates to have a message on the
+				   screen */
+
+/* Flags for gettarget */
+#define TARG_SHIP	(1<<0)
+#define TARG_BASE	(1<<1)
+#define TARG_PLANET	(1<<2)
+#define TARG_CLOAK	(1<<3)	/* Include cloaked ships in search */
+#define TARG_SELF	(1<<4)
+#define TARG_ENEMY	(1<<5)	/* enemy ships/planets only */
+#define TARG_FRIENDLY   (1<<6)	/* friendly ships/planets only */
+#define TARG_TEAM	(1<<7)	/* same team */
+#define TARG_STAR	(1<<8)
+#define TARG_NEBULA	(1<<9)
+#define TARG_BLACKHOLE  (1<<10)
+
+#define TARG_PLAYER	(TARG_SHIP|TARG_BASE)
+#define TARG_ASTRAL	(TARG_PLANET|TARG_STAR|TARG_NEBULA|TARG_BLACKHOLE)
+
+#define DEFAULT_SERVER	"cassius.cs.uiuc.edu"
+#define DEFAULT_PORT	2592
+
+#define hypot(x,y)	sqrt((x)*(x)+(y)*(y))
+
+#define ABS(a)			/* abs(a) */ (((a) < 0) ? -(a) : (a))
+#ifndef MAX
+#define MAX(a,b)		((a) > (b) ? (a) : (b))
+#endif
+
+#define myPlasmaTorp(t)		(me->p_no == (t)->pt_owner)
+#define myTorp(t)		(me->p_no == (t)->t_owner)
+#define friendlyPlasmaTorp(t)	((!(idx_to_mask(me->p_teami) & (t)->pt_war)) || (myPlasmaTorp(t)))
+#define friendlyTorp(t)		((!(idx_to_mask(me->p_teami) & (t)->t_war)) || (myTorp(t)))
+#define myPhaser(p)		(&phasers[me->p_no] == (p))
+#define friendlyPhaser(p)	(me->p_teami == players[(p) - phasers].p_teami)
+#define myPlayer(p)		(me == (p))
+#define myPlanet(p)		(me->p_teami == mask_to_idx((p)->pl_owner))
+#define friendlyPlayer(p)	((!(idx_to_mask(me->p_teami) & \
+				    ((p)->p_swar | (p)->p_hostile))) && \
+				    (!(idx_to_mask((p)->p_teami) & \
+				    (me->p_swar | me->p_hostile))))
+#define isAlive(p)		((p)->p_status == PALIVE)
+#define isPlaying(p)		((p)->p_status != PFREE)
+#define isBase(num)		((num)==STARBASE || (num)==WARBASE || \
+				 (num)==JUMPSHIP)
+#define friendlyPlanet(p)	((p)->pl_info & idx_to_mask(me->p_teami) && \
+			     !((p)->pl_owner & (me->p_swar | me->p_hostile)))
+
+#define isLockPlanet(p)		((me->p_flags & PFPLLOCK) && (me->p_planet == p->pl_no))
+#define isLockPlayer(p)		((me->p_flags & PFPLOCK) && (me->p_playerl == p->p_no))
+#define PtOutsideWin(x, y)      	(x < 0 || x > WINSIDE || y < 0 || y > WINSIDE)	/* TSH */
+
+#define torpColor(t)		\
+	(myTorp(t) ? myColor : shipCol[1+players[(t)->t_owner].p_teami])
+#define droneColor(t)		\
+	(myTorp(t) ? myColor : shipCol[1+players[(t)->t_owner].p_teami])
+#define plasmatorpColor(t)		\
+	(myPlasmaTorp(t) ? myColor : shipCol[1+players[(t)->pt_owner].p_teami])
+#define phaserColor(p)		\
+	(myPhaser(p) ? myColor : shipCol[1+players[(p) - phasers].p_teami])
+/*
+ * Cloaking phase (and not the cloaking flag) is the factor in determining
+ * the color of the ship.  Color 0 is white (same as 'myColor' used to be).
+ */
+#define playerColor(p)		\
+	(myPlayer(p) ? myColor : shipCol[1+(p)->p_teami])
+#define planetColor(p)		\
+	(((p)->pl_info & idx_to_mask(me->p_teami)) ? shipCol[1+mask_to_idx((p)->pl_owner)] : unColor)
+
+#define planetFont(p)		\
+	(myPlanet(p) ? W_BoldFont : friendlyPlanet(p) ? W_UnderlineFont \
+	    : W_RegularFont)
+#define shipFont(p)		\
+	(myPlayer(p) ? W_BoldFont : friendlyPlayer(p) ? W_UnderlineFont \
+	    : W_RegularFont)
+#define bombingRating(p)	\
+	((float) (p)->p_stats.st_tarmsbomb * status->timeprod / \
+	 ((float) (p)->p_stats.st_tticks * status->armsbomb))
+#define planetRating(p)		\
+	((float) (p)->p_stats.st_tplanets * status->timeprod / \
+	 ((float) (p)->p_stats.st_tticks * status->planets))
+#define offenseRating(p)	\
+	((float) (p)->p_stats.st_tkills * status->timeprod / \
+	 ((float) (p)->p_stats.st_tticks * status->kills))
+#define defenseRating(p)	\
+	((float) (p)->p_stats.st_tticks * status->losses / \
+	 ((p)->p_stats.st_tlosses!=0 ? \
+	  ((float) (p)->p_stats.st_tlosses * status->timeprod) : \
+	  (status->timeprod)))
+
+#ifdef SVR4			/* to get it to work under Solaris */
+#define srandom srand48
+#define bcopy(s,d,l) memmove((d),(s),(l))
+#define bzero(s,l) memset((s),(char)0,(l))
+#define random lrand48
+#define rindex(s,c) strrchr((s),(c))
+#endif				/* SVR4 */
+
+#ifdef ROTATERACE
+#define sendTorpReq(dir) sendShortPacket(CP_TORP, RotateDirSend(dir))
+#define sendPhaserReq(dir) sendShortPacket(CP_PHASER, RotateDirSend(dir))
+#define sendDirReq(dir) sendShortPacket(CP_DIRECTION, RotateDirSend(dir))
+#define sendPlasmaReq(dir) sendShortPacket(CP_PLASMA, RotateDirSend(dir))
+#else
+#define sendTorpReq(dir) sendShortPacket(CP_TORP, dir)
+#define sendPhaserReq(dir) sendShortPacket(CP_PHASER, dir)
+#define sendDirReq(dir) sendShortPacket(CP_DIRECTION, dir)
+#define sendPlasmaReq(dir) sendShortPacket(CP_PLASMA, dir)
+#endif				/* ROTATERACE */
+
+#define sendSpeedReq(speed) sendShortPacket(CP_SPEED, speed)
+#define sendShieldReq(state) sendShortPacket(CP_SHIELD, state)
+#define sendOrbitReq(state) sendShortPacket(CP_ORBIT, state)
+#define sendRepairReq(state) sendShortPacket(CP_REPAIR, state)
+#define sendBeamReq(state) sendShortPacket(CP_BEAM, state)
+#define sendCopilotReq(state) sendShortPacket(CP_COPILOT, state)
+#define sendDetonateReq() sendShortPacket(CP_DET_TORPS, 0)
+#define sendCloakReq(state) sendShortPacket(CP_CLOAK, state)
+#define sendBombReq(state) sendShortPacket(CP_BOMB, state)
+#define sendPractrReq() sendShortPacket(CP_PRACTR, 0)
+#define sendWarReq(mask) sendShortPacket(CP_WAR, mask)
+#define sendRefitReq(ship) sendShortPacket(CP_REFIT, ship)
+#define sendPlaylockReq(pnum) sendShortPacket(CP_PLAYLOCK, pnum)
+#define sendPlanlockReq(pnum) sendShortPacket(CP_PLANLOCK, pnum)
+#define sendCoupReq() sendShortPacket(CP_COUP, 0)
+#define sendQuitReq() sendShortPacket(CP_QUIT, 0)
+#define sendByeReq() sendShortPacket(CP_BYE, 0)
+#define sendDockingReq(state) sendShortPacket(CP_DOCKPERM, state)
+#define sendResetStatsReq(verify) sendShortPacket(CP_RESETSTATS, verify)
+#ifdef ATM
+#define sendScanReq(who) sendShortPacket(CP_SCAN, who)	/* ATM */
+#endif				/* ATM */
+
+/* This macro allows us to time things based upon # frames / sec.
+ */
+#define ticks(x) ((x)*200000/timerDelay)
+
+char   *getdefault();
+
+#ifdef ATM
+/*
+ * UDP control stuff
+ */
+#ifdef GATEWAY
+#define UDP_NUMOPTS    11
+#define UDP_GW         UDP_NUMOPTS-1
+#else
+#define UDP_NUMOPTS    10
+#endif
+#define UDP_CURRENT     0
+#define UDP_STATUS      1
+#define UDP_DROPPED     2
+#define UDP_SEQUENCE    3
+#define UDP_SEND	4
+#define UDP_RECV	5
+#define UDP_DEBUG       6
+#define UDP_FORCE_RESET	7
+#define UDP_UPDATE_ALL	8
+#define UDP_DONE        9
+#define COMM_TCP        0
+#define COMM_UDP        1
+#define COMM_VERIFY     2
+#define COMM_UPDATE	3
+#define COMM_MODE	4
+#define SWITCH_TCP_OK   0
+#define SWITCH_UDP_OK   1
+#define SWITCH_DENIED   2
+#define SWITCH_VERIFY   3
+#define CONNMODE_PORT   0
+#define CONNMODE_PACKET 1
+#define STAT_CONNECTED  0
+#define STAT_SWITCH_UDP 1
+#define STAT_SWITCH_TCP 2
+#define STAT_VERIFY_UDP 3
+#define MODE_TCP        0
+#define MODE_SIMPLE     1
+#define MODE_FAT	2
+#define MODE_DOUBLE     3
+
+#define UDP_RECENT_INTR 300
+#define UDP_UPDATE_WAIT	5
+
+/* client version of UDPDIAG */
+#define UDPDIAG(x)      { if (udpDebug) { printf("UDP: "); printf x; }}
+#define V_UDPDIAG(x)    UDPDIAG(x)
+#endif				/* ATM */
+
+#define RSA_VERSION "RSA v2.0 CLIENT"	/* string must begin with characters
+					   "RSA v" */
+#define KEY_SIZE 32
+#define RESERVED_SIZE 16
+#define MSG_LEN 80
+#define NAME_LEN 16
+#define KEYMAP_LEN 96
+
+#ifdef ROTATERACE
+#define RotateDirSend(d)        (rotate?d-rotate_deg:d)
+#endif
+
+#ifdef SHORT_PACKETS
+#define         SPK_VOFF        0	/* variable packets off */
+#define         SPK_VON         1	/* variable packets on */
+#define         SPK_MOFF        2	/* message packets off */
+#define         SPK_MON         3	/* message packets on */
+#define         SPK_M_KILLS     4	/* send kill mesgs */
+#define         SPK_M_NOKILLS   5	/* don't send kill mesgs */
+#define         SPK_THRESHOLD   6	/* threshold */
+#define         SPK_M_WARN      7	/* warnings */
+#define         SPK_M_NOWARN    8	/* no warnings */
+#define SPK_SALL 9		/* only planets,kills and weapons */
+#define         SPK_ALL 10	/* Full Update - SP_STATS */
+
+#define         SPK_NUMFIELDS   7
+
+#define         SPK_VFIELD      0
+#define         SPK_MFIELD      1
+#define         SPK_KFIELD      2
+#define         SPK_WFIELD      3
+#define         SPK_TFIELD      4
+#define         SPK_WHYFIELD    5
+#define         SPK_DONE        6
+#endif
+
+#ifdef TOOLS
+#define TOOLSWINLEN 25
+#endif
+
+#ifdef BEEPLITE
+#define LITE_PLAYERS_MAP	0x01
+#define LITE_PLAYERS_LOCAL	0x02
+#define LITE_SELF		0x04
+#define LITE_PLANETS		0x08
+#define LITE_SOUNDS		0x10
+#define LITE_COLOR              0x20
+#endif
+
+#ifdef AMIGA
+#include "amigadefs.h"
+#else
+#define sock_write		write
+#define sock_close		close
+#define sock_ioctl		ioctl
+#endif				/* AMIGA */
+
+#ifdef RECORDER
+#define PB_REDALERT -1
+#define PB_YELLOWALERT -2
+#define PB_DEATH -3
+#endif
+
+#if defined (sgi) || defined (__FreeBSD__) || defined (__NetBSD__)
+#define strcmpi strcasecmp
+#define strncmpi strncasecmp
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/defwin.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1023 @@
+/* $Id: defwin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#ifdef XTREKRC_HELP
+/*
+ * taken from helpwin.c
+ * (copyright 1991 ERic mehlhaff Free to use, hack, etc. Just keep
+ *  these credits here. Use of this code may be dangerous to your health
+ *  and/or system. Its use is at your own risk. I assume no responsibility for
+ *  damages, real, potential, or imagined, resulting  from the use of it.)
+ *
+ */
+
+#include <stdio.h>
+#include "math.h"
+#include <signal.h>
+#include <sys/types.h>
+#ifdef hpux
+#include <time.h>
+#else				/* hpux */
+#include <sys/time.h>
+#endif				/* hpux */
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "proto.h"
+#include "data.h"
+#ifndef SVR4
+#include <strings.h>
+#else
+#include <string.h>
+#endif
+
+void def_write 
+P((char *file));
+
+/* this is the number of help messages there are */
+
+#define INT_DEF		0
+#define BOOL_DEF	1
+#define STR_DEF		2
+#define SINT_DEF	3
+
+#define NAME_WIDTH	18
+#define VAL_WIDTH	8
+#define INDENT		3
+#define MAX_VLINES	58
+
+extern int updateSpeed;
+#ifdef RECORD
+extern char *recordFileName;
+#endif
+
+#define DEFMESSAGES	(sizeof(def_messages)/ sizeof(struct def))
+
+char   *name = NULL, *cloak_chars = NULL, *bmap = NULL, *keymap = NULL, *plist = NULL, *log_file = NULL, *saveFileName = NULL;
+int     galacticFrequent;
+
+/* sure its a mess, but it gets the job done */
+
+static
+struct def {
+    char   *name;
+    int     type;
+    char   *desc;
+    void   *variable;
+
+    struct {
+	int     i_value;	/* if int or bool */
+	char   *s_value;	/* if str */
+	char   *desc;
+    }       values[10];
+
+    struct {			/* the area of the window this def takes up */
+	int     x, y, rt, bot;
+    }       loc;
+}       def_messages[] = {
+
+#ifdef AUTHORIZE
+    {
+	"useRSA", BOOL_DEF, "Use RSA checking",
+	&RSA_Client,
+        {
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#endif
+    {
+	"showStats", BOOL_DEF, "Show stats window",
+	&showStats,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showShields", BOOL_DEF, "Show shields around ship",
+	&showShields,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"keepPeace", BOOL_DEF, "Stay peaceful when reborn",
+	&keeppeace,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"reportKills", BOOL_DEF, "Report kill messages",
+	&reportKills,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#if 0
+    {
+	"altBitmaps", BOOL_DEF, "Use alternate ship bitmaps",
+	&blk_altbits,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#endif
+    {
+	"showStars", BOOL_DEF, "Show star background on tactical",
+	&blk_showStars,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showMySpeed", BOOL_DEF, "Show speed next to ship",
+	&showMySpeed,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showTractorPressor", BOOL_DEF, "Show my tract/press",
+	&showTractorPressor,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showLock", INT_DEF, "Lock display for planets/players",
+	&showLock,
+	{
+	    {
+		0, NULL, "don't show lock"
+	    },
+	    {
+		1, NULL, "show lock on galactic only"
+	    },
+	    {
+		2, NULL, "show lock on tactical only"
+	    },
+	    {
+		3, NULL, "show lock on both"
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	}
+    },
+    {
+	"showGrid", BOOL_DEF, "Show grid on galactic",
+	&drawgrid,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"Dashboard", INT_DEF, "Type of dashboard to use",
+	&Dashboard,
+	{
+	    {
+		0, NULL, "text based dashboard"
+	    },
+	    {
+		1, NULL, "new dashboard"
+	    },
+	    {
+		2, NULL, "color dashboard"
+	    },
+	    {
+		3, NULL, "Rainbow Dashboard"
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	}
+    },
+    {
+	"cloakChars", STR_DEF, "Cloak chars for map",
+	&(cloak_chars),
+	{
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"logging", BOOL_DEF, "Use message logging",
+	&logmess,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"logFile", STR_DEF, "File to use for message logging",
+	&(log_file),
+	{
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#ifdef VARY_HULL
+    {
+	"warnHull", BOOL_DEF, "Warn hull state based on damage",
+	&vary_hull,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#endif
+    {
+	"warpStreaks", BOOL_DEF, "Streak stars when entering warp",
+	&warpStreaks,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"useMsgw", BOOL_DEF, "Use message window",
+	&use_msgw,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showShieldDam", BOOL_DEF, "Vary shields based on damage",
+	&show_shield_dam,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"updatesPerSec", SINT_DEF, "No. of updates from server per sec",
+	&updateSpeed,
+	{
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"redrawDelay", SINT_DEF, "Minimum time between redraws (x/10 sec)",
+	&redrawDelay,
+	{
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"extraAlertBorder", BOOL_DEF, "Show alert on local border",
+	&extraBorder,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"galacticFrequent", BOOL_DEF, "Update galactic map frequently",
+	&galacticFrequent,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#ifdef CONTINUOUS_MOUSE
+    {
+	"continuousMouse", BOOL_DEF, "Continuous mouse input",
+	&continuousMouse,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#endif
+    {
+	"tryUdp", BOOL_DEF, "Try UDP automatically",
+	&tryUdp,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"udpClientReceive", INT_DEF, "UDP receive mode",
+	&udpClientRecv,
+	{
+	    {
+		0, NULL, "TCP only"
+	    },
+	    {
+		1, NULL, "simple UDP"
+	    },
+	    {
+		2, NULL, "fat UDP"
+	    },
+	    {
+		3, NULL, "double UDP (obsolete)"
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"udpClientSend", INT_DEF, "UDP send mode",
+	&udpClientSend,
+	{
+	    {
+		0, NULL, "TCP only"
+	    },
+	    {
+		1, NULL, "simple UDP"
+	    },
+	    {
+		2, NULL, "enforced UDP (state only)"
+	    },
+	    {
+		3, NULL, "enforced UDP (state & weapon)"
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"udpSequenceCheck", BOOL_DEF, "UDP sequence checking",
+	&udpSequenceChk,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"sortPlayers", BOOL_DEF, "Sort playerlist by teams",
+	&sortPlayers,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"robsort", BOOL_DEF, "Put enemies on left in sorted playerlist",
+	&robsort,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"hideNoKills", BOOL_DEF, "Replace 0.00 kills with spaces",
+	&hideNoKills,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showDead", BOOL_DEF, "Show dead in playerlist",
+	&showDead,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showPreLogins", BOOL_DEF, "Show pre-logins in playerlist",
+	&showPreLogins,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"sortOutfitting", BOOL_DEF, "Sort outfitting ('--') to bottom",
+	&sortOutfitting,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"timerType", INT_DEF, "Type of timer to use",
+	&timerType,
+	{
+	    {
+		0, NULL, "no timer"
+	    },
+	    {
+		1, NULL, "time of day"
+	    },
+	    {
+		2, NULL, "time on server"
+	    },
+	    {
+		3, NULL, "time in ship"
+	    },
+	    {
+		4, NULL, "user set timer"
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showGalactic", INT_DEF, "Galactic planet bitmaps",
+	&showgalactic,
+	{
+	    {
+		0, NULL, "show nothing on galactic map"
+	    },
+	    {
+		1, NULL, "show facilities on galactic map"
+	    },
+	    {
+		2, NULL, "show owner on galactic map"
+	    },
+	    {
+		3, NULL, "show surface properties on galactic map"
+	    },
+	    {
+		4, NULL, "show scout info age on galactic map"
+	    },
+	    {
+		5, NULL, "show MOO facilities on galactic map"
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"showLocal", INT_DEF, "Local planet bitmaps",
+	&showlocal,
+	{
+	    {
+		0, NULL, "show nothing on local map"
+	    },
+	    {
+		1, NULL, "show facilities on local map"
+	    },
+	    {
+		2, NULL, "show owner on local map"
+	    },
+	    {
+		3, NULL, "show surface properties on local map"
+	    },
+	    {
+		4, NULL, "show MOO facilities"
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"name", STR_DEF, "Default player name",
+	&(name),
+	{
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"keymap", STR_DEF, "Keyboard map",
+	&(keymap),
+	{
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"buttonmap", STR_DEF, "Mouse button map",
+	&(bmap),
+	{
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"nameMode", BOOL_DEF, "Show names on map/local",
+	&namemode,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#ifdef SHORT_PACKETS
+    {
+	"tryShort", BOOL_DEF, "Try SHORT-PACKETS at startup",
+	&tryShort,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#endif
+#ifdef IGNORE_SIGNALS_SEGV_BUS
+    {
+	"ignoreSignals", BOOL_DEF, "Ignore SIGSEGV and SIGBUS",
+	&ignore_signals,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#endif
+#ifdef SHIFTED_MOUSE
+    {
+	"shiftedMouse", BOOL_DEF, "More mouse buttons with shift",
+	&extended_mouse,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#endif
+#ifdef BEEPLITE
+    {
+	"UseLite", BOOL_DEF, "Use message highliting",
+	&UseLite,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+    {
+	"DefLite", BOOL_DEF, "Use default lites",
+	&DefLite,
+	{
+	    {
+		0, NULL, ""
+	    },
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+#endif
+    {
+	"saveFileName", STR_DEF, "Name to save defaults as(click here)",
+	&(saveFileName),
+	{
+	    {
+		0, NULL, NULL
+	    },
+	},
+    },
+};
+
+char   *
+itos(v)
+    int     v;
+{
+    static char value[10];
+    sprintf(value, "%d", v);
+    return value;
+}
+
+char   *
+btoa(v)
+    int     v;
+{
+    if (v)
+	return "on";
+    else
+	return "off";
+}
+
+static void
+def_redraw(d)
+    struct def *d;
+{
+    int     xo = d->loc.x, yo = d->loc.y;
+    int     x, y, j;
+    char   *val;
+    W_Color col;
+
+    x = xo;
+    y = yo;
+
+    W_ClearArea(defWin, d->loc.x, d->loc.y, d->loc.rt - d->loc.x, d->loc.bot - d->loc.y);
+
+    W_WriteText(defWin, x, y, W_Yellow, d->name, strlen(d->name),
+		W_RegularFont);
+    x += NAME_WIDTH;
+
+    W_WriteText(defWin, x, y, textColor, d->desc, strlen(d->desc),
+		W_RegularFont);
+    y++;
+    x = xo + INDENT;
+
+    if (d->type != STR_DEF) {
+	if (!d->values[0].desc && d->variable) {
+	    if (d->type == SINT_DEF)
+		val = itos(*(int *)d->variable);
+	    else
+		val = itos(d->values[0].i_value);
+
+	    W_WriteText(defWin, x, y, W_Green, val, strlen(val),
+			W_RegularFont);
+	    y++;
+	}
+	for (j = 0; d->values[j].desc; j++) {
+	    switch (d->type) {
+	    case INT_DEF:
+		val = itos(d->values[j].i_value);
+		if (d->values[j].i_value == *(int *)d->variable) {
+		    col = W_Green;
+
+		    W_WriteText(defWin, x, y, col, val, strlen(val),
+				W_RegularFont);
+		    if (W_Mono()) {
+			W_WriteText(defWin, x + 1, y, col, "*", 1,
+				    W_RegularFont);
+		    }
+		} else {
+		    col = textColor;
+
+		    W_WriteText(defWin, x, y, col, val, strlen(val),
+				W_RegularFont);
+		}
+		x = xo + NAME_WIDTH;
+		W_WriteText(defWin, x, y, col, d->values[j].desc,
+			    strlen(d->values[j].desc), W_RegularFont);
+		y++;
+		x = xo + INDENT;
+		break;
+
+	    case BOOL_DEF:
+		val = btoa(*(int *)d->variable);
+		W_WriteText(defWin, x, y, W_Green, val, strlen(val),
+			    W_RegularFont);
+		y++;
+		x = xo + INDENT;
+		break;
+	    default:
+		fprintf(stderr, "Unknown type.\n");
+		break;
+	    }
+	}
+    } else if (d->variable && *(int *)d->variable) {
+	W_WriteText(defWin, x, y, W_Green, (char *)*(int *)d->variable,
+		    strlen((char *)(*(int *)d->variable)),
+		    W_RegularFont);
+    }
+}
+
+
+void
+showdef()
+{
+    register i, j, x = 0, y = 0, xo = 0, yo = 0, max_desc = 0, height = 1, width = 1;
+    register struct def *d;
+    char   *val;
+    W_Color col;
+
+    name = getdefault("name");
+    keymap = getdefault("keymap");
+/*   plist = getdefault ("playerlist");*/
+    cloak_chars = cloakchars;
+    bmap = getdefault("buttonmap");
+    log_file = getdefault("logfile");
+    galacticFrequent = (mapmode == 2) ? 0 : 1;
+    if (!saveFileName) {
+	saveFileName = stringDefault("saveFileName", "~/.paradisesaverc");
+	saveFileName = expandFilename(saveFileName);
+    }
+    if (!defWin)
+	defWin = W_MakeTextWindow("xtrekrc_help", 1, 100, 174, 60, NULL, NULL, BORDER);
+
+    for (i = 0, d = def_messages; i < DEFMESSAGES; i++, d++) {
+	x = xo;
+	y = yo;
+
+	d->loc.x = x;
+	d->loc.y = y;
+
+	W_WriteText(defWin, x, y, W_Yellow, d->name, strlen(d->name),
+		    W_RegularFont);
+	x += NAME_WIDTH;
+
+	W_WriteText(defWin, x, y, textColor, d->desc, strlen(d->desc),
+		    W_RegularFont);
+	if ((int)strlen(d->desc) > max_desc) {
+	    max_desc = strlen(d->desc);
+	    width = MAX(width, x + max_desc);
+	}
+	y++;
+	x = xo + INDENT;
+
+	if (d->type != STR_DEF) {
+	    if (!d->values[0].desc && d->variable) {
+		if (d->type == SINT_DEF)
+		    val = itos(*(int *)d->variable);
+		else
+		    val = itos(d->values[0].i_value);
+
+		W_WriteText(defWin, x, y, W_Green, val, strlen(val),
+			    W_RegularFont);
+		y++;
+	    }
+	    for (j = 0; d->values[j].desc; j++) {
+		switch (d->type) {
+		case INT_DEF:
+		    val = itos(d->values[j].i_value);
+		    if (d->values[j].i_value == *(int *)d->variable) {
+			col = W_Green;
+
+			W_WriteText(defWin, x, y, col, val, strlen(val),
+				    W_RegularFont);
+			if (W_Mono()) {
+			    W_WriteText(defWin, x + 1, y, col, "*", 1,
+					W_RegularFont);
+			}
+		    } else {
+			col = textColor;
+
+			W_WriteText(defWin, x, y, col, val, strlen(val),
+				    W_RegularFont);
+		    }
+		    x = xo + NAME_WIDTH;
+		    W_WriteText(defWin, x, y, col, d->values[j].desc,
+				strlen(d->values[j].desc), W_RegularFont);
+		    y++;
+		    x = xo + INDENT;
+		    break;
+
+		case BOOL_DEF:
+		    val = btoa(*(int *)d->variable);
+		    W_WriteText(defWin, x, y, W_Green, val, strlen(val),
+				W_RegularFont);
+		    y++;
+		    x = xo + INDENT;
+		    break;
+		default:
+		    fprintf(stderr, "Unknown type.\n");
+		    break;
+		}
+	    }
+	} else if (d->variable && *(int *)d->variable) {
+	    W_WriteText(defWin, x, y, W_Green, (char *)*(int *)d->variable,
+			strlen((char *)(*(int *)d->variable)),
+			W_RegularFont);
+	    y++;
+	}
+	d->loc.rt = xo + max_desc;
+	d->loc.bot = y + 1;
+
+	height = MAX(height, y);
+	if (y > MAX_VLINES) {
+	    yo = 0;
+	    xo += NAME_WIDTH + max_desc + 2;
+	    max_desc = 0;
+	} else {
+	    yo = y + 1;
+	}
+    }
+
+    if (!W_IsMapped(defWin)) {
+	W_ResizeText(defWin, width, height);
+	W_MapWindow(defWin);
+    }
+}
+
+void
+def_action(ev)
+    W_Event *ev;
+{
+    int     i, j, x, y, line;
+    register struct def *d;
+    char    buf[100];
+
+    x = ev->x;
+    y = ev->y;
+    W_TranslatePoints(ev->Window, &x, &y);
+
+    for (i = 0, d = def_messages; i < DEFMESSAGES; i++, d++) {
+	if (y >= d->loc.y && y < d->loc.bot &&
+	    x >= d->loc.x && x < d->loc.rt)
+	    break;		/* found it! */
+    }
+
+    if (i >= DEFMESSAGES)
+	return;
+
+    line = y - d->loc.y;
+
+    switch (ev->type) {
+    case W_EV_BUTTON:
+	switch (d->type) {
+	case BOOL_DEF:
+	    *(int *)d->variable = !(*(int *)d->variable);
+	    def_redraw(d);
+	    break;
+	case INT_DEF:
+	case SINT_DEF:
+	    if (line == 0 || d->type == SINT_DEF) {
+		switch (ev->key) {
+		case W_LBUTTON:
+		    (*(int *)d->variable)++;
+		    if (!(*(int *)d->values[*(int *)d->variable].desc))
+			*(int *)d->variable = 0;
+		    break;
+		case W_RBUTTON:
+		    (*(int *)d->variable)--;
+		    if (*(int *)d->variable < 0) {
+			for (j = 0; d->values[j].desc; j++)
+			     /* empty */ ;
+			*(int *)d->variable = j - 1;
+		    }
+		    break;
+		case W_MBUTTON:
+		    *(int *)d->variable = 0;
+		    break;
+		default:
+		    break;
+		}
+	    } else if (y < d->loc.bot)
+		*(int *)d->variable = line - 1;
+	    def_redraw(d);
+	    break;
+	case STR_DEF:
+	    if (d->variable == &saveFileName)
+		def_write(saveFileName);
+	    break;
+	default:
+	    break;
+	}
+    }
+}
+
+void
+def_write(file)
+    char   *file;
+{
+    int     i;
+    struct def *d;
+    FILE   *f;
+
+    f = fopen(file, "w");
+
+
+    for (i = 0, d = def_messages; i < DEFMESSAGES; i++, d++) {
+	switch (d->type) {
+	case INT_DEF:
+	case SINT_DEF:
+	    fprintf(f, "%s: %d\n", d->name, *(int *)d->variable);
+	    break;
+	case BOOL_DEF:
+	    fprintf(f, "%s: %s\n", d->name, (*(int *)d->variable ? "on" : "off"));
+	    break;
+	case STR_DEF:
+	    fprintf(f, "%s: %s\n", d->name, (char *)*(int *)d->variable);
+	    break;
+	}
+    }
+
+    fclose(f);
+}
+
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/detonate.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,34 @@
+/* $Id: detonate.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * detonate.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+/* Detonate torp */
+
+void
+detmine()
+{
+    if (paradise) {
+	sendDetMineReq(-1);
+    } else {
+	register int i;
+
+	for (i = 0; i < ntorps; i++) {
+	    int     j = i + me->p_no * ntorps;
+	    if (torps[j].t_status == TMOVE ||
+		torps[j].t_status == TSTRAIGHT) {
+		sendDetMineReq(j);
+	    }
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/distress.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,870 @@
+/* $Id: distress.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * distress.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <ctype.h>
+#include <string.h>
+#ifndef SERVER
+#include "Wlib.h"
+#endif
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "gameconf.h"
+#include "proto.h"
+
+/* #$!@$#% length of address field of messages */
+#define ADDRLEN 10
+#define MAXMACLEN 256
+#define MZERO bzero
+
+
+/*
+ * The two in-line defs that follow enable us to avoid calling strcat over
+ * and over again.
+ */
+char   *pappend;
+#define APPEND(ptr,str)     \
+   pappend = str;           \
+   while(*pappend)          \
+       *ptr++ = *pappend++;
+
+#define APPEND_CAP(ptr,cap,str) \
+   pappend = str;               \
+   while(*pappend)              \
+   {                            \
+       *ptr++ = (cap ? toupper(*pappend) : *pappend); \
+       pappend++;               \
+   }
+
+/*
+ * This is a hacked version from the K&R book.  Basically it puts <n> into
+ * <s> in reverse and then reverses the string...
+ * MH.  10-18-93
+ */
+int
+itoa2(n, s)
+    int     n;
+    char    s[];
+{
+    int     i, c, j, len;
+
+    if ((c = n) < 0)
+	n = -n;
+
+    i = 0;
+    do {
+	s[i++] = n % 10 + '0';
+    } while ((n /= 10) > 0);
+
+    if (c < 0)
+	s[i++] = '-';
+
+    s[i] = '\0';
+
+    len = i--;
+
+    for (j = 0; i > j; j++, i--) {
+	c = s[i];
+	s[i] = s[j];
+	s[j] = c;
+    }
+
+    return len;
+}
+
+/*
+ * Like APPEND, and APPEND_CAP, APPEND_INT is an in-line function that
+ * stops us from calling sprintf over and over again.
+ */
+#define APPEND_INT(ptr, i) \
+    ptr += itoa2(i, ptr);
+
+
+#ifdef SERVER
+#define ADDRLEN 10
+#define MAXMACLEN 85
+extern char *shiptypes[];
+#define warning(x)	fprintf(stderr,x)
+#endif
+
+
+char   *getaddr(), *getaddr2();
+
+
+
+/* This takes an MDISTR flagged message and makes it into a dist struct */
+void
+HandleGenDistr(message, from, to, dist)
+    char   *message;
+    struct distress *dist;
+    unsigned char from, to;
+{
+
+    char   *mtext;
+    unsigned char i;
+
+    mtext = &message[ADDRLEN];
+#ifndef SERVER
+    MZERO((char *) dist, sizeof(dist));
+#else
+    bzero((char *) dist, sizeof(dist));
+#endif
+
+    dist->sender = from;
+    dist->distype = mtext[0] & 0x1f;
+    dist->macroflag = ((mtext[0] & 0x20) > 0);
+    dist->fuelp = mtext[1] & 0x7f;
+    dist->dam = mtext[2] & 0x7f;
+    dist->shld = mtext[3] & 0x7f;
+    dist->etmp = mtext[4] & 0x7f;
+    dist->wtmp = mtext[5] & 0x7f;
+    dist->arms = mtext[6] & 0x1f;
+    dist->sts = mtext[7] & 0x7f;
+    dist->wtmpflag = ((dist->sts & PFWEP) != 0) ? 1 : 0;
+    dist->etempflag = ((dist->sts & PFENG) != 0) ? 1 : 0;
+    dist->cloakflag = ((dist->sts & PFCLOAK) != 0) ? 1 : 0;
+    dist->close_pl = mtext[8] & 0x7f;
+    dist->close_en = mtext[9] & 0x7f;
+    dist->tclose_pl = mtext[10] & 0x7f;
+    dist->tclose_en = mtext[11] & 0x7f;
+    dist->tclose_j = mtext[12] & 0x7f;
+    dist->close_j = mtext[13] & 0x7f;
+    dist->tclose_fr = mtext[14] & 0x7f;
+    dist->close_fr = mtext[15] & 0x7f;
+    i = 0;
+    while ((mtext[16 + i] & 0xc0) == 0xc0 && (i < 6)) {
+	dist->cclist[i] = mtext[16 + i] & 0x1f;
+	i++;
+    }
+    dist->cclist[i] = mtext[16 + i];
+    if (dist->cclist[i] == 0x80)
+	dist->pre_app = 1;
+    else
+	dist->pre_app = 0;
+    dist->preappend[0] = '\0';
+
+    if (mtext[16 + i + 1] != '\0') {
+	strncpy(dist->preappend, &mtext[16 + i + 1], MSG_LEN - 1);
+	dist->preappend[MSG_LEN - 1] = '\0';
+    }
+}
+
+/* this converts a dist struct to the appropriate text
+   (excludes F1->FED text bit).. sorry if this is not what we said
+   earlier jeff.. but I lost the paper towel I wrote it all down on */
+void
+Dist2Mesg(dist, buf)
+    struct distress *dist;
+    char   *buf;
+{
+    int     len, i;
+
+    sprintf(buf, "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
+	    (dist->macroflag << 5) + (dist->distype),
+	    dist->fuelp | 0x80,
+	    dist->dam | 0x80,
+	    dist->shld | 0x80,
+	    dist->etmp | 0x80,
+	    dist->wtmp | 0x80,
+	    dist->arms | 0x80,
+	    dist->sts | 0x80,
+	    dist->close_pl | 0x80,
+	    dist->close_en | 0x80,
+	    dist->tclose_pl | 0x80,
+	    dist->tclose_en | 0x80,
+	    dist->tclose_j | 0x80,
+	    dist->close_j | 0x80,
+	    dist->tclose_fr | 0x80,
+	    dist->close_fr | 0x80);
+
+    /* cclist better be terminated properly otherwise we hose here */
+    i = 0;
+    while (((dist->cclist[i] & 0xc0) == 0xc0)) {
+	buf[16 + i] = dist->cclist[i];
+	i++;
+    }
+    /* get the pre/append cclist terminator in there */
+    buf[16 + i] = dist->cclist[i];
+    buf[16 + i + 1] = '\0';
+
+    len = 16 + i + 1;
+    if (dist->preappend[0] != '\0') {
+	strncat(buf, dist->preappend, MSG_LEN - len);	/* false sense of
+							   security? */
+	buf[MSG_LEN - 1] = '\0';
+    }
+}
+
+/* small permutation on the newmacro code... this takes a pointer to
+   ** a distress structure and a pointer to a macro syntax string,
+   ** and converts it into a line of text.
+   **  9/1/93 - jn
+ */
+int
+makedistress(dist, cry, pm)
+    struct distress *dist;	/* the info */
+    char   *cry;		/* the call for help! (output) - should be
+				   array */
+    char   *pm;			/* macro to parse, used for distress and
+				   macro */
+{
+    char    buf1[10 * MAXMACLEN];
+    char   *pbuf1;
+    char    buf2[10 * MAXMACLEN];
+    char    buf3[10 * MAXMACLEN];
+    char    tmp[10 * MAXMACLEN];
+    int     index = 0;
+    int     index2 = 0;
+    int     index3 = 0;
+    int     cap = 0;
+    struct player *sender;
+    struct player *j;
+    struct planet *l;
+    char   *strcap();
+#ifndef SERVER
+    extern int ping_tloss_sc;	/* total % loss 0--100, server to client */
+    extern int ping_tloss_cs;	/* total % loss 0--100, client to server */
+    extern int ping_av;		/* average rt */
+    extern int ping_sd;		/* standard deviation */
+#endif
+    char    c;
+
+
+    sender = &players[dist->sender];
+
+    if (!(*pm)) {
+	cry[0] = '\0';
+	return (0);
+    }
+    buf1[0] = '\0';
+    pbuf1 = buf1;
+
+    /* first step is to substitute variables */
+    while (*pm) {
+	if (*pm == '%') {
+	    pm++;
+
+	    if (!pm)
+		continue;
+
+	    switch (c = *(pm++)) {
+	    case ' ':
+		APPEND(pbuf1, " \0");
+		break;
+	    case 'O':		/* push a 3 character team name into buf */
+		cap = 1;
+	    case 'o':		/* push a 3 character team name into buf */
+		APPEND_CAP(pbuf1, cap, teaminfo[sender->p_teami].shortname);
+		cap = 0;
+		break;
+	    case 'a':		/* push army number into buf */
+		APPEND_INT(pbuf1, dist->arms);
+		break;
+	    case 'd':		/* push damage into buf */
+		APPEND_INT(pbuf1, dist->dam);
+		break;
+	    case 's':		/* push shields into buf */
+		APPEND_INT(pbuf1, dist->shld);
+		break;
+	    case 'f':		/* push fuel into buf */
+		APPEND_INT(pbuf1, dist->fuelp);
+		break;
+	    case 'w':		/* push wtemp into buf */
+		APPEND_INT(pbuf1, dist->wtmp);
+		break;
+	    case 'e':		/* push etemp into buf */
+		APPEND_INT(pbuf1, dist->etmp);
+		break;
+
+	    case 'P':		/* push player id into buf */
+	    case 'G':		/* push friendly player id into buf */
+	    case 'H':		/* push enemy target player id into buf */
+
+	    case 'p':		/* push player id into buf */
+	    case 'g':		/* push friendly player id into buf */
+	    case 'h':		/* push enemy target player id into buf */
+
+		switch (c) {
+		case 'p':
+		    j = &players[dist->tclose_j];
+		    break;
+		case 'g':
+		    j = &players[dist->tclose_fr];
+		    break;
+		case 'h':
+		    j = &players[dist->tclose_en];
+		    break;
+		case 'P':
+		    j = &players[dist->close_j];
+		    break;
+		case 'G':
+		    j = &players[dist->close_fr];
+		    break;
+		default:
+		    j = &players[dist->close_en];
+		    break;
+		}
+		tmp[0] = j->p_mapchars[1];
+		tmp[1] = '\0';
+		APPEND(pbuf1, tmp);
+		break;
+
+	    case 'n':		/* push planet armies into buf */
+		l = &planets[dist->tclose_pl];
+		APPEND_INT(pbuf1,
+			   ((l->pl_info & idx_to_mask(sender->p_teami))
+			    ? l->pl_armies : -1));
+		break;
+	    case 'B':
+		cap = 1;
+	    case 'b':		/* push planet into buf */
+		l = &planets[dist->close_pl];
+		tmp[0] = l->pl_name[0] - 'A' + 'a';
+		tmp[1] = l->pl_name[1];
+		tmp[2] = l->pl_name[2];
+		tmp[3] = '\0';
+		APPEND_CAP(pbuf1, cap, tmp);
+		cap = 0;
+		break;
+	    case 'L':
+		cap = 1;
+	    case 'l':		/* push planet into buf */
+		l = &planets[dist->tclose_pl];
+		tmp[0] = l->pl_name[0] - 'A' + 'a';
+		tmp[1] = l->pl_name[1];
+		tmp[2] = l->pl_name[2];
+		tmp[3] = '\0';
+		APPEND_CAP(pbuf1, cap, tmp);
+		cap = 0;
+		break;
+	    case 'Z':		/* push a 3 character team name into buf */
+		cap = 1;
+	    case 'z':		/* push a 3 character team name into buf */
+		l = &planets[dist->tclose_pl];
+		APPEND_CAP(pbuf1, cap,
+			   teaminfo[mask_to_idx(l->pl_owner)].shortname);
+		cap = 0;
+		break;
+	    case 't':		/* push a team character into buf */
+		l = &planets[dist->tclose_pl];
+		tmp[0] = teaminfo[mask_to_idx(l->pl_owner)].letter;
+		tmp[1] = '\0';
+		APPEND(pbuf1, tmp);
+		break;
+	    case 'T':		/* push my team into buf */
+		tmp[0] = teaminfo[sender->p_teami].letter;
+		tmp[1] = '\0';
+		APPEND(pbuf1, tmp);
+		break;
+	    case 'c':		/* push my id char into buf */
+		tmp[0] = sender->p_mapchars[1];
+		tmp[1] = '\0';
+		APPEND(pbuf1, tmp);
+		break;
+	    case 'W':		/* push WTEMP flag into buf */
+		if (dist->wtmpflag)
+		    tmp[0] = '1';
+		else
+		    tmp[0] = '0';
+		tmp[1] = '\0';
+		APPEND(pbuf1, tmp);
+		break;
+	    case 'E':		/* push ETEMP flag into buf */
+		if (dist->etempflag)
+		    tmp[0] = '1';
+		else
+		    tmp[0] = '0';
+		tmp[1] = '\0';
+		APPEND(pbuf1, tmp);
+		break;
+	    case 'K':
+		cap = 1;
+	    case 'k':
+		if (cap)
+		    j = &players[dist->tclose_en];
+		else
+		    j = sender;
+
+		if (j->p_ship->s_type == STARBASE)
+		    sprintf(tmp, "%5.2f", j->p_stats.st_sbkills / 100.0);
+		else
+		    sprintf(tmp, "%5.2f", (j->p_stats.st_kills + j->p_stats.st_tkills) / 100.0);
+		APPEND(pbuf1, tmp);
+		break;
+
+	    case 'U':		/* push player name into buf */
+		cap = 1;
+	    case 'u':		/* push player name into buf */
+		j = &players[dist->tclose_en];
+		APPEND_CAP(pbuf1, cap, j->p_name);
+		cap = 0;
+		break;
+	    case 'I':		/* my player name into buf */
+		cap = 1;
+	    case 'i':		/* my player name into buf */
+		APPEND_CAP(pbuf1, cap, sender->p_name);
+		cap = 0;
+		break;
+	    case 'S':		/* push ship type into buf */
+#ifndef SERVER
+		*pbuf1++ = sender->p_ship->s_desig[0];
+		*pbuf1++ = sender->p_ship->s_desig[1];
+#else
+		APPEND(pbuf1, shiptypes[sender->p_ship->s_type]);
+#endif
+		break;
+
+#ifdef SERVER
+	    case 'v':		/* push average ping round trip time into buf */
+	    case 'V':		/* push ping stdev into buf */
+	    case 'y':		/* push packet loss into buf */
+		APPEND(pbuf1, "0\0");
+	    case 'M':		/* push capitalized lastMessage into buf */
+	    case 'm':		/* push lastMessage into buf */
+		break;
+#else
+	    case 'M':		/* push capitalized lastMessage into buf */
+		cap = 1;
+	    case 'm':		/* push lastMessage into buf */
+		APPEND_CAP(pbuf1, cap, lastMessage);
+		cap = 0;
+		break;
+
+	    case 'v':		/* push average ping round trip time into buf */
+		APPEND_INT(pbuf1, ping_av);
+		break;
+
+	    case 'V':		/* push ping stdev into buf */
+		APPEND_INT(pbuf1, ping_sd);
+		break;
+
+	    case 'y':		/* push packet loss into buf */
+		/* this is the weighting formula used be socket.c ntserv */
+		APPEND_INT(pbuf1, (2 * ping_tloss_sc + ping_tloss_cs) / 3);
+		break;
+#endif
+
+	    case '*':		/* push %} into buf */
+		APPEND(pbuf1, "%*\0");
+		break;
+	    case '}':		/* push %} into buf */
+		APPEND(pbuf1, "%}\0");
+		break;
+	    case '{':		/* push %{ into buf */
+		APPEND(pbuf1, "%{\0");
+		break;
+	    case '!':		/* push %! into buf */
+		APPEND(pbuf1, "%!\0");
+		break;
+	    case '?':		/* push %? into buf */
+		APPEND(pbuf1, "%?\0");
+		break;
+	    case '%':		/* push %% into buf */
+		APPEND(pbuf1, "%%\0");
+		break;
+	    default:
+/* try to continue
+** bad macro character is skipped entirely,
+** the message will be parsed without whatever %. has occurred. - jn
+*/
+		warning("Bad Macro character in distress!");
+		fprintf(stderr, "Unrecognizable special character in distress pass 1: %c\n", *(pm - 1));
+		break;
+	    }
+	} else {
+	    tmp[0] = *pm;
+	    tmp[1] = '\0';
+	    APPEND(pbuf1, tmp);
+	    pm++;
+	}
+
+    }
+
+    *pbuf1 = '\0';
+
+    /* second step is to evaluate tests, buf1->buf2 */
+    testmacro(buf1, buf2, &index, &index2);
+    buf2[index2] = '\0';
+
+    if (index2 <= 0) {
+	cry[0] = '\0';
+	return (0);
+    }
+    index2 = 0;
+
+    /* third step is to include conditional text, buf2->buf3 */
+    condmacro(buf2, buf3, &index2, &index3, 1);
+
+    if (index3 <= 0) {
+	cry[0] = '\0';
+	return (0);
+    }
+    buf3[index3] = '\0';
+
+    cry[0] = '\0';
+    strncat(cry, buf3, MSG_LEN);
+
+    return (index3);
+}
+
+int
+testmacro(bufa, bufb, inda, indb)
+    char   *bufa;
+    char   *bufb;
+    int    *inda;
+    int    *indb;
+{
+    int     state = 0;
+
+    if (*indb >= 10 * MAXMACLEN)
+	return 0;
+/* maybe we should do something more "safe" here (and at other returns)? */
+
+
+    while (bufa[*inda] && (*indb < 10 * MAXMACLEN)) {
+	if (state) {
+	    switch (bufa[(*inda)++]) {
+	    case '*':		/* push %* into buf */
+		if (*indb < 10 * MAXMACLEN - 2) {
+		    bufb[*indb] = '%';
+		    (*indb)++;
+		    bufb[*indb] = '*';
+		    (*indb)++;
+		} else
+		    return (0);	/* we are full, so we are done */
+		state = 0;
+		continue;
+		break;
+
+	    case '%':		/* push %% into buf */
+		if (*indb < 10 * MAXMACLEN - 2) {
+		    bufb[*indb] = '%';
+		    (*indb)++;
+		    bufb[*indb] = '%';
+		    (*indb)++;
+		} else
+		    return (0);	/* we are full, so we are done */
+		state = 0;
+		continue;
+		break;
+
+	    case '{':		/* push %{ into buf */
+		if (*indb < 10 * MAXMACLEN - 2) {
+		    bufb[*indb] = '%';
+		    (*indb)++;
+		    bufb[*indb] = '{';
+		    (*indb)++;
+		} else
+		    return (0);	/* we are full, so we are done */
+		state = 0;
+		continue;
+		break;
+
+	    case '}':		/* push %} into buf */
+		if (*indb < 10 * MAXMACLEN - 2) {
+		    bufb[*indb] = '%';
+		    (*indb)++;
+		    bufb[*indb] = '}';
+		    (*indb)++;
+		} else
+		    return (0);	/* we are full, so we are done */
+		state = 0;
+		continue;
+		break;
+
+	    case '!':		/* push %! into buf */
+		if (*indb < 10 * MAXMACLEN - 2) {
+		    bufb[*indb] = '%';
+		    (*indb)++;
+		    bufb[*indb] = '!';
+		    (*indb)++;
+		} else
+		    return (0);	/* we are full, so we are done */
+		state = 0;
+		continue;
+		break;
+
+	    case '?':		/* the dreaded conditional, evaluate it */
+		bufb[*indb] = '0' + solvetest(bufa, inda);
+		(*indb)++;
+		state = 0;
+		continue;
+		break;
+
+	    default:
+		warning("Bad character in Macro!");
+		printf("Unrecognizable special character in macro pass2: %c  Trying to continue.\n",
+		       bufa[(*inda) - 1]);
+		state = 0;
+		continue;
+		break;
+	    }
+	}
+	if (bufa[*inda] == '%') {
+	    state++;
+	    (*inda)++;
+	    continue;
+	}
+	state = 0;
+
+
+	if (*indb < 10 * MAXMACLEN) {
+	    bufb[*indb] = bufa[*inda];
+	    (*inda)++;
+	    (*indb)++;
+	} else
+	    return (0);
+    }
+
+    return (0);
+}
+
+int
+solvetest(bufa, inda)
+    char   *bufa;
+    int    *inda;
+{
+    int     state = 0;
+    char    bufh[10 * MAXMACLEN];
+    char    bufc[10 * MAXMACLEN];
+    int     indh = 0, indc = 0, i;
+    char    operation;
+
+
+    while (bufa[*inda] &&
+	   bufa[*inda] != '<' &&
+	   bufa[*inda] != '>' &&
+	   bufa[*inda] != '=') {
+
+	bufh[indh++] = bufa[(*inda)++];
+    }
+    bufh[indh] = '\0';
+
+    operation = bufa[(*inda)++];
+
+    while (bufa[*inda] &&
+	   !(state &&
+	     ((bufa[*inda] == '?') ||
+	      (bufa[*inda] == '{')))) {
+
+	if (state && (bufa[*inda] == '%' ||
+		      bufa[*inda] == '!' ||
+		      bufa[*inda] == '}')) {
+	    bufc[indc++] = '%';
+	} else if (bufa[*inda] == '%') {
+	    state = 1;
+	    (*inda)++;
+	    continue;
+	}
+	state = 0;
+	bufc[indc++] = bufa[(*inda)++];
+    }
+    bufc[indc] = '\0';
+
+    if (bufa[*inda])
+	(*inda)--;
+
+    if (!operation)		/* incomplete is truth, just ask Godel */
+	return (1);
+
+    switch (operation) {
+    case '=':			/* character by character equality */
+	if (indc != indh)
+	    return (0);
+	for (i = 0; i < indc; i++) {
+	    if (bufc[i] != bufh[i])
+		return (0);
+	}
+	return (1);
+	break;
+
+    case '<':
+	if (atoi(bufh) < atoi(bufc))
+	    return (1);
+	else
+	    return (0);
+	break;
+
+    case '>':
+	if (atoi(bufh) > atoi(bufc))
+	    return (1);
+	else
+	    return (0);
+	break;
+
+    default:
+	warning("Bad operation in Macro!");
+	printf("Unrecognizable operation in macro pass3: %c  Trying to continue.\n",
+	       operation);
+	return (1);		/* don't know what happened, pretend we do */
+	break;
+    }
+}
+
+int
+condmacro(bufa, bufb, inda, indb, flag)
+    char   *bufa;
+    char   *bufb;
+    int    *inda;
+    int    *indb;
+    int     flag;
+{
+    int     newflag, include;
+    int     state = 0;
+
+
+    if (*indb >= MAXMACLEN)
+	return 0;
+
+    include = flag;
+
+    while (bufa[*inda] && (*indb < MAXMACLEN)) {
+	if (state) {
+	    switch (bufa[(*inda)++]) {
+	    case '}':		/* done with this conditional, return */
+		return (0);
+		break;
+
+	    case '{':		/* handle new conditional */
+		if (*indb > 0) {
+		    (*indb)--;
+		    if (bufb[*indb] == '0')
+			newflag = 0;
+		    else
+			newflag = 1;
+		} else		/* moron starting with cond, assume true */
+		    newflag = 1;
+
+		if (include)
+		    condmacro(bufa, bufb, inda, indb, newflag);
+		else {
+		    (*indb)++;
+		    *inda = skipmacro(bufa, *inda);
+		}
+
+		state = 0;
+		continue;
+		break;
+
+	    case '!':		/* handle not indicator */
+		if (flag)
+		    include = 0;
+		else
+		    include = 1;
+
+		state = 0;
+		continue;
+		break;
+
+	    case '%':		/* push % into buf */
+		if (include) {
+		    if (*indb < MAXMACLEN) {
+			bufb[*indb] = '%';
+			(*indb)++;
+		    } else
+			return (0);
+		}
+		state = 0;
+		continue;
+
+	    default:
+		warning("Bad character in Macro!");
+		printf("Unrecognizable special character in macro pass4: %c  Trying to continue.\n",
+		       bufa[(*inda) - 1]);
+	    }
+	}
+	if (bufa[*inda] == '%') {
+	    state++;
+	    (*inda)++;
+	    continue;
+	}
+	state = 0;
+
+
+	if (include) {
+	    if (*indb < MAXMACLEN) {
+		bufb[*indb] = bufa[*inda];
+		(*inda)++;
+		(*indb)++;
+	    } else
+		return (0);
+	} else
+	    (*inda)++;
+    }
+    return (0);
+}
+
+int
+skipmacro(buf, index)
+    char    buf[];
+    int     index;
+{
+    int     state = 0;
+    int     end = 0;
+
+    if (index == 0)
+	index++;
+
+    while (buf[index] && !end) {
+	if (state) {
+	    switch (buf[index++]) {
+	    case '{':
+		index = skipmacro(buf, index);
+		continue;
+		break;
+	    case '}':
+		end = 1;
+		continue;
+		break;
+	    case '!':
+	    case '%':
+		state = 0;
+		continue;
+		break;
+	    default:
+		warning("Bad character in Macro!");
+		printf("Unrecognizable special character in macro pass5: %c  Trying to continue.\n",
+		       buf[index - 1]);
+	    }
+	}
+	if (buf[index] == '%') {
+	    state++;
+	    index++;
+	    continue;
+	}
+	state = 0;
+	index++;
+    }
+
+    return (index);
+}
+
+
+/* return a pointer to a capitalized copy of string s */
+char   *
+strcap(s)
+    char   *s;
+{
+    static char buf[256];	/* returns static */
+    register char *t = buf;
+
+    while (*s) {
+	if (islower(*s))
+	    *t++ = toupper(*s++);
+	else
+	    *t++ = *s++;
+    }
+    *t = 0;
+    if (buf[255]) {
+	fprintf(stderr, "ERROR: String constant overwritten\n");
+	return NULL;
+    }
+    return buf;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dmessage.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,778 @@
+/* $Id: dmessage.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * dmessage.c
+ *
+ * for the client of a socket based protocol.
+ * code for message window scrollback added by Bill Dyess 12/7/93
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif
+
+#define MESSAGESIZE	20
+#define YOFF		0
+
+struct messageData {
+    char   *message;
+    unsigned char flags, from, to;
+};
+
+struct messageNode {
+    struct messageData *line;
+    struct messageNode *next, *prev;
+};
+
+/* Prototypes */
+int instr P((char *string1, char *string2));
+void CheckFeatures P((char *m));
+void print_message 
+P((char *message, unsigned int flags, unsigned int from,
+   unsigned int to, struct messageData * data,
+   W_Window winmask, int backwards));
+    void evalFlags P((int type, char *flagList));
+
+    void    initMessageWindows()
+{
+    int     i;
+    char   *s;
+
+    messWin[WALL].window = W_MakeScrollingWindow("review_all", WINSIDE + BORDER,
+						 YOFF + WINSIDE + 3 * BORDER + 2 * MESSAGESIZE, 80, 10, 0, "xterm", BORDER);
+    messWin[WTEAM].window = W_MakeScrollingWindow("review_team", WINSIDE + BORDER,
+      YOFF + WINSIDE + 4 * BORDER + 2 * MESSAGESIZE + 10 * W_Textheight + 8,
+						  80, 5, 0, "xterm", BORDER);
+    messWin[WINDIV].window = W_MakeScrollingWindow("review_your", WINSIDE + BORDER,
+     YOFF + WINSIDE + 5 * BORDER + 2 * MESSAGESIZE + 15 * W_Textheight + 16,
+						 80, 4, 0, "xterm", BORDER);
+    messWin[WKILL].window = W_MakeScrollingWindow("review_kill", WINSIDE + BORDER,
+     YOFF + WINSIDE + 6 * BORDER + 2 * MESSAGESIZE + 19 * W_Textheight + 24,
+						  80, 6, 0, "xterm", BORDER);
+    messWin[WPHASER].window = W_MakeScrollingWindow("review_phaser", WINSIDE +
+    BORDER, YOFF + WINSIDE + 7 * BORDER + 2 * MESSAGESIZE + 24 * W_Textheight
+					   + 32, 80, 3, 0, "xterm", BORDER);
+    messWin[WREVIEW].window = W_MakeScrollingWindow("review", WINSIDE + BORDER,
+			      YOFF + WINSIDE + 3 * BORDER + 2 * MESSAGESIZE,
+						80, 20, 0, "xterm", BORDER);
+
+    /*
+       initialize the 'allow' flags.  Any window can display any message.
+       [BDyess]
+    */
+    s = stringDefault("review_all.allow", "MA");
+    evalFlags(WALL, s);
+    s = stringDefault("review_team.allow", "T");
+    evalFlags(WTEAM, s);
+    s = stringDefault("review_your.allow", "I");
+    evalFlags(WINDIV, s);
+    s = stringDefault("review_kill.allow", "K");
+    evalFlags(WKILL, s);
+    s = stringDefault("review_phaser.allow", "P");
+    evalFlags(WPHASER, s);
+    s = stringDefault("review.allow", "MATIKP");
+    evalFlags(WREVIEW, s);
+
+    for (i = 0; i < WNUM; i++) {
+	messWin[i].head = messWin[i].curHead = NULL;
+    }
+}
+
+void
+evalFlags(type, flagList)
+    int     type;
+    char   *flagList;
+{
+    char *orig=flagList;
+
+    messWin[type].flags = 0;
+    while (*flagList) {
+	switch (toupper(*flagList)) {
+	case 'A':
+	    messWin[type].flags |= WA_ALL;
+	    break;
+	case 'T':
+	    messWin[type].flags |= WA_TEAM;
+	    break;
+	case 'I':
+	    messWin[type].flags |= WA_INDIV;
+	    break;
+	case 'K':
+	    messWin[type].flags |= WA_KILL;
+	    break;
+	case 'P':
+	    messWin[type].flags |= WA_PHASER;
+	    break;
+	case 'M':
+	    messWin[type].flags |= WA_MACRO;
+	    break;
+	default:
+	    printf("Invalid allow flag '%c' in allow list, ignoring\n",
+		   *flagList);
+	    break;
+	}
+	flagList++;
+    }
+    free(orig);
+}
+
+void
+messageWinEvent(evt)
+    W_Event *evt;
+/* handles the mouse and keyboard events that happen in one of the message
+   windows.  For key events, if the event is within the team or all window then
+   it will automatically start the message for you, with destination to the
+   player's team or ALL, respectively.  If it's a button event, it will scroll
+   the message window back, forward, or to start (left, right, and middle
+   button respectively).  It beeps if there is no messages to scroll (ie at
+   the top or bottom already). [BDyess] 12/07/93 */
+{
+    struct messageNode **headpntr, *runner, *newcpntr;
+    struct messageData *j;
+    int     windowHeight;
+    register int i;
+    W_Window window = evt->Window;
+    int     key = evt->key;
+    int scroll=0;
+
+    if (!W_IsMapped(window))
+	return;
+
+    if (evt->type == W_EV_KEY) {
+	if (key == ('e' + 128)) {	/* erase window [BDyess] */
+	    W_ClearWindow(window);
+	} else if(key == ('p'+128)) {
+	    scroll = -1;
+	} else if(key == ('n'+128)) {
+	    scroll = 1;
+	} else if (window == messWin[WALL].window) {
+	    smessage_ahead('A', key);
+	} else if (window == messWin[WTEAM].window) {
+	    smessage_ahead('T', key);
+	} else {
+	    smessage(key);
+	}
+	if(!scroll)
+	    return;
+    }
+    headpntr = NULL;
+    for (i = 0; i < WNUM; i++) {
+	if (window == messWin[i].window) {
+	    headpntr = &messWin[i].curHead;
+	    break;
+	}
+    }
+
+    runner = *headpntr;
+    if (runner == NULL) {
+	if(scrollBeep)
+	    W_Beep();
+	return;
+    }
+    windowHeight = W_WindowHeight(window);
+
+    if(scroll==-1) {
+	for (i = 0; (i < windowHeight) && runner; i++, runner = runner->next)
+            ;
+	if (runner == NULL) {
+	    if (scrollBeep)
+		W_Beep();
+	    return;
+	}
+	j=runner->line;
+	print_message(j->message, j->flags, j->from, j->to, NULL, window, 1);
+	*headpntr = (*headpntr)->next;
+	return;
+    } else if(scroll==1) {
+	if(runner->prev == NULL) {
+	    if (scrollBeep)
+		W_Beep();
+	    return;
+	}
+	j=runner->prev->line;
+	print_message(j->message, j->flags, j->from, j->to, NULL, window, 0);
+	*headpntr = (*headpntr)->prev;
+	return;
+    }
+    switch (key) {
+    case W_LBUTTON:
+	for (i = 0; (i < windowHeight-1) && runner->next; i++, runner = runner->next)
+	    ;
+	newcpntr=runner;
+	
+	if (runner->next == NULL) {
+	    if (scrollBeep)
+		W_Beep();
+	    break;
+	}
+	runner=runner->next;
+	for (i = 0; (i < windowHeight-1) && runner; i++, runner = runner->next) {
+	    j=runner->line;
+	    print_message(j->message, j->flags, j->from, j->to, NULL, window, 1);
+	}
+	if(i<windowHeight-1) {
+	    for(;i<windowHeight-1;i++)
+		W_WriteText(window,0,-1,0,"",0,0);
+	}
+	*headpntr=newcpntr;
+	break;
+    case W_RBUTTON:
+	if (runner->prev == NULL) {
+	    if (scrollBeep)
+		W_Beep();
+	    break;
+	}
+	for (i = 0; (i < windowHeight-1) && runner->prev; i++, runner = runner->prev) {
+	    j=runner->prev->line;
+	    print_message(j->message, j->flags, j->from, j->to, NULL, window, 0);
+	}
+	*headpntr = runner;
+	break;
+    case W_MBUTTON:
+	if (runner->prev == NULL) {
+	    if (scrollBeep)
+		W_Beep();
+	    break;
+	}
+	W_ClearWindow(window);
+	while (runner->prev)
+	    runner = runner->prev;
+	*headpntr = runner;
+	for (i = 0; i < windowHeight && runner->next; i++, runner = runner->next);
+	while (runner) {
+	    j = runner->line;
+	    print_message(j->message, j->flags, j->from, j->to, NULL, window, 0);
+	    runner = runner->prev;
+	}
+	break;
+    }
+}
+
+void
+rsvp_borg_call(message, from)
+    char   *message;
+    int     from;
+{
+#if 0
+    int     len, pos;
+    len = strlen(message);
+    pos = len - 5;
+    if (strncmp(message + pos, "     ", 5) == 0)
+#else
+    char   *chk;
+
+    if (strlen(message) < 15)
+	return;
+    for (chk = message + 10; *chk && *chk == ' '; chk++)
+	 /* empty body */ ;
+    if (*chk)
+	return;
+#endif
+    {
+	char    buf[120];
+
+	sprintf(buf, "Paradise Client %s (%s)", CLIENTVERS,
+#ifdef __osf__
+		"DEC OSF/1"
+#else
+#ifdef NeXT
+		"NeXT"
+#else
+#ifdef ultrix
+		"DEC Ultrix"
+#else
+#if defined(sparc) && defined(SVR4)
+		"Solaris"
+#else
+#ifdef sparc
+		"SUN4/Sparc"
+#else
+#ifdef sun
+		"SUN3"
+#else
+#ifdef sequent
+		"sequent"
+#else
+#ifdef hpux
+		"hpux"
+#else
+#ifdef AIX
+		"AIX"
+#else
+#ifdef vax
+		"vax"
+#else
+#ifdef sgi
+		"sgi/IRIX"
+#else
+#ifdef apollo
+		"apollo"
+#else
+#ifdef RS6K
+		"RS6K"
+#else
+#ifdef linux
+		"Linux"
+#else
+#ifdef __NetBSD__
+		"NetBSD"
+#else
+#ifdef __FreeBSD__
+		"FreeBSD"
+#else
+#ifdef AMIGA
+		"Amiga"
+#else
+		"generic"
+#endif				/* Amiga */
+#endif				/* linux */
+#endif				/* RS6K */
+#endif				/* apollo */
+#endif				/* sgi */
+#endif				/* vax */
+#endif				/* AIX */
+#endif				/* hpux */
+#endif				/* sequent */
+#endif				/* sun */
+#endif				/* sparc */
+#endif				/* solaris */
+#endif				/* ultrix */
+#endif				/* NeXT */
+#endif				/* __osf__ */
+#endif				/* FreeBSD */
+#endif				/* NetBSD */
+	    );
+	if (from == 255) {
+	    sendMessage(buf, MGOD, 0);
+	} else
+	    sendMessage(buf, MINDIV, from);
+    }
+}
+
+void
+logit(message)
+    char   *message;
+/* logs the given message if the 'logmess' variable is set to one.  It send the
+   message to stdout by default, or to a file if one is defined. [BDyess] */
+{
+    if (!logmess)
+	return;
+    if (logfilehandle && logFile) {
+	fprintf(logfilehandle, "%s\n", message);
+	fflush(logfilehandle);
+    } else {
+	printf("%s\n", message);
+    }
+}
+
+void
+writeMessage(data, message, color, len, winmask, type, backwards)
+    struct messageData *data;
+    char   *message;
+    W_Color color;
+    int     len;
+    W_Window winmask;
+    int     type;
+    int     backwards;
+{
+    struct messageNode *newhead;
+    struct messageWin *j;
+
+    if (data != NULL) {
+#ifdef SPEECH /* was AMIGA... ya never know ;-) */
+	if (((S_SpeakYour && type & WA_INDIV) ||
+	     (S_SpeakTeam && type & WA_TEAM) ||
+	     (S_SpeakAll && type & WA_ALL) ||
+	     (S_SpeakKill && type & WA_KILL)) &&
+	    ((strncmp(message,"GOD->",5) != 0) || S_SpeakGod) &&
+	    ((data->from != me->p_no) || S_SpeakSelf)) {
+	    S_SpeakString(message, len);
+	}
+#endif				/* SPEECH */
+#ifdef SOUND
+	if ((type & WA_INDIV) && data->from != me->p_no) {
+	    S_PlaySound(S_WHISTLE);
+	}
+#endif
+	for (j = &messWin[0]; j < &messWin[WNUM]; j++) {
+	    if (!(j->flags & type))
+		continue;
+	    newhead = (struct messageNode *) malloc(sizeof(struct messageNode));
+	    newhead->next = j->head;
+	    if (newhead->next)
+		newhead->next->prev = newhead;
+	    newhead->prev = NULL;
+	    newhead->line = data;
+	    if (j->head == j->curHead) {
+		/* we aren't currently scrolled back [BDyess] */
+		W_WriteText(j->window, 0, 0, color, message, len, 0);
+		j->curHead = newhead;
+	    }
+	    j->head = newhead;
+	}
+    } else {			/* we're drawing a new page */
+	for (j = &messWin[0]; j < &messWin[WNUM]; j++) {
+	    if (!(j->flags & type))
+		continue;
+	    if (j->window != winmask)
+		continue;
+	    W_WriteText(j->window, 0, (backwards ? -1 : 0), color, message, len, 0);
+	}
+    }
+}
+
+void
+print_message(message, flags, from, to, data, winmask, backwards)
+    char   *message;
+    unsigned int flags, from, to;
+    struct messageData *data;
+    W_Window winmask;
+    int backwards;
+/* this function determines the color that the given message should be and
+   then passes it to writeMessage, where the data structure for the scroll
+   back code is created and also where the winmask test is done.  The winmask
+   determines what window the message is written to, useful when calling this
+   routine from the scrollback routines.  If winmask == NULL it doesn't
+   limit printing at all, eg team messages will go to the team window and to
+   the total review window.  [BDyess] 12/07/93 */
+{
+    register int len;
+    W_Color color;
+    W_Window targwin;
+
+#define    take  MTEAM + MTAKE + MVALID
+#define    destroy  MTEAM + MDEST + MVALID
+#define    kill  MALL + MKILL + MVALID
+#define    killp  MALL + MKILLP + MVALID
+#define    killa  MALL + MKILLA + MVALID
+#define    bomb  MTEAM + MBOMB + MVALID
+#define    team  MTEAM + MVALID
+#define    conq  MALL + MCONQ + MVALID
+
+    len = strlen(message);
+    if (from == 254) {		/* client passing info around */
+	switch (showPhaser) {
+	case 0:
+	    break;
+	case 1:
+	    writeMessage(data, message, textColor, len, winmask, WA_KILL | WA_REVIEW, backwards);
+	    break;
+	case 2:
+	    writeMessage(data, message, textColor, len, winmask, WA_REVIEW | WA_PHASER, backwards);
+	    break;
+	case 3:
+	    writeMessage(data, message, textColor, len, winmask, WA_REVIEW, backwards);
+	    break;
+	}
+	return;
+    }
+    if (from == 255) {
+	if (flags == MCONFIG + MINDIV + MVALID) {
+/*       printf("Going to checkfeatures\n");*/
+	    CheckFeatures(message);
+	    return;
+	}
+	/* From God */
+	color = textColor;
+    } else {
+	/* kludge to fix the occasional incorrect color message */
+	if (*message == ' ' && from != me->p_no) {
+	    /* XXX fix to handle funky teams */
+	    switch (*(message + 1)) {
+	    case 'F':
+		color = W_Yellow;
+		break;
+	    case 'R':
+		color = W_Red;
+		break;
+	    case 'K':
+		color = W_Green;
+		break;
+	    case 'O':
+		color = W_Cyan;
+		break;
+	    case 'I':
+		color = W_Grey;
+		break;
+	    default:
+		color = playerColor(&(players[from]));
+	    }
+	} else
+	    color = playerColor(&(players[from]));
+    }
+
+    /* added/modified to fit with the scrollback feature 1/94 -JR */
+    if (!paradise && niftyNewMessages) {
+	if (flags == conq) {
+	    /* output conquer stuff to stdout in addition to message window */
+	    fprintf(stdout, "%s\n", message);
+	    if (instr(message, "kill")) {
+		fprintf(stdout, "NOTE: The server here does not properly set message flags\n");
+		fprintf(stdout, "You should probably pester the server god to update....\n");
+	    }
+	}
+	if ((flags == team) || (flags == take) || (flags == destroy)) {
+	    writeMessage(data, message, color, len, winmask, WA_TEAM | WA_REVIEW, backwards);
+	    targwin = messWin[WTEAM].window;
+	} else if ((flags == kill) || (flags == killp) || (flags == killa) || (flags == bomb)) {
+	    writeMessage(data, message, color, len, winmask,
+			 WA_KILL | (reportKills ? WA_REVIEW : 0), backwards);
+	    targwin = messWin[WKILL].window;
+	} else if (flags & MINDIV) {
+	    writeMessage(data, message, color, len, winmask, (WA_INDIV | WA_REVIEW), backwards);
+	    targwin = messWin[WINDIV].window;
+	} else if (flags == (MMACRO | MALL)) {
+	    writeMessage(data, message, color, len, winmask, (WA_MACRO | WA_REVIEW), backwards);
+	    targwin = messWin[WALL].window;
+	} else {
+	    /*
+	       if we don't know where the message belongs by this time, stick
+	       it in the all board...
+	    */
+	    writeMessage(data, message, color, len, winmask, (WA_ALL | WA_REVIEW), backwards);
+	    targwin = messWin[WALL].window;
+	}
+    } else {
+
+	/*
+	   Kludge stuff for report kills...
+	*/
+	if ((strncmp(message, "GOD->ALL", 8) == 0 &&
+	     (instr(message, "was kill") ||
+	      instr(message, "killed by"))) ||
+	    instr(message, "burned to a crisp by") ||
+	    instr(message, "shot down by") ||
+	    (*message != ' ' && instr(message, "We are being attacked"))) {
+	    writeMessage(data, message, color, len, winmask,
+			 WA_KILL | (reportKills ? WA_REVIEW : 0), backwards);
+	    return;
+	}
+	/*
+	   note: messages are kept track of even if the associated window is
+	   not mapped.  This allows the window to be later mapped and have
+	   all the past messages. [BDyess]
+	*/
+	if (flags & MTEAM) {
+	    writeMessage(data, message, color, len, winmask, WA_TEAM | WA_REVIEW, backwards);
+	    targwin = messWin[WTEAM].window;
+	} else if (flags & MINDIV) {
+	    writeMessage(data, message, color, len, winmask, WA_INDIV | WA_REVIEW, backwards);
+	    targwin = messWin[WINDIV].window;
+	} else if (flags == (MMACRO | MALL)) {
+	    writeMessage(data, message, color, len, winmask, WA_MACRO | WA_REVIEW, backwards);
+	    targwin = messWin[WALL].window;
+	} else {
+	    writeMessage(data, message, color, len, winmask, WA_ALL | WA_REVIEW, backwards);
+	    targwin = messWin[WALL].window;
+	}
+    }
+    /*
+       send warnings to warning or message window, if player doesn't have
+       messag es mapped
+    */
+    if ((use_msgw && (targwin == messWin[WINDIV].window || targwin == messWin[WTEAM].window)) ||
+	(!W_IsMapped(targwin) && !W_IsMapped(messWin[WREVIEW].window))) {
+	if (!messpend && messagew) {	/* don't collide with messages being
+					   written! */
+	    W_ClearWindow(messagew);
+	    W_WriteText(messagew, 5, 5, color, message, len, W_RegularFont);
+	} else
+	    warning(message);
+    }
+}
+
+void
+dmessage(message, flags, from, to)
+    char   *message;
+    unsigned int flags, from, to;
+/* prints the given message by going though several subroutines.  Here, it first
+   creates the data structure that holds the message info and logs the message,
+   then sends it on it's subroutine path to print it to the correct window(s).
+   This is a good place to handle any special-functions that occur due to
+   incoming messages.  The data structure for the scroll back is like this:
+   each window has a head pointer that points to the top of its message
+   list.  Each list only contains the messages that go to it's window.  The
+   lists have pointers to the message itself, so that only one copy of the
+   message exists even if it is displayed on several windows.  Each list also
+   has a current head pointer that points to the record that is at the bottom
+   of that current window.  If the current head pointer and the head pointer
+   are different, then the window must be scrolled back.  In such a case, new
+   messages are still received but not printed.  [BDyess] 12/07/93 */
+{
+    struct messageData *data;
+    struct distress dist;
+    int len;
+
+#ifdef RC_DISTRESS
+    /* aha! A new type distress/macro call came in. parse it appropriately */
+    if (F_gen_distress && (flags == (MTEAM | MDISTR | MVALID))) {
+	HandleGenDistr(message, from, to, &dist);
+	len = makedistress(&dist, message, distmacro[dist.distype].macro);
+#ifdef BEEPLITE
+	if (UseLite)
+	    rcdlite(&dist);
+#endif
+	if (len <= 0)
+	    return;
+	flags ^= MDISTR;
+    }
+#endif
+    /*
+       add create message data struct.  Used for message scrollback
+       capability.  [BDyess]
+    */
+    data = (struct messageData *) malloc(sizeof(struct messageData));
+    data->message = (char *) strdup(message);
+    data->flags = flags;
+    data->from = from;
+    data->to = to;
+    /*
+       keep track of how many queued messages there are for use with the
+       infoIcon [BDyess]
+    */
+    if (infoIcon) {
+	if (to == me->p_no && flags & MINDIV) {	/* personal message */
+	    me_messages++;
+	} else if (flags & MTEAM) {	/* team message */
+	    team_messages++;
+	} else {		/* message for all */
+	    all_messages++;
+	}
+	if (iconified)
+	    drawIcon();
+    }
+    logit(message);
+
+    /*
+       fix for upgrade bug.  Forced UDP would resend numbers, (thinking them
+       speed changes) screwing up upgrading on those twinkish sturgeon
+       servers. [BDyess]
+    */
+    if (strncmp(message, "UPG->", 5) == 0)
+	upgrading = 1;
+    if (upgrading && !(me->p_flags & PFORBIT))
+	upgrading = 0;
+
+    if ((from != me->p_no) || pigSelf)
+	rsvp_borg_call(message, from);
+
+    /* beep when a personal message is sent while iconified [BDyess] */
+    if (to == me->p_no && (flags & MINDIV) && iconified) {
+	W_Beep();
+    }
+    if (from == 255 &&
+	strcmp(message, "Tractor beam aborted warp engagement") == 0) {
+	me->p_flags &= ~PFWARPPREP;
+    }
+    print_message(message, flags, from, to, data, NULL, 0);
+}
+
+
+int
+instr(string1, string2)
+    char   *string1, *string2;
+{
+    char   *s;
+    int     length;
+
+    length = strlen(string2);
+    for (s = string1; *s != 0; s++) {
+	if (*s == *string2 && strncmp(s, string2, length) == 0)
+	    return (1);
+    }
+    return (0);
+}
+
+void
+CheckFeatures(m)
+    char   *m;
+/* I don't know if this works correctly or not.  It is ripped from BRM and has
+   been modified a bit to fit.  Right now it doesn't do anything.  [BDyess] */
+{
+    char    buf[BUFSIZ];
+    char   *pek = &m[10];
+
+    if ((int) strlen(m) < 11)
+	return;
+
+    while ((*pek == ' ') && (*pek != '\0'))
+	pek++;
+
+    strcpy(buf, "Paradise Client: ");
+
+    if (!strcmp(pek, "NO_VIEW_BOX")) {
+	allowViewBox = 0;
+	strcat(buf, pek);
+    }
+#ifdef CONTINUOUS_MOUSE
+    if (!strcmp(pek, "NO_CONTINUOUS_MOUSE")) {
+	allowContinuousMouse = 0;
+	strcat(buf, pek);
+    }
+#endif				/* CONTINUOUS_MOUSE */
+    if (!strcmp(pek, "NO_SHOW_ALL_TRACTORS")) {
+	allowShowAllTractorPressor = 0;
+	strcat(buf, pek);
+    }
+    if (!strcmp(pek, "HIDE_PLAYERLIST_ON_ENTRY")) {
+	allowPlayerlist = 0;
+	strcat(buf, pek);
+    }
+    if (!strcmp(pek, "NO_NEWMACRO")) {
+/*      UseNewMacro = 0;*/
+	strcat(buf, pek);
+    }
+    if (!strcmp(pek, "NO_SMARTMACRO")) {
+/*      UseSmartMacro = 0;*/
+	strcat(buf, pek);
+    }
+    if (!strcmp(pek, "WHY_DEAD")) {
+	why_dead = 1;
+	strcat(buf, pek);
+    }
+    if (!strcmp(pek, "RC_DISTRESS")) {
+/*      gen_distress = 1;*/
+/*      distmacro = dist_prefered;*/
+	strcat(buf, pek);
+    }
+    /* what the hell is this? - jmn */
+    if (!strncmp(pek, "INFO", 4)) {
+	strcat(buf, pek);
+    }
+    if (strlen(buf) == strlen("Paradise Client: ")) {
+	strcat(buf, "UNKNOWN FEATURE: ");
+	strcat(buf, pek);
+    }
+    buf[79] = '\0';
+
+    printf("%s\n", buf);
+
+    W_WriteText(messWin[WREVIEW].window, 0, 0, W_White, buf, strlen(buf), 0);
+    W_WriteText(messWin[WALL].window, 0, 0, W_White, buf, strlen(buf), 0);
+}
+
+void
+sendVersion()
+{
+    static int version_sent = 0;
+    char    buf[80];
+
+    if (!version_sent) {
+	version_sent = 1;
+	sprintf(buf, "@%s", CLIENTVERS);
+	pmessage(buf, me->p_no, MINDIV | MCONFIG);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emph_planet_seq.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,40 @@
+/* $Id: emph_planet_seq.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#define emph_planet_seq_width 24
+#define emph_planet_seq_height 24
+#define emph_planet_seq_frames 5
+static char emph_planet_seq_bits[emph_planet_seq_frames][72] = {{
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00,
+	0x00, 0x83, 0x01, 0xc0, 0x00, 0x06, 0x40, 0x00, 0x04, 0x20, 0x00, 0x08,
+	0x20, 0x00, 0x08, 0x10, 0x00, 0x10, 0x10, 0x00, 0x10, 0x10, 0x00, 0x10,
+	0x10, 0x00, 0x10, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x20, 0x00, 0x08,
+	0x40, 0x00, 0x04, 0xc0, 0x00, 0x06, 0x00, 0x83, 0x01, 0x00, 0x7c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x80, 0x01, 0x03,
+    0x40, 0x00, 0x04, 0x20, 0x00, 0x08, 0x10, 0x00, 0x10, 0x10, 0x00, 0x10,
+    0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20,
+    0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x10, 0x00, 0x10,
+    0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x04, 0x80, 0x01, 0x03,
+0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x80, 0x01, 0x03, 0x40, 0x00, 0x04,
+    0x20, 0x00, 0x08, 0x10, 0x00, 0x10, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20,
+    0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40,
+    0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x08, 0x00, 0x20,
+    0x08, 0x00, 0x20, 0x10, 0x00, 0x10, 0x20, 0x00, 0x08, 0x40, 0x00, 0x04,
+0x80, 0x01, 0x03, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0xfe, 0x00, 0x80, 0x01, 0x03, 0x60, 0x00, 0x0c, 0x10, 0x00, 0x10,
+    0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40,
+    0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80,
+    0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x04, 0x00, 0x40,
+    0x04, 0x00, 0x40, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20, 0x10, 0x00, 0x10,
+0x60, 0x00, 0x0c, 0x80, 0x01, 0x03, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0xff, 0x01, 0xc0, 0x00, 0x06, 0x30, 0x00, 0x18, 0x08, 0x00, 0x20,
+    0x08, 0x00, 0x20, 0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x02, 0x00, 0x80,
+    0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80,
+    0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80, 0x02, 0x00, 0x80,
+    0x04, 0x00, 0x40, 0x04, 0x00, 0x40, 0x08, 0x00, 0x20, 0x08, 0x00, 0x20,
+0x30, 0x00, 0x18, 0xc0, 0x00, 0x06, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00}};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emph_player_seq.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,26 @@
+/* $Id: emph_player_seq.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#define emph_player_seq_width 24
+#define emph_player_seq_height 24
+#define emph_player_seq_frames 3
+static char emph_player_seq_bits[emph_player_seq_frames][72] = {{
+	0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x80, 0x9c, 0x00,
+	0x80, 0xff, 0x00, 0xc0, 0xc1, 0x01, 0x60, 0x00, 0x03, 0x38, 0x00, 0x0e,
+	0x30, 0x00, 0x06, 0x10, 0x00, 0x04, 0x18, 0x00, 0x0c, 0x1e, 0x00, 0x3c,
+	0x18, 0x00, 0x0c, 0x10, 0x00, 0x04, 0x30, 0x00, 0x06, 0x38, 0x00, 0x0e,
+	0x60, 0x00, 0x03, 0xc0, 0xc1, 0x01, 0x80, 0xff, 0x00, 0x80, 0x9c, 0x00,
+0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x40, 0x1c, 0x01, 0xc0, 0xff, 0x01,
+    0xc0, 0xff, 0x01, 0xe0, 0x80, 0x03, 0x7c, 0x00, 0x1f, 0x38, 0x00, 0x0e,
+    0x18, 0x00, 0x0c, 0x18, 0x00, 0x0c, 0x1c, 0x00, 0x1c, 0x1f, 0x00, 0x7c,
+    0x1c, 0x00, 0x1c, 0x18, 0x00, 0x0c, 0x18, 0x00, 0x0c, 0x38, 0x00, 0x0e,
+    0x7c, 0x00, 0x1f, 0xe0, 0x80, 0x03, 0xc0, 0xff, 0x01, 0xc0, 0xff, 0x01,
+0x40, 0x1c, 0x01, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/emph_player_seql.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,38 @@
+/* $Id: emph_player_seql.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#define emph_player_seql_width 30
+#define emph_player_seql_height 30
+#define emph_player_seql_frames 3
+static char emph_player_seql_bits[emph_player_seql_frames][120] = {{
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x18, 0x06, 0x00,
+	0x80, 0xfc, 0x4f, 0x00, 0x80, 0x0f, 0x7c, 0x00, 0xc0, 0x01, 0xe0, 0x00,
+	0x60, 0x00, 0x80, 0x01, 0x38, 0x00, 0x00, 0x07, 0x30, 0x00, 0x00, 0x03,
+	0x10, 0x00, 0x00, 0x02, 0x18, 0x00, 0x00, 0x06, 0x1e, 0x00, 0x00, 0x1e,
+	0x0c, 0x00, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x04,
+	0x08, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x04, 0x0c, 0x00, 0x00, 0x0c,
+	0x1e, 0x00, 0x00, 0x1e, 0x18, 0x00, 0x00, 0x06, 0x10, 0x00, 0x00, 0x02,
+	0x30, 0x00, 0x00, 0x03, 0x38, 0x00, 0x00, 0x07, 0x60, 0x00, 0x80, 0x01,
+	0xc0, 0x01, 0xe0, 0x00, 0x80, 0x0f, 0x7c, 0x00, 0x80, 0xfc, 0x4f, 0x00,
+0x00, 0x18, 0x06, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x08, 0x04, 0x00, 0x00, 0x18, 0x06, 0x00, 0x40, 0xfc, 0x8f, 0x00,
+    0xc0, 0xff, 0xff, 0x00, 0xc0, 0x0f, 0xfc, 0x00, 0xe0, 0x00, 0xc0, 0x01,
+    0x7c, 0x00, 0x80, 0x0f, 0x38, 0x00, 0x00, 0x07, 0x18, 0x00, 0x00, 0x06,
+    0x18, 0x00, 0x00, 0x06, 0x1c, 0x00, 0x00, 0x0e, 0x1f, 0x00, 0x00, 0x3e,
+    0x0e, 0x00, 0x00, 0x1c, 0x0c, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x0c,
+    0x0c, 0x00, 0x00, 0x0c, 0x0c, 0x00, 0x00, 0x0c, 0x0e, 0x00, 0x00, 0x1c,
+    0x1f, 0x00, 0x00, 0x3e, 0x1c, 0x00, 0x00, 0x0e, 0x18, 0x00, 0x00, 0x06,
+    0x18, 0x00, 0x00, 0x06, 0x38, 0x00, 0x00, 0x07, 0x7c, 0x00, 0x80, 0x0f,
+    0xe0, 0x00, 0xc0, 0x01, 0xc0, 0x0f, 0xfc, 0x00, 0xc0, 0xff, 0xff, 0x00,
+0x40, 0xfc, 0x8f, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0x08, 0x04, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/enter.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,65 @@
+/* $Id: enter.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * enter.c
+ *
+ * This version modified to work as the client in a socket based protocol.
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <ctype.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "packets.h"
+
+/* Enter the game */
+
+/* Prototypes */
+
+void
+enter()
+{
+    redrawTstats();
+    delay = 0;
+}
+
+/* Doesn't really openmem, but it will
+ * set some stuff up...
+ */
+static struct status dummy1;
+static struct status2 dummy2;
+void
+openmem()
+{
+    /* players, weapons, planets are handled in build_default_configuration */
+
+    /* thingies allocation is handled in build_default_configuration */
+    /* thingies = universe.drones; */
+
+
+    status = &dummy1;
+    status2 = &dummy2;
+
+    /* mctl->mc_current=0; */
+    status->time = 1;
+    status->timeprod = 1;
+    status->kills = 1;
+    status->losses = 1;
+    status->time = 1;
+    status->planets = 1;
+    status->armsbomb = 1;
+
+    if (ghoststart) {
+	me = &players[ghost_pno];
+	myship = me->p_ship;
+	mystats = &(me->p_stats);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/expire.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,45 @@
+/* $Id: expire.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#ifndef hpux
+#include <sys/time.h>
+#endif
+#include <time.h>
+#include <stdio.h>
+
+
+/* Here's a handy perl script to set any timeout you want:
+
+   perl -e 'require "timelocal.pl"; print &timelocal(0,0,0,9,9,93);'
+
+   The arguments to timelocal are (sec, min, hours, mday, mon, year).
+   These are all 0 based indexing so the 7th day of the month is
+   really 6 to the perl script.
+   */
+
+static time_t expire = 915091200;
+
+void 
+checkExpire(verbose)
+    int     verbose;
+{
+    time_t  now;
+
+    now = time(NULL);
+    if (verbose) {
+	printf("This client expires on %s\n", ctime(&expire));
+	return;
+    }
+    if (now > expire) {
+	printf("\
+  I'm sorry.  This client has expired.  You may bypass the expire by\n\
+using the -o option which disables RSA authentication.  Expired\n\
+clients are not supported by paradise-workers.\n\
+  You can find a new set of binaries on ftp.pnetrek.org OR ftp.cs.umn.edu \n\
+in the directory /users/glamm/paradise/bin/.  If you have any problems mail \n\
+to paradise-workers@pnetrek.org\n");
+	exit(0);
+
+    } else if (now + 10 * 24 * 60 * 60 > expire) {
+	printf("This client expires in %d days.\n", (int) (expire - now) / (60 * 60 * 24));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/feature.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,222 @@
+/* $Id: feature.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * Feature.c
+ *
+ * March, 1994.    Joe Rumsey, Tedd Hadley
+ *
+ * most of the functions needed to handle SP_FEATURE/CP_FEATURE
+ * packets.  fill in the features list below for your client, and
+ * add a call to reportFeatures just before the RSA response is sent.
+ * handleFeature should just call checkFeature, which will search the
+ * list and set the appropriate variable.  features unknown to the
+ * server are set to the desired value for client features, and off
+ * for server/client features.
+ *
+ * feature packets look like:
+struct feature_cpacket {
+   char                 type;
+   char                 feature_type;
+   char                 arg1,
+                        arg2;
+   int                  value;
+   char                 name[80];
+};
+
+ *  type is CP_FEATURE, which is 60.  feature_spacket is identical.
+ */
+
+
+#ifdef FEATURE
+#include "copyright.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "packets.h"
+
+
+void    sendFeature P((char *name, int feature_type,
+		       int value, int arg1, int arg2));
+void    reportFeatures P((void));
+
+/* not the actual packets: this holds a list of features to report for */
+/* this client. */
+struct feature {
+    char   *name;
+    int    *var;		/* holds allowed/enabled status */
+    char    feature_type;	/* 'S' or 'C' for server/client */
+    int     value;		/* desired status */
+    char   *arg1, *arg2;	/* where to copy args, if non-null */
+} features[] = {
+    /*
+       also sent seperately, put here for checking later. should be ok that
+       it's sent twice.
+    */
+    {"FEATURE_PACKETS", &F_feature_packets, 'S', 1, 0, 0},
+
+    {"VIEW_BOX", &allowViewBox, 'C', 1, 0, 0},
+    {"SHOW_ALL_TRACTORS", &allowShowAllTractorPressor, 'S', 1, 0, 0},
+#ifdef CONTINUOUS_MOUSE
+    {"CONTINUOUS_MOUSE", &allowContinuousMouse, 'C', 1, 0, 0},
+#endif
+    {"NEWMACRO", &F_UseNewMacro, 'C', 1, 0, 0},
+    /* {"SMARTMACRO",&UseSmartMacro, 'C', 1, 0, 0}, */
+    {"MULTIMACROS", &F_multiline_enabled, 'S', 1, 0, 0},
+    {"WHY_DEAD", &why_dead, 'S', 1, 0, 0},
+    {"CLOAK_MAXWARP", &cloakerMaxWarp, 'S', 1, 0, 0},
+/*{"DEAD_WARP", &F_dead_warp, 'S', 1, 0, 0},*/
+#ifdef RC_DISTRESS
+    {"RC_DISTRESS", &F_gen_distress, 'S', 1, 0, 0},
+#ifdef BEEPLITE
+    {"BEEPLITE", &F_allow_beeplite, 'C', 1, (char*)&F_beeplite_flags, 0},
+#endif
+#endif
+/* terrain features */
+    {"TERRAIN", &F_terrain, 'S', 1, (char*)&F_terrain_major, (char*)&F_terrain_minor},
+/* Gzipped MOTD */
+    {"GZ_MOTD", &F_gz_motd, 'S', 1, (char*)&F_gz_motd_major, (char*)&F_gz_motd_minor},
+    {0, 0, 0, 0, 0, 0}
+};
+
+void
+checkFeature(packet)
+    struct feature_spacket *packet;
+{
+    int     i;
+    int     value = ntohl(packet->value);
+
+#ifdef FEAT_DEBUG
+    if (packet->type != SP_FEATURE) {
+	printf("Packet type %d sent to checkFeature!\n", packet->type);
+	return;
+    }
+#endif
+    printf("%s: %s(%d)\n", &packet->name[0],
+	   ((value == 1) ? "ON" : (value == 0) ? "OFF" : "UNKNOWN"),
+	   value);
+
+    for (i = 0; features[i].name != 0; i++) {
+	if (strcmpi(packet->name, features[i].name) == 0) {
+	    /*
+	       if server returns unknown, set to off for server mods, desired
+	       value for client mods. Otherwise,  set to value from server.
+	    */
+	    *features[i].var = (value == -1 ?
+		 (features[i].feature_type == 'S' ? 0 : features[i].value) :
+				value);
+	    if (features[i].arg1)
+		*features[i].arg1 = packet->arg1;
+	    if (features[i].arg2)
+		*features[i].arg2 = packet->arg2;
+	    break;
+	}
+    }
+    if (features[i].name == 0) {
+	printf("Feature %s from server unknown to client!\n", packet->name);
+    }
+/* special cases: */
+    if ((strcmpi(packet->name, "FEATURE_PACKETS")==0))
+	reportFeatures();
+    else if ((strcmpi(packet->name, "RC_DISTRESS") == 0) && F_gen_distress)
+	distmacro = dist_prefered;
+    else if ((strcmpi(packet->name, "BEEPLITE") == 0)) {
+	switch (value) {
+	case -1:		/* Unknown, we can use all of the features! */
+	    F_beeplite_flags = LITE_PLAYERS_MAP |
+		LITE_PLAYERS_LOCAL |
+		LITE_SELF |
+		LITE_PLANETS |
+		LITE_SOUNDS |
+		LITE_COLOR;
+	    break;
+	case 1:
+	    if (F_beeplite_flags == 0) {	/* Server says we can have
+						   beeplite, but no
+						   options??? must be
+						   configured wrong. */
+		F_beeplite_flags = LITE_PLAYERS_MAP |
+		    LITE_PLAYERS_LOCAL |
+		    LITE_SELF |
+		    LITE_PLANETS |
+		    LITE_SOUNDS |
+		    LITE_COLOR;
+	    }
+	    if (!(F_beeplite_flags & LITE_PLAYERS_MAP))
+		printf("  LITE_PLAYERS_MAP   disabled\n");
+	    if (!(F_beeplite_flags & LITE_PLAYERS_LOCAL))
+		printf("  LITE_PLAYERS_LOCAL disabled\n");
+	    if (!(F_beeplite_flags & LITE_SELF))
+		printf("  LITE_SELF          disabled\n");
+	    if (!(F_beeplite_flags & LITE_PLANETS))
+		printf("  LITE_PLANETS       disabled\n");
+	    if (!(F_beeplite_flags & LITE_SOUNDS))
+		printf("  LITE_SOUNDS        disabled\n");
+	    if (!(F_beeplite_flags & LITE_COLOR))
+		printf("  LITE_COLOR         disabled\n");
+	    break;
+	default:
+	    break;
+	}
+    }
+}
+
+/* call this from handleReserved */
+void
+reportFeatures()
+{
+    struct feature *f;
+
+    /* 
+       Don't send features[0], which is the feature for FEATURE_PACKETS itself.
+       That's sent from main()
+     */
+    for (f = &features[1]; f->name != 0; f++) {
+	sendFeature(f->name,
+		    f->feature_type,
+		    f->value,
+		    (f->arg1 ? *f->arg1 : 0),
+		    (f->arg2 ? *f->arg2 : 0));
+#ifdef FEAT_DEBUG
+	printf("(C->S) %s (%c): %d\n", f->name, f->feature_type, f->value);
+#endif
+    }
+}
+
+void
+sendFeature(name, feature_type, value, arg1, arg2)
+    char   *name;
+    int     feature_type;
+    int     value;
+    int     arg1, arg2;
+{
+    struct feature_cpacket packet;
+
+#ifdef FEAT_DEBUG
+    printf( "Sending feature %s (value = %d)\n", name, value );
+#endif
+    strncpy(packet.name, name, sizeof(packet.name));
+    packet.type = CP_FEATURE;
+    packet.name[sizeof(packet.name) - 1] = 0;
+    packet.feature_type = feature_type;
+    packet.value = htonl(value);
+    packet.arg1 = arg1;
+    packet.arg2 = arg2;
+    sendServerPacket((struct player_spacket *) & packet);
+}
+
+void
+handleFeature(packet)
+    struct feature_spacket *packet;
+{
+#ifdef FEAT_DEBUG
+    printf( "Handling Feature packet\n" );
+#endif
+    checkFeature(packet);
+}
+#endif				/* FEATURE */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/findslot.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,246 @@
+/* $Id: findslot.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * findslot.c
+ *
+ * Kevin Smith 03/23/88
+ *
+ */
+#include "copyright2.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <ctype.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+#define WAITWIDTH 180
+#define WAITHEIGHT 60
+#define WAITTITLE 15		/* height of title for wait window */
+#define WAITICONHEIGHT 50
+#define WAITICONWIDTH  50
+
+/* Prototypes */
+static void mapWaitCount P((W_Window countWin, unsigned int count));
+static void mapWaitQuit P((W_Window qwin));
+static void mapWaitWin P((W_Window waitWin));
+static void mapMotdButtonWin P((W_Window motdButtonWin));
+static void mapWaitIcon 
+P((W_Window waitIcon, unsigned int count,
+   int *motdMapLater));
+
+    extern int newMotdStuff;	/* from newwin.c */
+
+
+    int     findslot()
+{
+    int     oldcount = -1;
+    W_Window waitWin, qwin, countWin, motdButtonWin, waitIcon;
+    W_Event event;
+    int     motdMapLater = 0;
+
+    /* Wait for some kind of indication about in/not in */
+    while (queuePos == -1) {
+	socketPause(1, 0);
+	if (isServerDead()) {
+	    printf("Augh!  Ghostbusted!\n");
+	    EXIT(0);
+	}
+	readFromServer();
+	if (me != NULL) {
+	    /* We are in! */
+	    printf("*** socket %d, player %d ( -s %d -G %d [-2] ) ***\n",
+		   nextSocket, me->p_no,
+		   nextSocket, me->p_no);
+	    return (me->p_no);
+	}
+    }
+
+    /* We have to wait.  Make appropriate windows, etc... */
+    waitWin = W_MakeWindow("wait", 0, 0, WAITWIDTH, WAITHEIGHT, NULL, (char *) 0, 2, foreColor);
+    countWin = W_MakeWindow("count", WAITWIDTH / 3, WAITTITLE, 2 * WAITWIDTH / 3,
+		 WAITHEIGHT - WAITTITLE, waitWin, (char *) 0, 1, foreColor);
+    qwin = W_MakeWindow("waitquit", 0, WAITTITLE, WAITWIDTH / 3,
+		 WAITHEIGHT - WAITTITLE, waitWin, (char *) 0, 1, foreColor);
+    motdButtonWin = W_MakeWindow("motd_select", 2 * WAITWIDTH / 3, WAITTITLE,
+      WAITWIDTH, WAITHEIGHT - WAITTITLE, waitWin, (char *) 0, 1, foreColor);
+    waitIcon = W_MakeWindow("wait_icon", 0, 0, WAITICONWIDTH, WAITICONHEIGHT,
+			    NULL, NULL, BORDER, foreColor);
+    W_SetIconWindow(waitWin, waitIcon);
+    /* showMotdWin(); */
+#ifndef AMIGA
+    W_MapWindow(waitWin);
+    W_MapWindow(countWin);
+    W_MapWindow(qwin);
+    W_MapWindow(motdButtonWin);
+#else
+    W_MapWindow(waitIcon);
+#endif
+    for (;;) {
+	socketPause(0, 10000);
+	readFromServer();
+	if (isServerDead()) {
+	    printf("We've been ghostbusted!\n");
+	    EXIT(0);
+	}
+	if (newMotdStuff)
+	    showMotd(motdWin);
+	while (W_EventsPending()) {
+	    W_NextEvent(&event);
+	    switch ((int) event.type) {
+	    case W_EV_KEY:
+		if (event.Window == motdWin) {
+		    motdWinEvent(event.key);
+		}
+#ifdef AMIGA
+		else if (event.Window == waitIcon) {
+		    switch (event.key) {
+		    case 'q':
+		    case 'Q':
+			printf("OK, bye!\n");
+			EXIT(0);
+		    case 'm':
+		    case 'M':
+			showMotdWin();
+			break;
+		    default:
+			break;
+		    }
+		}
+#endif
+	    case W_EV_BUTTON:	/* fall through */
+		if (event.Window == qwin) {
+		    printf("OK, bye!\n");
+		    EXIT(0);
+		} else if (event.Window == motdButtonWin) {
+		    showMotdWin();
+		} else if (event.Window == waitIcon) {
+		    mapWaitIcon(waitIcon, queuePos, NULL);
+		}
+		break;
+	    case W_EV_EXPOSE:
+		if (event.Window == waitWin) {
+		    if (motdMapLater) {
+			showMotd(motdWin);
+			motdMapLater = 0;
+		    }
+		    mapWaitWin(waitWin);
+		} else if (event.Window == qwin) {
+		    mapWaitQuit(qwin);
+		} else if (event.Window == countWin) {
+		    mapWaitCount(countWin, queuePos);
+		} else if (event.Window == motdWin) {
+		    showMotd(motdWin);
+		} else if (event.Window == motdButtonWin) {
+		    mapMotdButtonWin(motdButtonWin);
+		} else if (event.Window == waitIcon) {
+		    mapWaitIcon(waitIcon, queuePos, &motdMapLater);
+		}
+		break;
+	    default:
+		break;
+	    }
+	}
+	if (queuePos != oldcount) {
+	    mapWaitCount(countWin, queuePos);
+	    mapWaitIcon(waitIcon, queuePos, NULL);
+	    oldcount = queuePos;
+	}
+	if (me != NULL) {
+	    W_DestroyWindow(waitWin);
+#ifdef AMIGA
+	    W_DestroyWindow(waitIcon);
+#endif
+	    printf("*** socket %d, player %d ( -s %d -G %d [-2] ) ***\n",
+		   nextSocket, me->p_no,
+		   nextSocket, me->p_no);
+	    return (me->p_no);
+	}
+    }
+}
+
+static void
+mapWaitWin(waitWin)
+    W_Window waitWin;
+{
+    char   *s = "Netrek: Game is full.";
+
+    W_WriteText(waitWin, 15, 5, textColor, s, strlen(s), W_RegularFont);
+}
+
+static void
+mapWaitQuit(qwin)
+    W_Window qwin;
+{
+    char   *s = "Quit";
+
+    W_WriteText(qwin, 15, 15, textColor, s, strlen(s), W_RegularFont);
+}
+
+static void
+mapWaitCount(countWin, count)
+    W_Window countWin;
+    unsigned int count;
+{
+    char   *s = "Wait";
+    char   *t = "Queue";
+    char    buf[10];
+    register int len;
+
+    W_WriteText(countWin, 15, 5, textColor, s, strlen(s), W_RegularFont);
+    W_WriteText(countWin, 20, 15, textColor, t, strlen(t), W_RegularFont);
+    sprintf(buf, "%d    ", count);
+    len = strlen(buf);
+    if (count == -1)
+	strcpy(buf, "?");
+    W_WriteText(countWin, WAITWIDTH / 6 - len * W_Textwidth / 2, 25, textColor, buf,
+		len, W_RegularFont);
+}
+
+static void
+mapMotdButtonWin(motdButtonWin)
+    W_Window motdButtonWin;
+{
+    char   *s = "MOTD";
+
+    W_WriteText(motdButtonWin, 15, 15, textColor, s, strlen(s), W_RegularFont);
+}
+
+static void
+mapWaitIcon(waitIcon, count, motdMapLater)
+    W_Window waitIcon;
+    unsigned int count;
+    int    *motdMapLater;
+{
+    char    buf[5];
+    int     len;
+
+    sprintf(buf, "%d", count);
+    len = strlen(buf);
+#ifndef AMIGA
+    if (motdMapLater && W_IsMapped(motdWin)) {
+	*motdMapLater = 1;
+	W_UnmapWindow(motdWin);
+    }
+    W_WriteText(waitIcon, WAITICONWIDTH / 2 - 10, W_Textheight, textColor, buf, len,
+		W_BigFont);
+#else
+
+    W_WriteText(waitIcon, WAITICONWIDTH / 2 - 10, W_Textheight, textColor, buf, len,
+		W_RegularFont);
+/* using the iconWin in place of the 4 separate windows I get otherwise. -JR */
+    W_WriteText(waitIcon, 0, 0, textColor, serverName, strlen(serverName), W_RegularFont);
+    W_WriteText(waitIcon, 0, 2 * W_Textheight, textColor, "Q to quit", 9, W_RegularFont);
+    W_WriteText(waitIcon, 0, 3 * W_Textheight, textColor, "M for Motd", 10, W_RegularFont);
+#endif
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gameconf.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,825 @@
+/* $Id: gameconf.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <time.h>
+#ifndef hpux
+#include <sys/time.h>
+#endif
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+
+#include "gameconf.h"
+#include "defaultlogos.h"
+#include "data.h"
+#include "gppackets.h"
+
+int     number_of_teams;
+
+struct teaminfo_s *teaminfo = 0;
+
+void
+load_default_teams()
+{
+    number_of_teams = 4;
+
+    /* independent is teaminfo[-1], allteam is teaminfo[4] */
+    teaminfo = 1 + (struct teaminfo_s *) malloc(sizeof(*teaminfo) * (number_of_teams + 2));
+
+    strcpy(teaminfo[-1].name, "Independant");
+    teaminfo[-1].letter = 'I';
+    strcpy(teaminfo[-1].shortname, "IND");
+
+    strcpy(teaminfo[0].name, "Federation");
+    teaminfo[0].letter = 'F';
+    strcpy(teaminfo[0].shortname, "FED");
+
+
+    strcpy(teaminfo[1].name, "Romulan");
+    teaminfo[1].letter = 'R';
+    strcpy(teaminfo[1].shortname, "ROM");
+
+
+    strcpy(teaminfo[2].name, "Klingon");
+    teaminfo[2].letter = 'K';
+    strcpy(teaminfo[2].shortname, "KLI");
+
+
+    strcpy(teaminfo[3].name, "Orion");
+    teaminfo[3].letter = 'O';
+    strcpy(teaminfo[3].shortname, "ORI");
+
+    strcpy(teaminfo[4].name, "None");
+    teaminfo[4].letter = '-';
+    strcpy(teaminfo[4].shortname, "NON");
+}
+
+void
+load_default_teamlogos()
+{
+    if (number_of_teams < 1)
+	return;
+    teaminfo[0].shield_logo = W_StoreBitmap(fedshield_width, fedshield_height,
+					    fedshield_bits, teamWin[0]);
+    if (number_of_teams < 2)
+	return;
+    teaminfo[1].shield_logo = W_StoreBitmap(romshield_width, romshield_height,
+					    romshield_bits, teamWin[1]);
+    if (number_of_teams < 3)
+	return;
+    teaminfo[2].shield_logo = W_StoreBitmap(klishield_width, klishield_height,
+					    klishield_bits, teamWin[2]);
+    if (number_of_teams < 4)
+	return;
+    teaminfo[3].shield_logo = W_StoreBitmap(orishield_width, orishield_height,
+					    orishield_bits, teamWin[3]);
+}
+
+void
+load_generic_teams()
+{
+    /*
+       reserved letters: A G T
+    */
+    int     i;
+
+    /* independent is teaminfo[-1] */
+    teaminfo = 1 + (struct teaminfo_s *) malloc(sizeof(*teaminfo) * (number_of_teams + 1));
+
+    strcpy(teaminfo[-1].name, "Independant");
+    teaminfo[-1].letter = 'I';
+    strcpy(teaminfo[-1].shortname, "IND");
+
+    load_default_teamlogos();	/* loads the first 4 team logos */
+
+    for (i = 0; i < number_of_teams; i++) {
+	sprintf(teaminfo[i].name, "Team #%d", i);
+	teaminfo[i].letter = 'J' + i;	/* I, J through P */
+	sprintf(teaminfo[i].shortname, "T%02d", i);
+
+#if 0
+	/* we should draw something nifty here */
+	if (i >= 4)		/* the first 4 have been loaded already. */
+	    teaminfo[i].shield_logo = W_StoreBitmap(1, 1, &i, teamWin[i]);
+	/* XXX uh-oh if more than 4 teams */
+
+/* exactly.  If there are more than 4 teams the above will SEGV because
+   of the &i (which should be a char * bitmap array).
+*/
+#endif
+
+    }
+}
+
+void
+initialize_thingies()
+{
+    int     i;
+    int     n = (npthingies * nplayers + ngthingies);
+    thingies = (struct thingy *) malloc(sizeof(*thingies) * n);
+    for (i = 0; i < n; i++) {
+	thingies[i].t_shape = SHP_BLANK;
+	thingies[i].t_no = i;
+	thingies[i].t_owner = (i >= npthingies * nplayers) ? -1 : (i / npthingies);
+    }
+}
+
+void
+initialize_players()
+{
+    int     i;
+
+    players = (struct player *) malloc(sizeof(*players) * nplayers);
+
+    bzero(players, sizeof(struct player) * nplayers);
+
+    for (i = 0; i < nplayers; i++) {
+	players[i].p_status = PFREE;
+	players[i].p_cloakphase = 0;
+	players[i].p_no = i;
+	players[i].p_ntorp = 0;
+	players[i].p_ndrone = 0;/* TSH */
+	players[i].p_explode = 1;
+	players[i].p_stats.st_tticks = 1;
+	players[i].p_ship = shiptypes->ship;
+    }
+}
+
+void
+initialize_torps()
+{
+    int     i;
+
+    torps = (struct torp *) malloc(sizeof(*torps) * nplayers * ntorps);
+
+    for (i = 0; i < nplayers * ntorps; i++) {
+	torps[i].t_status = TFREE;
+	torps[i].t_no = i;
+	torps[i].t_owner = (i / ntorps);
+    }
+}
+
+void
+initialize_plasmas()
+{
+    int     i;
+
+    plasmatorps = (struct plasmatorp *) malloc(sizeof(*plasmatorps) * nplayers * nplasmas);
+
+    for (i = 0; i < nplayers * nplasmas; i++) {
+	plasmatorps[i].pt_status = PTFREE;
+	plasmatorps[i].pt_no = i;
+	plasmatorps[i].pt_owner = (i / nplasmas);
+    }
+}
+
+void
+initialize_phasers()
+{
+    int     i;
+
+    phasers = (struct phaser *) malloc(sizeof(*phasers) * nplayers * nphasers);
+
+    for (i = 0; i < nplayers * nphasers; i++) {
+	phasers[i].ph_status = PHFREE;
+	phasers[i].ph_fuse = 0;
+    }
+}
+
+void
+initialize_planets()
+{
+    int     i;
+
+    planets = (struct planet *) malloc(sizeof(*planets) * nplanets);
+
+    for (i = 0; i < nplanets; i++) {
+	struct planet *curr = &planets[i];
+	curr->pl_no = i;
+	curr->pl_flags = 0;
+	curr->pl_owner = 0;
+	curr->pl_x = curr->pl_y = -10000;
+	sprintf(curr->pl_name, "planet%d", i);
+	curr->pl_namelen = strlen(curr->pl_name);
+	curr->pl_armies = 0;
+	curr->pl_info = 0;
+	curr->pl_deadtime = 0;
+	curr->pl_couptime = 0;
+	curr->pl_timestamp = 0;
+
+	/* initialize planet redraw for moving planets */
+	pl_update[i].plu_update = -1;
+    }
+}
+
+void
+init_ranks()
+{
+    ranks2 = (struct rank2 *) malloc(sizeof(*ranks2) * nranks2);
+    ranks2[0].genocides = 0;
+    ranks2[0].di = 0;
+    ranks2[0].battle = 0.0;
+    ranks2[0].strategy = 0.0;
+    ranks2[0].specship = 0.0;
+    ranks2[0].name = strdup("Recruit");
+
+    ranks2[1].genocides = 1;
+    ranks2[1].di = 10;
+    ranks2[1].battle = 0.30;
+    ranks2[1].strategy = 0.3;
+    ranks2[1].specship = 0.0;
+    ranks2[1].name = strdup("Specialist");
+
+    ranks2[2].genocides = 2;
+    ranks2[2].di = 25;
+    ranks2[2].battle = 0.40;
+    ranks2[2].strategy = 0.6;
+    ranks2[2].specship = 0.0;
+    ranks2[2].name = strdup("Cadet");
+
+    ranks2[3].genocides = 3;
+    ranks2[3].di = 45;
+    ranks2[3].battle = 0.50;
+    ranks2[3].strategy = 0.9;
+    ranks2[3].specship = 0.0;
+    ranks2[3].name = strdup("Midshipman");
+
+    ranks2[4].genocides = 4;
+    ranks2[4].di = 70;
+    ranks2[4].battle = 0.70;
+    ranks2[4].strategy = 1.2;
+    ranks2[4].specship = 0.0;
+    ranks2[4].name = strdup("Ensn. J.G.");
+
+    ranks2[5].genocides = 5;
+    ranks2[5].di = 100;
+    ranks2[5].battle = 0.90;
+    ranks2[5].strategy = 1.5;
+    ranks2[5].specship = 0.0;
+    ranks2[5].name = strdup("Ensign");
+
+    ranks2[6].genocides = 6;
+    ranks2[6].di = 140;
+    ranks2[6].battle = 1.10;
+    ranks2[6].strategy = 2.0;
+    ranks2[6].specship = 0.0;
+    ranks2[6].name = strdup("Lt. J.G.");
+
+    ranks2[7].genocides = 8;
+    ranks2[7].di = 190;
+    ranks2[7].battle = 1.30;
+    ranks2[7].strategy = 2.5;
+    ranks2[7].specship = 0.0;
+    ranks2[7].name = strdup("Lieutenant");
+
+    ranks2[8].genocides = 10;
+    ranks2[8].di = 250;
+    ranks2[8].battle = 1.50;
+    ranks2[8].strategy = 3.0;
+    ranks2[8].specship = 0.5;
+    ranks2[8].name = strdup("Lt. Cmdr.");
+
+    ranks2[9].genocides = 15;
+    ranks2[9].di = 300;
+    ranks2[9].battle = 1.80;
+    ranks2[9].strategy = 3.5;
+    ranks2[9].specship = 0.7;
+    ranks2[9].name = strdup("Commander");
+
+    ranks2[10].genocides = 18;
+    ranks2[10].di = 350;
+    ranks2[10].battle = 2.00;
+    ranks2[10].strategy = 4.0;
+    ranks2[10].specship = 1.0;
+    ranks2[10].name = strdup("Captain");
+
+    ranks2[11].genocides = 25;
+    ranks2[11].di = 400;
+    ranks2[11].battle = 2.10;
+    ranks2[11].strategy = 4.3;
+    ranks2[11].specship = 2.5;
+    ranks2[11].name = strdup("Fleet Capt.");
+
+    ranks2[12].genocides = 50;
+    ranks2[12].di = 500;
+    ranks2[12].battle = 2.15;
+    ranks2[12].strategy = 4.8;
+    ranks2[12].specship = 3.0;
+    ranks2[12].name = strdup("Commodore");
+
+    ranks2[13].genocides = 75;
+    ranks2[13].di = 700;
+    ranks2[13].battle = 2.20;
+    ranks2[13].strategy = 5.3;
+    ranks2[13].specship = 3.3;
+    ranks2[13].name = strdup("Moff");
+
+    ranks2[14].genocides = 100;
+    ranks2[14].di = 900;
+    ranks2[14].battle = 2.25;
+    ranks2[14].strategy = 5.7;
+    ranks2[14].specship = 3.6;
+    ranks2[14].name = strdup("Grand Moff");
+
+    ranks2[15].genocides = 300;
+    ranks2[15].di = 1200;
+    ranks2[15].battle = 2.30;
+    ranks2[15].strategy = 6.0;
+    ranks2[15].specship = 3.8;
+    ranks2[15].name = strdup("Rear Adml.");
+
+    ranks2[16].genocides = 700;
+    ranks2[16].di = 1700;
+    ranks2[16].battle = 2.35;
+    ranks2[16].strategy = 6.1;
+    ranks2[16].specship = 4.0;
+    ranks2[16].name = strdup("Admiral");
+
+    ranks2[17].genocides = 1000;
+    ranks2[17].di = 2500;
+    ranks2[17].battle = 2.40;
+    ranks2[17].strategy = 6.2;
+    ranks2[17].specship = 4.2;
+    ranks2[17].name = strdup("Grand Adml.");
+}
+
+void
+init_royal()
+{
+    royal = (struct royalty *) malloc(sizeof(*royal) * nroyals);
+
+    royal[0].name = strdup("none");
+    royal[1].name = strdup("Wesley");
+    royal[2].name = strdup("Centurion");
+    royal[3].name = strdup("Praetor");
+    royal[4].name = strdup("Emperor");
+#if 0
+    royal[5].name = strdup("Wizard");
+    royal[6].name = strdup("Duke");
+    royal[7].name = strdup("Count");
+    royal[8].name = strdup("Baron");
+    royal[9].name = strdup("Knight");
+    royal[10].name = strdup("Dread");
+    royal[11].name = strdup("Lord of Destruction");
+    royal[12].name = strdup("BlitzMeister");
+    royal[13].name = strdup("Hitler");
+    royal[14].name = strdup("Terminator");
+    royal[15].name = strdup("Kamikaze");
+    royal[16].name = strdup("Speed Kamikaze");
+    royal[17].name = strdup("Carpet Bomber");
+    royal[18].name = strdup("NukeMeister");
+    royal[19].name = strdup("Terrorist");
+    royal[20].name = strdup("Democrat");
+    royal[21].name = strdup("Executioner");
+    royal[22].name = strdup("DooshMeister");
+    royal[23].name = strdup("Diplomat");
+    royal[24].name = strdup("speed Diplomat");
+    royal[25].name = strdup("Addict");
+#endif				/* 0 */
+}
+
+void
+reinit_ranks()
+{
+    int     i;
+    ranks2 = (struct rank2 *) malloc(sizeof(*ranks2) * nranks2);
+
+    for (i = 0; i < nranks2; i++) {
+	ranks2[i].name = strdup("blank");
+    }
+}
+
+void
+reinit_royal()
+{
+    int     i;
+    royal = (struct royalty *) malloc(sizeof(*royal) * nroyals);
+
+    for (i = 0; i < nroyals; i++) {
+	royal[i].name = strdup("blank");
+    }
+}
+
+
+void
+resize_players()
+{
+    int     me_no;
+
+    if (me)
+	me_no = me->p_no;
+    players = (struct player *) realloc(players, sizeof(*players) * nplayers);
+    if (me) {
+	me = &players[me_no];
+	myship = me->p_ship;
+    }
+}
+
+void
+free_teams()
+{
+    int     i;
+    for (i = 0; i < number_of_teams; i++) {
+	W_FreeBitmap(teaminfo[i].shield_logo);
+    }
+    /* we offsetted by 1 to make room for IND */
+    free(teaminfo - 1);
+    teaminfo = 0;
+}
+
+void
+free_torps()
+{
+    free(torps);
+    torps = 0;
+}
+
+void
+free_phasers()
+{
+    free(phasers);
+    phasers = 0;
+}
+
+void
+free_plasmas()
+{
+    free(plasmatorps);
+    plasmatorps = 0;
+}
+
+void
+free_thingies()
+{
+    free(thingies);
+    thingies = 0;
+}
+
+void
+free_ranks()
+{
+    int     i;
+    for (i = 0; i < nranks2; i++)
+	if (ranks2[i].name)
+	    free(ranks2[i].name);
+    free(ranks2);
+    ranks2 = 0;
+}
+
+void
+free_royal()
+{
+    int     i;
+    for (i = 0; i < nroyals; i++)
+	if (royal[i].name)
+	    free(royal[i].name);
+
+    free(royal);
+    royal = 0;
+}
+
+/*
+ */
+
+void
+build_default_configuration()
+{
+    load_default_teams();
+    /* can't load logos until we have some windows */
+
+    init_shiptypes();
+    initialize_players();
+    initialize_torps();
+    initialize_thingies();
+    initialize_plasmas();
+    initialize_planets();
+    initialize_phasers();
+
+
+    init_ranks();
+    init_royal();
+}
+
+/*
+ */
+
+
+int
+compute_gameparam_size(buf)
+    char   *buf;
+{
+    struct gameparam_spacket *pkt = (struct gameparam_spacket *) buf;
+
+    if (*buf != SP_GPARAM)
+	return -1;
+
+    switch (pkt->subtype) {
+    case 0:
+	return sizeof(struct gp_sizes_spacket);
+    case 1:
+	return sizeof(struct gp_team_spacket);
+    case 2:
+	return sizeof(struct gp_teamlogo_spacket);
+    case 3:
+	return sizeof(struct gp_shipshape_spacket);
+    case 4:
+	return sizeof(struct gp_shipbitmap_spacket);
+    case 5:
+	return sizeof(struct gp_rank_spacket);
+    case 6:
+	return sizeof(struct gp_royal_spacket);
+    case 7:
+	return sizeof(struct gp_teamplanet_spacket);
+    default:
+	return -1;
+    }
+}
+
+void
+handleGPsizes(pkt)
+    struct gp_sizes_spacket *pkt;
+{
+    free_ranks();
+    free_royal();
+
+    free_teams();
+    free_torps();
+    free_phasers();
+    free_plasmas();
+    free_thingies();
+
+    free_shipshapes();
+
+    nplayers = pkt->nplayers;
+    number_of_teams = pkt->nteams;
+    /* shiptypes */
+    nranks2 = pkt->nranks;
+    nroyals = pkt->nroyal;
+    nphasers = pkt->nphasers;
+    ntorps = pkt->ntorps;
+    nplasmas = pkt->nplasmas;
+    npthingies = pkt->nthingies;
+    ngthingies = pkt->gthingies;
+
+    /* gwidth */
+    /* flags */
+
+    load_generic_teams();
+
+    reinit_ranks();
+    reinit_royal();
+
+    resize_players();
+    initialize_torps();
+    initialize_phasers();
+    initialize_plasmas();
+    initialize_thingies();
+
+    slurp_ship_bitmaps();
+}
+
+void
+handleGPteam(pkt)
+    struct gp_team_spacket *pkt;
+{
+    struct teaminfo_s *currteam;
+
+    if ((int) pkt->index >= number_of_teams) {
+	fprintf(stderr, "Team #%d %s is out of range (0..%d)\n", pkt->index,
+		pkt->teamname, number_of_teams);
+	return;
+    }
+    currteam = &teaminfo[pkt->index];
+
+    currteam->letter = pkt->letter;
+
+    strncpy(currteam->shortname, pkt->shortname, 3);
+    currteam->shortname[3] = 0;
+
+    strncpy(currteam->name, pkt->teamname, sizeof(currteam->name) - 1);
+    currteam->name[sizeof(currteam->name) - 1] = 0;;
+}
+
+void
+handleGPteamlogo(pkt)
+    struct gp_teamlogo_spacket *pkt;
+{
+    static char buf[13 * 99];	/* 99x99 */
+    static int curr_height = 0;
+    static int lwidth, lheight;
+    static int teamindex;
+    int     pwidth;
+
+    if ((unsigned) pkt->teamindex >= number_of_teams) {
+	fprintf(stderr, "Team #%d is out of range (0..%d)\n", pkt->teamindex,
+		number_of_teams);
+	return;
+    }
+    if (pkt->y != curr_height) {
+	fprintf(stderr, "Bad gp_teamlogo packet sequence y(%d) != curr_height(%d)\n",
+		pkt->y, curr_height);
+	curr_height = 0;
+	return;
+    }
+    if (curr_height) {
+	if (lwidth != pkt->logowidth || lheight != pkt->logoheight ||
+	    teamindex != pkt->teamindex) {
+	    fprintf(stderr, "gp_teamlogo packet sequence error, %d!=%d || %d!=%d || %d!=%d\n",
+		    lwidth, pkt->logowidth, lheight, pkt->logoheight,
+		    teamindex, pkt->teamindex);
+	    curr_height = 0;
+	    return;
+	}
+    } else {
+	teamindex = pkt->teamindex;
+	lwidth = pkt->logowidth;
+	lheight = pkt->logoheight;
+	if (lwidth > 99 || lheight > 99) {
+	    fprintf(stderr, "logo too big (%dx%d), rejecting\n", lwidth, lheight);
+	    curr_height = 0;
+	    return;
+	}
+    }
+    pwidth = (lwidth - 1) / 8 + 1;
+    memcpy(buf + pwidth * curr_height, pkt->data, pwidth * pkt->thisheight);
+    curr_height += pkt->thisheight;
+
+    if (curr_height >= lheight) {
+	W_FreeBitmap(teaminfo[teamindex].shield_logo);
+	teaminfo[teamindex].shield_logo = W_StoreBitmap(lwidth, lheight, buf,
+							teamWin[teamindex]);
+	curr_height = 0;
+    }
+}
+
+void
+handleGPshipshape(pkt)
+    struct gp_shipshape_spacket *pkt;
+{
+    if (pkt->race < -1 || pkt->race >= number_of_teams) {
+	fprintf(stderr, "race #%d out of range (-1..%d)\n", pkt->race,
+		number_of_teams - 1);
+	return;
+    }
+    if ( /* pkt->shipno<0 || */ (int) pkt->shipno >= nshiptypes) {
+	fprintf(stderr, "ship class #%d out of range (0..%d)\n", pkt->shipno,
+		nshiptypes - 1);
+	return;
+    }
+    replace_shipshape(pkt->race, pkt->shipno, pkt->nviews,
+		      pkt->width, pkt->height);
+}
+
+void
+handleGPshipbitmap(pkt)
+    struct gp_shipbitmap_spacket *pkt;
+{
+    if (pkt->race < -1 || pkt->race >= number_of_teams) {
+	fprintf(stderr, "race #%d out of range (-1..%d)\n", pkt->race,
+		number_of_teams - 1);
+	return;
+    }
+    if ( /* pkt->shipno<0 || */ (int) pkt->shipno >= nshiptypes) {
+	fprintf(stderr, "ship class #%d out of range (0..%d)\n", pkt->shipno,
+		nshiptypes - 1);
+	return;
+    }
+    replace_ship_bitmap(pkt->race, pkt->shipno, pkt->thisview, pkt->bitmapdata);
+}
+
+void
+handleGPrank(pkt)
+    struct gp_rank_spacket *pkt;
+{
+    struct rank2 *curr;
+    if (pkt->rankn >= nranks2) {
+	fprintf(stderr, "rank #%d %s out of range (0..%d)\n", pkt->rankn,
+		pkt->name, nranks2 - 1);
+	return;
+    }
+    curr = &ranks2[pkt->rankn];
+    free(curr->name);
+
+    curr->genocides = htonl(pkt->genocides);
+    curr->di = htonl(pkt->milliDI) / 1000.0;
+    curr->battle = htonl(pkt->millibattle) / 1000.0;
+    curr->strategy = htonl(pkt->millistrat) / 1000.0;
+    curr->specship = htonl(pkt->millispec) / 1000.0;
+    curr->name = strdup(pkt->name);
+}
+
+void
+handleGProyal(pkt)
+    struct gp_royal_spacket *pkt;
+{
+    if ((int) pkt->rankn >= nroyals) {
+	fprintf(stderr, "Royalty #%d %s out of range (0..%d)\n", pkt->rankn,
+		pkt->name, nroyals - 1);
+	return;
+    }
+    free(royal[pkt->rankn].name);
+    royal[pkt->rankn].name = strdup(pkt->name);
+}
+
+static unsigned char mplanet_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x40,
+    0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0x02, 0x20,
+0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+static unsigned char planet_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00,
+    0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+void
+handleGPteamplanet(pkt)
+    struct gp_teamplanet_spacket *pkt;
+{
+    {
+#define	TACTICALSIZE	sizeof(pkt->tactical)
+	unsigned char tactical[TACTICALSIZE];
+	int     i;
+	int     race = pkt->teamn;
+
+	if (race < -1 || race >= number_of_teams) {
+	    fprintf(stderr, "race #%d out of range (-1..%d)\n", race,
+		    number_of_teams - 1);
+	    return;
+	}
+	for (i = 0; i < TACTICALSIZE; i++) {
+	    tactical[i] = (pkt->tactical[i] & pkt->tacticalM[i]) |
+		(planet_bits[i] & ~pkt->tacticalM[i]);
+	}
+
+	W_FreeBitmap(bplanets[race + 1]);
+	bplanets[race + 1] = W_StoreBitmap(30, 30, tactical, w);
+
+#undef TACTICALSIZE
+    }
+
+    {
+#define	GALACTICSIZE	sizeof(pkt->galactic)
+	unsigned char galactic[GALACTICSIZE];
+	int     i;
+	int     race = pkt->teamn;
+
+	if (race < -1 || race >= number_of_teams) {
+	    fprintf(stderr, "race #%d out of range (-1..%d)\n", race,
+		    number_of_teams - 1);
+	    return;
+	}
+	for (i = 0; i < GALACTICSIZE; i++) {
+	    galactic[i] = (pkt->galactic[i] & pkt->galacticM[i]) |
+		(mplanet_bits[i] & ~pkt->galacticM[i]);
+	}
+
+	W_FreeBitmap(mbplanets[race + 1]);
+	mbplanets[race + 1] = W_StoreBitmap(16, 16, galactic, mapw);
+
+#undef GALACTICSIZE
+    }
+}
+
+void
+handleGameparams(pkt)
+    struct gameparam_spacket *pkt;
+{
+    switch (pkt->subtype) {
+    case 0:
+	handleGPsizes((struct gp_sizes_spacket *) pkt);
+	break;
+    case 1:
+	handleGPteam((struct gp_team_spacket *) pkt);
+	break;
+    case 2:
+	handleGPteamlogo((struct gp_teamlogo_spacket *) pkt);
+	break;
+    case 3:
+	handleGPshipshape((struct gp_shipshape_spacket *) pkt);
+	break;
+    case 4:
+	handleGPshipbitmap((struct gp_shipbitmap_spacket *) pkt);
+	break;
+    case 5:
+	handleGPrank((struct gp_rank_spacket *) pkt);
+	break;
+    case 6:
+	handleGProyal((struct gp_royal_spacket *) pkt);
+	break;
+    case 7:
+	handleGPteamplanet((struct gp_teamplanet_spacket *) pkt);
+	break;
+    default:
+	fprintf(stderr, "Gameparams packet subtype %d not yet implemented\n",
+		pkt->subtype);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gameconf.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,29 @@
+/* $Id: gameconf.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+   this header declares declares variables for much information that
+   used to be constant.
+   */
+
+#ifndef gameconf_h_
+#define gameconf_h_
+
+#include "Wlib.h"
+#include "proto.h"
+
+extern struct teaminfo_s {
+    char    name[32];		/* this is not meant to limit the length of
+				   team names */
+    W_Icon  shield_logo;	/* logo that appears in the team choice
+				   window */
+    char    letter;		/* 1-letter abbreviation */
+    char    shortname[4];	/* 3-letter abbreviation */
+}      *teaminfo;
+
+extern int number_of_teams;
+
+struct gameparam_spacket;
+
+void handleGameparams P((struct gameparam_spacket *));
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getname.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,429 @@
+/* $Id: getname.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * getname.c
+ *
+ * Kevin P. Smith 09/28/88
+ *
+ */
+#include "copyright2.h"
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <errno.h>
+#include <pwd.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#ifndef hpux
+#include <sys/time.h>
+#endif
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+static char tempname[16];
+static char password1[16];
+static char password2[16];
+static int state, autolog;
+static char username[32] = "****";
+#define ST_GETNAME 0
+#define ST_GETPASS 1
+#define ST_MAKEPASS1 2
+#define ST_MAKEPASS2 3
+#define ST_DONE 4
+
+/* Prototypes */
+static void adjustString P((int ch, char *str, char *defname));
+static void checkpassword P((void));
+static void displayStartup P((char *defname));
+static void loaddude P((void));
+static void makeNewGuy P((void));
+static void loginproced P((int ch, char *defname));
+
+void
+noautologin()
+{
+    char   *tempstr;
+
+    autolog = 0;
+    *defpasswd = *password1 = *password2 = '\0';
+    tempstr = "Automatic login failed";
+    W_WriteText(w, 100, 100, textColor, tempstr, strlen(tempstr),
+		W_BoldFont);
+}
+
+void
+getname(defname, defpasswd)
+    char   *defname, *defpasswd;
+/* Let person identify themselves from w */
+{
+    W_Event event;
+    register ch = 0;
+    int     secondsLeft = 99, laststate;
+    char    tempstr[40];
+    long    lasttime;
+    register int j;
+
+#ifdef RECORDER
+    if (playback)
+	return;
+#endif
+    autolog = (*defpasswd && *defname) ? 1 : 0;
+
+    {
+	struct passwd *passwd;
+
+	passwd = getpwuid(getuid());
+	if (passwd)		/* believe it or not, getpwuid failed on me -
+				   RF */
+	    strcpy(username, passwd->pw_name);
+    }
+
+    bzero(mystats, sizeof(struct stats));
+    mystats->st_tticks = 1;
+    mystats->st_flags =
+	(ST_NOBITMAPS * (!sendmotdbitmaps) +
+	 ST_KEEPPEACE * keeppeace +
+	 0);
+    lasttime = time(NULL);
+
+    if (ghoststart)
+	return;
+
+    tempname[0] = '\0';
+    password1[0] = '\0';
+    password2[0] = '\0';
+    laststate = state = ST_GETNAME;
+    displayStartup(defname);
+    for (;;) {
+	if (isServerDead()) {
+	    printf("Ack!  We've been ghostbusted!\n");
+#ifdef AUTOKEY
+	    if (autoKey)
+		W_AutoRepeatOn();
+#endif
+	    EXIT(0);
+	}
+	if (lasttime != time(NULL)) {
+	    lasttime++;
+	    secondsLeft--;
+	    if (!autolog) {
+		sprintf(tempstr, "Seconds to go: %d ", secondsLeft);
+		W_WriteText(w, 150, 400, textColor, tempstr, strlen(tempstr),
+			    W_BoldFont);
+	    }
+	    if (secondsLeft == 0) {
+		me->p_status = PFREE;
+		printf("Auto-Quit\n");
+#ifdef AUTOKEY
+		if (autoKey)
+		    W_AutoRepeatOn();
+#endif
+		EXIT(0);
+	    }
+	}
+	if (state == ST_DONE) {
+	    W_ClearWindow(w);
+	    return;
+	}
+	readFromServer();	/* Just in case it wants to say something */
+
+	if (autolog) {
+	    switch (state) {
+	    case ST_GETNAME:
+		tempname[0] = '\0';
+		ch = 13;
+		j = 0;
+		break;
+
+	    case ST_GETPASS:
+	    case ST_MAKEPASS1:
+	    case ST_MAKEPASS2:
+		ch = defpasswd[j++];
+		if (ch == '\0') {
+		    j = 0;
+		    ch = 13;
+		}
+		break;
+
+	    default:
+		break;
+	    }
+
+	    loginproced(ch, defname);
+
+	}
+	laststate = state;
+
+	if (!W_EventsPending())
+	    continue;
+	W_NextEvent(&event);
+	if (event.Window != w)
+	    continue;
+	switch ((int) event.type) {
+	case W_EV_EXPOSE:
+	    displayStartup(defname);
+	    break;
+	case W_EV_KEY:
+	    ch = event.key;
+	    if (!autolog)
+		loginproced(ch, defname);
+	}
+    }
+}
+
+
+static
+void
+loginproced(ch, defname)
+    int     ch;
+    char   *defname;
+{
+    if (ch > 255)
+	ch -= 256;		/* was alt key, ignore it */
+    if (ch == 10)
+	ch = 13;
+    if ((ch == ('d' + 128) || ch == ('D' + 128)) && state == ST_GETNAME && *tempname == '\0') {
+#ifdef AUTOKEY
+	if (autoKey)
+	    W_AutoRepeatOn();
+#endif
+	EXIT(0);
+    }
+    if ((ch < 32 || ch > 127) && ch != 21 && ch != 13 && ch != 8)
+	return;
+    switch (state) {
+    case ST_GETNAME:
+	if (ch == 13) {
+	    if (*tempname == '\0') {
+		strcpy(tempname, defname);
+	    }
+	    loaddude();
+	    displayStartup(defname);
+	} else {
+	    adjustString(ch, tempname, defname);
+	}
+	break;
+    case ST_GETPASS:
+	if (ch == 13) {
+	    checkpassword();
+	    displayStartup(defname);
+	} else {
+	    adjustString(ch, password1, defname);
+	}
+	break;
+    case ST_MAKEPASS1:
+	if (ch == 13) {
+	    state = ST_MAKEPASS2;
+	    displayStartup(defname);
+	} else {
+	    adjustString(ch, password1, defname);
+	}
+	break;
+    case ST_MAKEPASS2:
+	if (ch == 13) {
+	    makeNewGuy();
+	    displayStartup(defname);
+	} else {
+	    adjustString(ch, password2, defname);
+	}
+	break;
+    }
+}
+
+static void
+loaddude()
+/* Query dude.
+ */
+{
+    if (strcmp(tempname, "Guest") == 0 || strcmp(tempname, "guest") == 0) {
+	loginAccept = -1;
+	sendLoginReq(tempname, "", username, 0);
+	state = ST_DONE;
+	me->p_pos = -1;
+	me->p_stats.st_tticks = 1;	/* prevent overflow */
+	strcpy(me->p_name, tempname);
+	while (loginAccept == -1) {
+	    socketPause(1, 0);
+	    readFromServer();
+	    if (isServerDead()) {
+		printf("Server is dead!\n");
+#ifdef AUTOKEY
+		if (autoKey)
+		    W_AutoRepeatOn();
+#endif
+
+		EXIT(0);
+	    }
+	}
+	if (loginAccept == 0) {
+	    printf("Hmmm... The SOB server won't let me log in as guest!\n");
+#ifdef AUTOKEY
+	    if (autoKey)
+		W_AutoRepeatOn();
+#endif
+
+	    EXIT(0);
+	}
+	return;
+    }
+    /* Ask about the user */
+    loginAccept = -1;
+    sendLoginReq(tempname, "", username, 1);
+    while (loginAccept == -1) {
+	socketPause(1, 0);
+	readFromServer();
+	if (isServerDead()) {
+	    printf("Server is dead!\n");
+#ifdef AUTOKEY
+	    if (autoKey)
+		W_AutoRepeatOn();
+#endif
+
+	    EXIT(0);
+	}
+    }
+    *password1 = *password2 = 0;
+    if (loginAccept == 0) {
+	state = ST_MAKEPASS1;
+    } else {
+	state = ST_GETPASS;
+    }
+}
+
+static void
+checkpassword()
+/* Check dude's password.
+ * If he is ok, move to state ST_DONE.
+ */
+{
+    char   *s;
+
+    sendLoginReq(tempname, password1, username, 0);
+    loginAccept = -1;
+    while (loginAccept == -1) {
+	socketPause(1, 0);
+	readFromServer();
+	if (isServerDead()) {
+	    printf("Server is dead!\n");
+#ifdef AUTOKEY
+	    if (autoKey)
+		W_AutoRepeatOn();
+#endif
+
+	    EXIT(0);
+	}
+    }
+    if (loginAccept == 0) {
+	if (!autolog) {
+	    s = "Bad password!";
+	    W_WriteText(w, 100, 100, textColor, s, strlen(s), W_BoldFont);
+	    (void) W_EventsPending();
+	    sleep(3);
+	    W_ClearWindow(w);
+	} else
+	    noautologin();
+	*tempname = 0;
+	state = ST_GETNAME;
+	return;
+    }
+    strcpy(me->p_name, tempname);
+    sendmotdbitmaps = !((me->p_stats.st_flags / ST_NOBITMAPS) & 1);
+    keeppeace = (me->p_stats.st_flags / ST_KEEPPEACE) & 1;
+    state = ST_DONE;
+}
+
+static void
+makeNewGuy()
+/* Make the dude with name tempname and password password1.
+ * Move to state ST_DONE.
+ */
+{
+    char   *s;
+
+    if (strcmp(password1, password2) != 0) {
+	if (!autolog) {
+	    s = "Passwords do not match";
+	    W_WriteText(w, 100, 120, textColor, s, strlen(s), W_BoldFont);
+	    (void) W_EventsPending();
+	    sleep(3);
+	    W_ClearWindow(w);
+	} else
+	    noautologin();
+	*tempname = 0;
+	state = ST_GETNAME;
+	return;
+    }
+    /* same routine! */
+    checkpassword();
+}
+
+static void
+adjustString(ch, str, defname)
+    char    ch, *str;
+    char   *defname;
+{
+    if (ch == 21) {
+	*str = '\0';
+	if (state == ST_GETNAME)
+	    displayStartup(defname);
+    } else if (ch == 8 || ch == '\177') {
+	if ((int) strlen(str) > 0) {
+	    str[strlen(str) - 1] = '\0';
+	    if (state == ST_GETNAME)
+		displayStartup(defname);
+	}
+    } else {
+	if (strlen(str) == 15)
+	    return;
+	str[strlen(str) + 1] = '\0';
+	str[strlen(str)] = ch;
+	if (state == ST_GETNAME)
+	    displayStartup(defname);
+    }
+}
+
+static void
+displayStartup(defname)
+    char   *defname;
+/* Draws entry screen based upon state. */
+{
+    char    s[100];
+    char   *t;
+
+    if (state == ST_DONE || autolog)
+	return;
+    t = "Enter your name.  Use the name 'guest' to remain anonymous.";
+    W_WriteText(w, 100, 30, textColor, t, strlen(t), W_BoldFont);
+    t = "Type ^D (Ctrl - D) to quit.";
+    W_WriteText(w, 100, 40, textColor, t, strlen(t), W_BoldFont);
+    sprintf(s, "Your name (default = %s): %s               ", defname, tempname);
+    W_WriteText(w, 100, 50, textColor, s, strlen(s), W_BoldFont);
+    if (state == ST_GETPASS) {
+	t = "Enter password: ";
+	W_WriteText(w, 100, 60, textColor, t, strlen(t), W_BoldFont);
+    }
+    if (state > ST_GETPASS) {
+	t = "You need to make a password.";
+	W_WriteText(w, 100, 70, textColor, t, strlen(t), W_BoldFont);
+	t = "So think of a password you can remember, and enter it.";
+	W_WriteText(w, 100, 80, textColor, t, strlen(t), W_BoldFont);
+	t = "What is your password? :";
+	W_WriteText(w, 100, 90, textColor, t, strlen(t), W_BoldFont);
+    }
+    if (state == ST_MAKEPASS2) {
+	t = "Enter it again to make sure you typed it right.";
+	W_WriteText(w, 100, 100, textColor, t, strlen(t), W_BoldFont);
+	t = "Your password? :";
+	W_WriteText(w, 100, 110, textColor, t, strlen(t), W_BoldFont);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/getship.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,395 @@
+/* $Id: getship.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * getship.c for client of socket protocol.
+ *
+ * This file has been mangled so it only sets the ship characteristics needed.
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <sys/types.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+/* Prototypes */
+static void getship_default P((struct ship * shipp, int s_type));
+
+void
+init_shiptypes()
+{
+    int     i;
+    struct shiplist *temp;
+
+    /* start at -1, the default shiptype */
+    for (i = -1; i < nshiptypes; i++) {
+	temp = (struct shiplist *) malloc(sizeof(struct shiplist));
+	temp->ship = (struct ship *) malloc(sizeof(struct ship));
+	getship_default(temp->ship, i);
+	temp->next = shiptypes;
+	if (temp->next)
+	    temp->next->prev = temp;
+	temp->prev = NULL;
+	shiptypes = temp;
+    }
+}
+
+void
+init_galaxy_class()
+{
+    /*
+       hack to allow galaxy class ships.  By the time the client knows it's
+       connected to a paradise server, the defaults must already have been
+       run. [BDyess]
+    */
+    struct shiplist *temp;
+
+    for (temp = shiptypes; temp->ship->s_type != GALAXY; temp = temp->next)
+	 /* null body */ ;
+    getship_default(temp->ship, GALAXY);
+
+    /* slurp_ship_bitmaps(); */ /* don't destroy downloaded bitmaps */
+
+    return;
+}
+
+#if 0
+void
+init_puck()
+{
+    /* ditto above init_galaxy_class(), but this time for hockey and puck.
+       [BDyess] */
+    struct shiplist *temp;
+
+    temp = shiptypes;
+    while(temp->next) temp = temp->next;
+    temp->next = (struct shiplist*)malloc(sizeof(struct shiplist));
+    temp = temp->next;
+    temp->ship = (struct ship*)malloc(sizeof(struct ship));
+    getship_default(temp->ship, PUCK);
+    temp->next = NULL;
+
+    slurp_ship_bitmaps();
+
+    return;
+}
+#endif /*0*/
+  
+/* now returns a pointer to where the ship data is located.  This way
+   if the data is later changed by the server everybody gets updated.
+   Plus as a bonus it's more efficient :)   [Bill Dyess] */
+struct ship *
+getship(s_type)
+    int     s_type;
+{
+    struct shiplist *temp, *new;
+
+    temp = shiptypes;
+    while (temp) {
+	if (temp->ship->s_type == s_type) {
+	    /* bcopy(temp->ship, shipp, sizeof(struct ship)); */
+	    return temp->ship;
+	}
+	temp = temp->next;
+    }
+    /*
+       ok, that shiptype is unheard of.  Assume a new shiptype, and get the
+       values for CA.  Also add the ship to the list so if it gets updated by
+       the server later everyone stays happy.  [Bill Dyess]
+    */
+    printf("Error:  getship of unknown ship type %d, using CA defaults\n", s_type);
+    temp = shiptypes;
+    while (temp) {
+	if (temp->ship->s_type == DEFAULT) {
+	    printf("Adding ship type %d\n", s_type);
+	    /* bcopy(temp->ship, shipp, sizeof(struct ship)); */
+	    /* now add the new ship to the list */
+	    new = (struct shiplist *) malloc(sizeof(struct shiplist));
+	    new->ship = (struct ship *) malloc(sizeof(struct ship));
+	    new->next = shiptypes;
+	    new->prev = NULL;
+	    if (shiptypes)
+		shiptypes->prev = new;
+	    shiptypes = new;
+	    bcopy(temp->ship, new->ship, sizeof(struct ship));
+	    new->ship->s_type = s_type;
+	    return new->ship;
+	}
+	temp = temp->next;
+    }
+    return temp->ship;
+
+}
+
+/* fill in ship characteristics */
+
+static void
+getship_default(shipp, s_type)
+    struct ship *shipp;
+    int     s_type;
+{
+    switch (s_type) {
+    case SCOUT:
+    case PUCK:
+	shipp->s_torpspeed = 16;
+	shipp->s_phaserrange = 4500;
+	shipp->s_maxspeed = 12;
+	shipp->s_maxfuel = 5000;
+	shipp->s_maxarmies = 2;
+	shipp->s_maxshield = 75;
+	shipp->s_maxdamage = 75;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1000;
+	if(s_type == PUCK) {
+	  shipp->s_type = PUCK;
+	  shipp->s_letter = 'k';
+	  shipp->s_desig[0] = 'P';
+	  shipp->s_desig[1] = 'U';
+	  shipp->s_bitmap = PUCK;
+	} else {
+	  shipp->s_type = SCOUT;
+	  shipp->s_letter = 's';
+	  shipp->s_desig[0] = 'S';
+	  shipp->s_desig[1] = 'C';
+	  shipp->s_bitmap = SCOUT;
+	}
+	break;
+    case DESTROYER:
+	shipp->s_type = DESTROYER;
+	shipp->s_torpspeed = 14;
+	shipp->s_phaserrange = 5100;
+	shipp->s_maxspeed = 10;
+	shipp->s_maxfuel = 7000;
+	shipp->s_maxarmies = 5;
+	shipp->s_maxshield = 85;
+	shipp->s_maxdamage = 85;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1000;
+	shipp->s_letter = 'd';
+	shipp->s_desig[0] = 'D';
+	shipp->s_desig[1] = 'D';
+	shipp->s_bitmap = DESTROYER;
+	break;
+    default:
+    case DEFAULT:
+    case CRUISER:
+	shipp->s_type = s_type;
+	shipp->s_torpspeed = 12;
+	shipp->s_phaserrange = 6000;
+	shipp->s_maxspeed = 9;
+	shipp->s_maxfuel = 10000;
+	shipp->s_maxarmies = 10;
+	shipp->s_maxshield = 100;
+	shipp->s_maxdamage = 100;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1000;
+	shipp->s_letter = 'c';
+	shipp->s_desig[0] = 'C';
+	shipp->s_desig[1] = 'A';
+	shipp->s_bitmap = CRUISER;
+	break;
+    case BATTLESHIP:
+	shipp->s_type = BATTLESHIP;
+	shipp->s_torpspeed = 12;
+	shipp->s_phaserrange = 6300;
+	shipp->s_maxspeed = 8;
+	shipp->s_maxfuel = 14000;
+	shipp->s_maxarmies = 6;
+	shipp->s_maxshield = 130;
+	shipp->s_maxdamage = 130;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1000;
+	shipp->s_letter = 'b';
+	shipp->s_desig[0] = 'B';
+	shipp->s_desig[1] = 'B';
+	shipp->s_bitmap = BATTLESHIP;
+	break;
+    case ASSAULT:
+	shipp->s_type = ASSAULT;
+	shipp->s_torpspeed = 16;
+	shipp->s_phaserrange = 4800;
+	shipp->s_maxspeed = 8;
+	shipp->s_maxfuel = 6000;
+	shipp->s_maxarmies = 20;
+	shipp->s_maxshield = 80;
+	shipp->s_maxdamage = 200;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1200;
+	shipp->s_letter = 'a';
+	shipp->s_desig[0] = 'A';
+	shipp->s_desig[1] = 'S';
+	shipp->s_bitmap = ASSAULT;
+	break;
+    case STARBASE:
+	shipp->s_type = STARBASE;
+	shipp->s_torpspeed = 14;
+	shipp->s_phaserrange = 7200;
+	shipp->s_maxspeed = 2;
+	shipp->s_maxfuel = 60000;
+	shipp->s_maxarmies = 25;
+	shipp->s_maxshield = 500;
+	shipp->s_maxdamage = 600;
+	shipp->s_maxwpntemp = 1300;
+	shipp->s_maxegntemp = 1000;
+	shipp->s_letter = 'o';
+	shipp->s_desig[0] = 'S';
+	shipp->s_desig[1] = 'B';
+	shipp->s_bitmap = STARBASE;
+	break;
+    case ATT:			/* or GALAXY */
+	if (paradise) {
+	    shipp->s_type = ATT;
+	    shipp->s_torpspeed = 20;
+	    shipp->s_phaserrange = 6000;
+	    shipp->s_maxspeed = 90;
+	    shipp->s_maxfuel = 60000;
+	    shipp->s_maxarmies = 1000;
+	    shipp->s_maxshield = 30000;
+	    shipp->s_maxdamage = 30000;
+	    shipp->s_maxwpntemp = 10000;
+	    shipp->s_maxegntemp = 10000;
+	    shipp->s_letter = 'X';
+	    shipp->s_desig[0] = 'A';
+	    shipp->s_desig[1] = 'T';
+	    shipp->s_bitmap = ATT;
+	} else {
+	    shipp->s_type = GALAXY;
+	    shipp->s_torpspeed = 13;
+	    shipp->s_phaserrange = 6000;	/* this is a guess */
+	    shipp->s_maxspeed = 9;
+	    shipp->s_maxfuel = 12000;
+	    shipp->s_maxarmies = 12;
+	    shipp->s_maxshield = 140;
+	    shipp->s_maxdamage = 120;
+	    shipp->s_maxwpntemp = 1000;
+	    shipp->s_maxegntemp = 1000;
+	    shipp->s_letter = 'g';
+	    shipp->s_desig[0] = 'G';
+	    shipp->s_desig[1] = 'A';
+	    shipp->s_bitmap = FLAGSHIP;
+	}
+	break;
+    case FLAGSHIP:
+	shipp->s_type = FLAGSHIP;
+	shipp->s_torpspeed = 14;
+	shipp->s_phaserrange = 5750;
+	shipp->s_maxspeed = 9;
+	shipp->s_maxfuel = 14500;
+	shipp->s_maxarmies = 8;
+	shipp->s_maxshield = 115;
+	shipp->s_maxdamage = 115;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1500;
+	shipp->s_letter = 'f';
+	shipp->s_desig[0] = 'F';
+	shipp->s_desig[1] = 'L';
+	shipp->s_bitmap = FLAGSHIP;
+	break;
+    case JUMPSHIP:
+	shipp->s_type = JUMPSHIP;
+	shipp->s_torpspeed = 18;
+	shipp->s_phaserrange = 3000;
+	shipp->s_maxspeed = 20;
+	shipp->s_maxfuel = 50000;
+	shipp->s_maxarmies = 0;
+	shipp->s_maxshield = 5;
+	shipp->s_maxdamage = 60;
+	shipp->s_maxwpntemp = 1300;
+	shipp->s_maxegntemp = 5000;
+	shipp->s_letter = 'j';
+	shipp->s_desig[0] = 'J';
+	shipp->s_desig[1] = 'S';
+	shipp->s_bitmap = JUMPSHIP;
+	break;
+    case WARBASE:
+	shipp->s_type = WARBASE;
+	shipp->s_torpspeed = 15;
+	shipp->s_phaserrange = 6000;
+	shipp->s_maxspeed = 3;
+	shipp->s_maxfuel = 50000;
+	shipp->s_maxarmies = 0;
+	shipp->s_maxshield = 150;
+	shipp->s_maxdamage = 500;
+	shipp->s_maxwpntemp = 1500;
+	shipp->s_maxegntemp = 1000;
+	shipp->s_letter = 'w';
+	shipp->s_desig[0] = 'W';
+	shipp->s_desig[1] = 'B';
+	shipp->s_bitmap = WARBASE;
+	break;
+
+    case LIGHTCRUISER:
+	shipp->s_type = LIGHTCRUISER;
+	shipp->s_torpspeed = 13;
+	shipp->s_phaserrange = 6000;
+	shipp->s_maxspeed = 10;
+	shipp->s_maxfuel = 9000;
+	shipp->s_maxarmies = 4;
+	shipp->s_maxshield = 95;
+	shipp->s_maxdamage = 90;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1500;
+	shipp->s_letter = 'l';
+	shipp->s_desig[0] = 'C';
+	shipp->s_desig[1] = 'L';
+	shipp->s_bitmap = LIGHTCRUISER;
+	break;
+
+    case CARRIER:
+	shipp->s_type = CARRIER;
+	shipp->s_torpspeed = 10;
+	shipp->s_phaserrange = 4500;
+	shipp->s_maxspeed = 10;
+	shipp->s_maxfuel = 15000;
+	shipp->s_maxarmies = 3;
+	shipp->s_maxshield = 100;
+	shipp->s_maxdamage = 150;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1000;
+	shipp->s_letter = 'v';
+	shipp->s_desig[0] = 'C';
+	shipp->s_desig[1] = 'V';
+	shipp->s_bitmap = CARRIER;
+	break;
+    case UTILITY:
+	shipp->s_type = UTILITY;
+	shipp->s_torpspeed = 16;
+	shipp->s_phaserrange = 5000;
+	shipp->s_maxspeed = 7;
+	shipp->s_maxfuel = 12000;
+	shipp->s_maxarmies = 12;
+	shipp->s_maxshield = 110;
+	shipp->s_maxdamage = 180;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1800;
+	shipp->s_letter = 'u';
+	shipp->s_desig[0] = 'U';
+	shipp->s_desig[1] = 'T';
+	shipp->s_bitmap = UTILITY;
+	break;
+
+    case PATROL:
+	shipp->s_type = PATROL;
+	shipp->s_torpspeed = 15;
+	shipp->s_phaserrange = 5000;
+	shipp->s_maxspeed = 11;
+	shipp->s_maxfuel = 4000;
+	shipp->s_maxarmies = 1;
+	shipp->s_maxshield = 50;
+	shipp->s_maxdamage = 40;
+	shipp->s_maxwpntemp = 1000;
+	shipp->s_maxegntemp = 1500;
+	shipp->s_letter = 'p';
+	shipp->s_desig[0] = 'P';
+	shipp->s_desig[1] = 'T';
+	shipp->s_bitmap = PATROL;
+	break;
+    }
+    buildShipKeymap(shipp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gppackets.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,164 @@
+/* $Id: gppackets.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#ifndef gppackets_h_
+#define gppackets_h_
+
+/* the definitions of {INT,CARD}{8,16,32} are in packets.h */
+#include "packets.h"
+
+struct gameparam_spacket {
+    INT8    type;
+    INT8    subtype;		/* this packet is not real */
+    /* generic game parameter packet */
+    INT16   pad;
+};
+
+struct gp_sizes_spacket {
+    INT8    type;
+    INT8    subtype;		/* =0 */
+
+    CARD8   nplayers;
+    CARD8   nteams;		/* max of 8 */
+
+    CARD8   nshiptypes;
+    CARD8   nranks;		/* number of ranks */
+    CARD8   nroyal;		/* number of royalties */
+    CARD8   nphasers;
+
+    CARD8   ntorps;
+    CARD8   nplasmas;
+    CARD8   nthingies;		/* per-player */
+    CARD8   gthingies;		/* auxiliary thingies */
+
+    CARD32  gwidth;		/* galaxy width */
+    /* 16 bytes */
+    CARD32  flags;		/* some game parameter flags */
+#define	GP_WRAPVERT	(1<<0)
+#define	GP_WRAPHORIZ	(1<<1)
+#define GP_WRAPALL	(GP_WRAPVERT|GP_WRAPHORIZ)
+
+    /*
+       The following bytes are room for growth. The size of this packet is
+       unimportant because it only gets sent once.  hopefully we've got
+       plenty of room.
+    */
+    INT32   ext1;		/* maybe more flags? */
+    INT32   ext2;
+    INT32   ext3;
+    /* 32 bytes */
+
+    INT32   ext4;
+    INT32   ext5;
+    INT32   ext6;
+    INT32   ext7;
+
+    INT32   ext8;
+    INT32   ext9;
+    INT32   ext10;
+    INT32   ext11;		/* 16 ints, 64 bytes */
+};
+
+struct gp_team_spacket {
+    INT8    type;
+    INT8    subtype;		/* =1 */
+
+    CARD8   index;		/* team index */
+    char    letter;		/* team letter 'F' */
+
+    char    shortname[3];	/* non-null-terminated 3-letter abbrev 'FED' */
+    CARD8   pad;
+    /* 8 bytes */
+    char    teamname[56];	/* padding to 64 byte packet */
+};
+
+struct gp_teamlogo_spacket {
+    /*
+       This packet contains several adjacent rows of a team's logo bitmap
+       Data is in raw XBM format (scanline-padded to 8 bits). Maximum bitmap
+       size is 99x99, which takes 1287 (99x13) bytes.
+    */
+    INT8    type;
+    INT8    subtype;		/* =2 */
+
+    INT8    logowidth;		/* <= 99 */
+    INT8    logoheight;		/* <= 99 */
+
+    INT8    y;			/* y coord of the start of this packets info */
+    INT8    thisheight;		/* the height of this packet's info */
+    INT8    teamindex;		/* which team's logo this is */
+
+    char    data[768 - 7];	/* pad packet to 768 bytes. */
+};
+
+struct gp_shipshape_spacket {
+    INT8    type;
+    INT8    subtype;		/* =3 */
+
+    CARD8   shipno;
+    INT8    race;		/* -1 is independent */
+    CARD8   nviews;		/* typically 16 */
+
+    CARD8   width, height;
+    CARD8   pad1;
+};
+
+struct gp_shipbitmap_spacket {
+    INT8    type;
+    INT8    subtype;		/* =4 */
+
+    CARD8   shipno;
+    INT8    race;		/* -1 is independent */
+    CARD8   thisview;		/* 0..nviews-1 */
+
+    CARD8   bitmapdata[999];
+};
+
+struct gp_rank_spacket {
+    INT8    type;
+    INT8    subtype;		/* =5 */
+
+    INT8    rankn;		/* rank number */
+
+    char    name[-3 + 64 - 20];	/* name of the rank */
+
+    INT32   genocides;
+    INT32   milliDI;		/* DI*1000 */
+    INT32   millibattle;	/* battle*1000 */
+    INT32   millistrat;		/* strategy*1000 */
+    INT32   millispec;		/* special ships*1000 */
+};
+
+struct gp_royal_spacket {
+    INT8    type;
+    INT8    subtype;		/* =6 */
+
+    CARD8   rankn;		/* rank number */
+
+    char    name[-3 + 64];	/* name of the rank */
+};
+
+struct gp_teamplanet_spacket {
+    INT8    type;
+    INT8    subtype;		/* =7 */
+
+    INT8    teamn;		/* 0..7 */
+    CARD8   pad1;
+
+    INT32   ext1;		/* extensions? */
+
+    /*
+       Bitmaps of the team logo and masks.  The bitmap of the planet will be
+       constructed with (mask ? logo : planet), applied bitwise. This
+       calculation is equivalent to (logo&mask)|(planet&~mask)
+    */
+
+    /* bitmap 30x30, X bitmap format (scanline padded to 8 bits) */
+    CARD8   tactical[120];
+    CARD8   tacticalM[120];
+
+    /* bitmap 16x16, X bitmap format (scanline padded to 8 bits) */
+    CARD8   galactic[32];
+    CARD8   galacticM[32];
+};
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/helpwin.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,298 @@
+/* $Id: helpwin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * helpwin.c
+ * copyright 1991 ERic mehlhaff
+ * Free to use, hack, etc. Just keep these credits here.
+ * Use of this code may be dangerous to your health and/or system.
+ * Its use is at your own risk.
+ * I assume no responsibility for damages, real, potential, or imagined,
+ * resulting  from the use of it.
+ *
+ * Hacked into paradise by Bill Dyess
+ */
+
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include <sys/types.h>
+
+
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+
+#ifdef SVR4
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+
+/* this is a set of routines that makes up a multi column help window,
+   ** and shows just what the keymaps current keymap representation of the
+   ** keys are.
+   **
+   **  fillhelp() handles the filling in if the strings for the help window
+   **  update_Help_to_Keymap() checks the keymap and sets it up in hte
+   ** help window.
+   **
+
+   **
+   ** Format for each entry is follows:
+   ** first character is the hard-coded character representation for the key
+   ** in the keymap.  Useful for when you re-key things. This  could confuse
+   ** people who do'nt know the keymap format.
+   **
+   ** the next few spaces are either spaces or  keys that also do that
+   ** function.  Note that if you have more than 3 keys set to do the same
+   ** thing, they will not be displayed.
+   ** So, you could, I suppose map everything to 'Q' and it would not
+   ** show, but that's a pretty bizarre situation.
+   **
+
+   **
+   ** Bugs & Comments:
+   ** You have to be sure that helpWin is defined to be big enough to handle
+   ** all the messages.  That's pretty much a trial&error by-hand thing
+   ** at this point
+   **
+   ** BZZZT!  Not anymore, done automatically [BDyess]
+ */
+
+/*  fills in the help window to note all keys also mapped to the
+   **  listed functions
+ */
+void    update_Help_to_Keymap();
+
+char   *help_message[] =
+{
+    " 0     Set speed 0",
+    " 1     Set speed 1",
+    " 2     Set speed 2",
+    " 3     Set speed 3",
+    " 4     Set speed 4",
+    " 5     Set speed 5",
+    " 6     Set speed 6",
+    " 7     Set speed 7",
+    " 8     Set speed 8",
+    " 9     Set speed 9",
+    "^0     Set speed 10",
+    "^1     Set speed 11",
+    "^2     Set speed 12",
+    "^3     Set speed 13",
+    "^4     Set speed 14",
+    "^5     Set speed 15",
+    "^6     Set speed 16",
+    "^7     Set speed 17",
+    "^8     Set speed 18",
+    "^9     Set speed 19",
+    "^)     Set speed 20",
+    "^!     Set speed 21",
+    "^@     Set speed 22",
+    "^#     Set speed 23",
+    "^$     Set speed 24",
+    "^%     Set speed 25",
+    "^^     Set speed 26",
+    "^&     Set speed 27",
+    "^*     Set speed 28",
+    "^(     Set speed 29",
+    " %     speed = maximum",
+    " #     speed = 1/2 maximum",
+    " <     slow speed 1",
+    " >     speed up 1",
+    " `     Afterburners",
+    " -     Engage warp",
+    " k     Set course",
+    " p     Fire phaser",
+    " t     Fire photon torpedo",
+    " f     Fire plasma torpedo",
+    " C     Switch special weapon",
+    " d     detonate enemy torps",
+    " D     detonate own torps",
+    " L     List players",
+    " P     List planets",
+    " S     Status graph toggle",
+    " ]     Put up shields",
+    " [     Put down shields",
+    " u     Shield toggle",
+    " s     Shield toggle",
+    " i     Info on player/planet",
+    " I     Extended info on player",
+    "^i     Info on a planet",
+    " b     Bomb planet",
+    " z     Beam up armies",
+    " x     Beam down armies",
+    " {     Cloak",
+    " }     Uncloak",
+    " T     Toggle tractor beam",
+    " y     Toggle pressor beam",
+    " _     Turn on tractor beam",
+    " ^     Turn on pressor beam",
+    " $     Turn off tractor/pressor beam",
+    " R     Enter repair mode",
+    " o     Orbit planet or dock to outpost",
+    " e     Docking permission toggle",
+    " r     Refit (change ship type)",
+    " Q     Quit",
+    " q     Fast Quit",
+    " ?     Message window toggle",
+    " c     Cloaking device toggle",
+    " l     Lock on to player/planet",
+    " ;     Lock on to planet",
+    " h     Help window toggle",
+    " w     War declarations window",
+    " N     Planet names toggle",
+    " V     Rotate local planet display",
+    " B     Rotate galactic planet display",
+    " *     Send in practice robot",
+    " E     Send Distress signal",
+    " F     Send armies carried report",
+    " U     Show rankings window",
+    " m     Message Window Zoom",
+    " '     Message Zoom + start to Team",
+    " /     Toggle sorted player list",
+    " :     Toggle message logging",
+    " !     activate kitchen sink",
+    " +     Show UDP options window",
+    " =     Update all",
+    " ,     Ping stats window",
+    " M     Show MOTD window",
+#if 0
+    " .     NetstatWindow",
+    " \\     LagMeter",
+#endif
+
+#ifdef SHORT_PACKETS
+    " ~     Toggle PacketWindow",
+    " \\     Update small",
+    " |     Update medium",
+#endif				/* SHORT_PACKETS */
+
+    "       (space) Unmap special windows",
+
+#ifdef TIMER
+    " @     Reset dashboard timer",
+    "^t     Cycle timer",
+#endif				/* TIMER */
+    "^m     Toggle map zoom",
+#ifdef WIDE_PLIST
+    " K     Cycle playerlist",
+#endif				/* WIDE_PLIST */
+
+#ifdef MACROS
+    " X     Enter Macro Mode",
+    " X?    Show current Macros",
+#endif				/* MACROS */
+
+    " &     Reread .paradiserc",
+    " )     Rotate galaxy clockwise",
+    " (     Rotate galaxy counter-clockwise",
+#ifdef RECORDER
+    "^r     Stop recording",
+#endif
+#ifdef SOUND
+    "^s     Sound window toggle",
+#endif
+#ifdef TOOLS
+  " \"     Toggle shell tools window",
+#endif
+#ifdef AMIGA
+    " A     Flush queued speech",
+    "HELP   Show Amiga keys/info",
+#endif
+    0
+};
+
+int     helpmessages = (sizeof(help_message) / sizeof(char *));
+/* this is the number of help messages there are */
+
+#define MAXHELP 40
+/* maximum length in characters of key explanation */
+
+
+void
+fillhelp()
+{
+    register int i = 0, row, column;
+    char    helpmessage[MAXHELP];
+
+
+    /* 4 column help window. THis may be changed depending on font size */
+    for (column = 0; column < 4; column++) {
+	for (row = 1; row < helpmessages / 4 + 2; row++) {
+	    if (help_message[i] == 0)
+		break;
+	    else {
+		strcpy(helpmessage, help_message[i]);
+		update_Help_to_Keymap(helpmessage);
+		W_WriteText(helpWin, MAXHELP * column, row - 1, textColor,
+			    helpmessage, strlen(helpmessage), W_RegularFont);
+		i++;
+	    }
+	}
+	if (help_message[i] == 0)
+	    break;
+    }
+}
+
+
+/*  this takes the help messages and puts in the keymap, so the player can
+ * see just what does  what!
+ *
+ * ordinary format:       "U     Show rankings window",
+ * translatedd here to    "[ sE  Computer options window",
+ */
+void
+update_Help_to_Keymap(helpmessage)
+    char    helpmessage[];
+{
+    int     i, num_mapped = 0, key;
+
+    key = helpmessage[1];
+    if (helpmessage[0] == '^') {
+	/* control character */
+	key += 128;
+    }
+    if ((int) strlen(helpmessage) < 6) {
+	return;
+    }
+    for (i = 0; i < 256; i++) {
+	if (myship->s_keymap[i] != key)
+	    continue;
+	if (i == key)
+	    continue;		/* it's already there!  don't add it! */
+
+	/* we've found a key mapped to key! */
+	/* the key is i */
+	num_mapped += 1 + (i > 127) ? 1 : 0;
+	if (num_mapped > 3)
+	    continue;		/* we've found too many! */
+
+	/* put the key in the string */
+	if (i > 127) {
+	    helpmessage[1 + num_mapped] = '^';
+	    helpmessage[2 + num_mapped] = i - 128;
+	} else {
+	    helpmessage[2 + num_mapped] = i;
+	}
+    }
+
+
+    /* clear spaces if any area available */
+/*  switch (num_mapped)
+    {
+    case 0:
+      helpmessage[3] = ' ';
+    case 1:
+      helpmessage[4] = ' ';
+    case 2:
+      helpmessage[5] = ' ';
+    case 3:
+    default:
+      helpmessage[6] = ' ';
+    }
+*/
+    return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hockey.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,335 @@
+/* $Id: hockey.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#ifdef HOCKEY
+/* code for hockey lines [BDyess] 9/14/94 */
+
+#include <stdio.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "gameconf.h"
+#include "packets.h"
+
+void dump_hockey_points();
+/*void init_puck();	/* getship.c */
+
+struct player *puck;
+
+/* check to see if on a hockey server and do initialization [BDyess] */
+void hockeyInit() {
+  int i,j;
+  struct planet *l, *last;
+  int rightmost = 0;
+  int leftmost = blk_gwidth;
+  int nplan = paradise ? nplanets : 40; /* shouldn't be Paradise... */
+  int middle = blk_gwidth / 2;
+  int top = 0;
+  int bottom = blk_gwidth;
+  int line = 0;
+  struct point { int x,y; } boxpoints[4];
+		    /* top-topleft, top-bottomright, bottom-topright,
+		       bottom-bottomright, {x,y} for each [BDyess] */
+  W_Color topcolor,bottomcolor;
+
+  topcolor = bottomcolor = W_Grey;
+
+  /* we're playing hockey if a player named "Puck" exists in the 'g'
+     slot, is independant, is in a scout, and has the login name
+     'Robot'. [BDyess] */
+  puck = &players['g'-'a'+10];
+  if(!hockey) {
+    if(0 == strcmp(puck->p_name,"Puck") &&
+       0 == strcmp(puck->p_login,"Robot") &&
+       puck->p_teami < 0 &&
+       SCOUT == puck->p_ship->s_type) {
+
+      printf("Hi Puck!\n");
+      hockey = 1;
+      /*init_puck();*/
+    }
+  }
+  if(!hockey)	/* not a hockey server, nothing more to do */
+    return;
+
+  if(puck->p_ship->s_type != PUCK) {
+    puck->p_ship = getship(PUCK);
+    redrawPlayer[puck->p_no];
+  }
+  if(tacticalHockeyLines) {
+    last = &planets[nplan];
+    /* guess where the lines are supposed to go based on planet
+       location.  Always draws straight lines, ie. if the border
+       bows out, tough - the furthest out planet will have a vertical
+       line through it. [BDyess] */
+
+    /* first the left and rightmost lines [BDyess] */
+    for(l = &planets[0];l < last;l++) {
+      if(l->pl_x < leftmost) {
+	leftmost = l->pl_x;
+      }
+      if(l->pl_x > rightmost) {
+	rightmost = l->pl_x;
+      }
+    }
+    hlines[line].vertical = 1;
+    hlines[line].pos = leftmost;
+    hlines[line].end1 = 0;
+    hlines[line].end2 = blk_gwidth;
+    hlines[line].color = W_Grey;
+    line++;
+    hlines[line].vertical = 1;
+    hlines[line].pos = rightmost;
+    hlines[line].end1 = 0;
+    hlines[line].end2 = blk_gwidth;
+    hlines[line].color = W_Grey;
+    line++;
+    /* now guess the middle planet.  Pick the planet closest to the
+       middle of the screen. [BDyess] */
+    hlines[line].pos = 0;
+    for(l = &planets[0];l < last;l++) {
+      if(ABS(l->pl_y - middle) < ABS(hlines[line].pos - middle))
+	hlines[line].pos = l->pl_y;
+    }
+    middle = hlines[line].pos;
+    hlines[line].end1 = leftmost;
+    hlines[line].end2 = rightmost;
+    hlines[line].vertical = 0;
+    hlines[line].color = W_Red;
+    line++;
+    /* now find the upper and lower middle lines by picking the planets
+       closest to the center yet still above/below the middle and inside
+       the left and rightmost [BDyess] */
+    for(l = &planets[0];l < last;l++) {
+      if(NOBODY == l->pl_owner) continue;
+      if(l->pl_y > top && l->pl_y < middle && 
+	 l->pl_x < rightmost && l->pl_x > leftmost) {
+	top = l->pl_y;
+	topcolor = planetColor(l);
+      }
+      if(l->pl_y < bottom && l->pl_y > middle && 
+	 l->pl_x < rightmost && l->pl_x > leftmost) {
+	bottom = l->pl_y;
+	bottomcolor = planetColor(l);
+      }
+    }
+    hlines[line].pos = top;
+    hlines[line].end1 = leftmost;
+    hlines[line].end2 = rightmost;
+    hlines[line].vertical = 0;
+    hlines[line].color = teamColorHockeyLines ? topcolor : W_Cyan;
+    line++;
+    hlines[line].pos = bottom;
+    hlines[line].end1 = leftmost;
+    hlines[line].end2 = rightmost;
+    hlines[line].vertical = 0;
+    hlines[line].color = teamColorHockeyLines ? bottomcolor : W_Cyan;
+    line++;
+    /* last, try to find the goal box.  Search for the planets that
+       are inside the left and right, above/below the upper/lower middle,
+       and are not neutral.  Of those planets, take the top left and
+       bottom right points [BDyess] */
+    /* toplefts */
+    boxpoints[0].x = boxpoints[0].y = boxpoints[2].x = boxpoints[2].y =
+    		blk_gwidth;
+    /* bottomrights */
+    boxpoints[1].x = boxpoints[1].y = boxpoints[3].x = boxpoints[3].y = 0;
+    for(l = &planets[0];l < last;l++) {
+      /* don't want nobody's planets */
+      if(l->pl_owner == NOBODY) continue;
+      /* check for out-of-bounds */
+      if((l->pl_y >= top && l->pl_y <= bottom) ||
+	 l->pl_x >= rightmost || l->pl_x <= leftmost) continue; 
+      /* top or bottom? */
+      if(l->pl_y < middle) i = 0; /* top */
+      else i = 2; 		  /* bottom */
+      if(l->pl_x <= boxpoints[i].x &&
+         l->pl_y <= boxpoints[i].y) {  /* new topleft */
+	boxpoints[i].x = l->pl_x;
+	boxpoints[i].y = l->pl_y;
+      }
+      if(l->pl_x >= boxpoints[i+1].x &&
+         l->pl_y >= boxpoints[i+1].y) { /* new bottomright */
+	boxpoints[i+1].x = l->pl_x;
+	boxpoints[i+1].y = l->pl_y;
+      }
+    }
+    if(! teamColorHockeyLines) {
+      topcolor = bottomcolor = W_Grey;
+    }
+    hlines[line].vertical = 0;
+    hlines[line].pos = boxpoints[0].y;
+    hlines[line].end1 = boxpoints[0].x;
+    hlines[line].end2 = boxpoints[1].x;
+    hlines[line].color = topcolor;
+    line++;
+    hlines[line].vertical = 1;
+    hlines[line].pos = boxpoints[0].x;
+    hlines[line].end1 = boxpoints[0].y;
+    hlines[line].end2 = boxpoints[1].y;
+    hlines[line].color = topcolor;
+    line++;
+    hlines[line].vertical = 0;
+    hlines[line].pos = boxpoints[1].y;
+    hlines[line].end1 = boxpoints[0].x;
+    hlines[line].end2 = boxpoints[1].x;
+    hlines[line].color = W_Red;
+    line++;
+    hlines[line].vertical = 1;
+    hlines[line].pos = boxpoints[1].x;
+    hlines[line].end1 = boxpoints[0].y;
+    hlines[line].end2 = boxpoints[1].y;
+    hlines[line].color = topcolor;
+    line++;
+
+    hlines[line].vertical = 0;
+    hlines[line].pos = boxpoints[2].y;
+    hlines[line].end1 = boxpoints[2].x;
+    hlines[line].end2 = boxpoints[3].x;
+    hlines[line].color = W_Red;
+    line++;
+    hlines[line].vertical = 1;
+    hlines[line].pos = boxpoints[2].x;
+    hlines[line].end1 = boxpoints[2].y;
+    hlines[line].end2 = boxpoints[3].y;
+    hlines[line].color = bottomcolor;
+    line++;
+    hlines[line].vertical = 0;
+    hlines[line].pos = boxpoints[3].y;
+    hlines[line].end1 = boxpoints[2].x;
+    hlines[line].end2 = boxpoints[3].x;
+    hlines[line].color = bottomcolor;
+    line++;
+    hlines[line].vertical = 1;
+    hlines[line].pos = boxpoints[3].x;
+    hlines[line].end1 = boxpoints[2].y;
+    hlines[line].end2 = boxpoints[3].y;
+    hlines[line].color = bottomcolor;
+    line++;
+  }
+}
+
+/* draw the tactical hockey lines [BDyess] */
+void tactical_hockey() {
+  int i;
+  struct hockeyLine *l = &hlines[0];
+  int dx,dx1,dx2,dy,dy1,dy2;
+  int view = SCALE * WINSIDE / 2;
+  static int old_tacticalHockeyLines, old_galacticHockeyLines,
+             old_cleanHockeyGalactic, old_teamColorHockeyLines;
+
+  if(!hockey)
+    return;
+
+  if(puck->p_ship->s_type != PUCK) {
+    puck->p_ship = getship(PUCK);
+    redrawPlayer[puck->p_no];
+  }
+  if(tacticalHockeyLines != old_tacticalHockeyLines) {
+    redrawall = 1;
+    old_tacticalHockeyLines = tacticalHockeyLines;
+  }
+  if(galacticHockeyLines != old_galacticHockeyLines) {
+    redrawall = 1;
+    old_galacticHockeyLines = galacticHockeyLines;
+  }
+  if(cleanHockeyGalactic != old_cleanHockeyGalactic) {
+    redrawall = 1;
+    old_cleanHockeyGalactic = cleanHockeyGalactic;
+  }
+  if(teamColorHockeyLines != old_teamColorHockeyLines) {
+    old_teamColorHockeyLines = teamColorHockeyLines;
+    hockeyInit();
+  }
+  /* draw whatever hockey lines are visible [BDyess] */
+  if(hockey && tacticalHockeyLines) {		/* if it should be drawn */
+    for(i = 0, l = &hlines[0]; i < NUM_HOCKEY_LINES; i++, l++) {
+      if(l->vertical) {
+	dx = l->pos - me->p_x;
+	dy1 = l->end1 - me->p_y;
+	dy2 = l->end2 - me->p_y;
+	/* is it in view? [BDyess] */
+        if(ABS(dx) <= view && 
+	   (ABS(dy1) <= view || ABS(dy2) <= view ||
+	    (l->end1 <= me->p_y && l->end2 >= me->p_y))) {
+	  dx = dx / SCALE + WINSIDE / 2;
+	  dy1 = dy1 / SCALE + WINSIDE / 2;
+	  dy2 = dy2 / SCALE + WINSIDE / 2;
+	  W_CacheLine(w, dx, dy1, dx, dy2, l->color);
+	  clearline[0][clearlcount] = dx;
+	  clearline[1][clearlcount] = dy1;
+	  clearline[2][clearlcount] = dx;
+	  clearline[3][clearlcount] = dy2; 
+	  clearlcount++;
+	}
+      } else {			/* horizontal */
+	dy = l->pos - me->p_y;
+	dx1 = l->end1 - me->p_x;
+	dx2 = l->end2 - me->p_x;
+	/* is it in view? [BDyess] */
+        if(ABS(dy) <= view && 
+	   (ABS(dx1) <= view || ABS(dx2) <= view ||
+	    (l->end1 <= me->p_x && l->end2 >= me->p_x))) {
+	  dy = dy / SCALE + WINSIDE / 2;
+	  dx1 = dx1 / SCALE + WINSIDE / 2;
+	  dx2 = dx2 / SCALE + WINSIDE / 2;
+	  W_CacheLine(w, dx1, dy,  dx2, dy, l->color);
+	  clearline[0][clearlcount] = dx1;
+	  clearline[1][clearlcount] = dy;
+	  clearline[2][clearlcount] = dx2;
+	  clearline[3][clearlcount] = dy;
+	  clearlcount++;
+	}
+      }
+    }
+  }
+}
+
+/* draw the tactical hockey lines [BDyess] */
+void galactic_hockey() {
+  int i;
+  struct hockeyLine *l;
+  int dx,dx1,dx2,dy,dy1,dy2;
+  int gwidth, offsetx, offsety;
+
+  if(hockey && galacticHockeyLines) {	/* if it should be drawn */
+    if(blk_zoom) {
+      gwidth = blk_gwidth / 2;
+      offsetx = zoom_offset(me->p_x);
+      offsety = zoom_offset(me->p_y);
+      /* keep last offset? */
+    } else {
+      gwidth = blk_gwidth;
+      offsetx = offsety = 0;
+    }
+    for(i = 0, l = &hlines[0]; i < NUM_HOCKEY_LINES; i++, l++) {
+      if(l->vertical) {
+	dx = (l->pos - offsetx) * WINSIDE / gwidth;
+	dy1 = (l->end1 - offsety) * WINSIDE / gwidth;
+	dy2 = (l->end2 - offsety) * WINSIDE / gwidth;
+	W_MakeLine(mapw, dx, dy1, dx, dy2, l->color);
+      } else {
+	dy = (l->pos - offsety) * WINSIDE / gwidth;
+	dx1 = (l->end1 - offsetx) * WINSIDE / gwidth;
+	dx2 = (l->end2 - offsetx) * WINSIDE / gwidth;
+        W_MakeLine(mapw, dx1, dy, dx2, dy, l->color);
+      }
+    }
+  }
+}
+
+void dump_hockey_points() {
+  int i;
+  struct hockeyLine *l;
+
+  printf("Hockey points dump:\n");
+  for (i = 0, l = &hlines[0]; i < NUM_HOCKEY_LINES; i++, l++) {
+    if(l->vertical) {
+      printf("%d: %d,%d  %d,%d\n",i,l->pos,l->end1,l->pos,l->end2);
+    } else {
+      printf("%d: %d,%d  %d,%d\n",i,l->end1,l->pos,l->end2,l->pos);
+    }
+  }
+}      
+#endif /*HOCKEY*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hullbitmaps.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,65 @@
+/* $Id: hullbitmaps.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#define hull_width 22
+#define hull_height 22
+#define HULL_FRAMES   8
+#define HULL_BYTE_SIZE 66
+
+static char hull_bits[HULL_FRAMES][HULL_BYTE_SIZE] = {
+    {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00},
+    {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00},
+    {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00},
+    {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00},
+    {
+	0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00}
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/icon.xbm	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,97 @@
+#define icon_width 112
+#define icon_height 80
+static unsigned char icon_bits[] = {
+  0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x7f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0xf8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc1, 0x83,
+  0x87, 0x9f, 0x7f, 0x3f, 0xf0, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x81, 0x07, 0xc7, 0xcf, 0x3f, 0x7f, 0xf8, 0x39, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x81, 0x07, 0xe7, 0x01, 0x0e, 0xe7, 0x3c, 0xb8, 0x03, 0xd8,
+  0x02, 0x10, 0x6c, 0x80, 0x81, 0x0f, 0xe7, 0x00, 0x0e, 0xc7, 0x1d, 0xf8,
+  0x01, 0x50, 0x56, 0x53, 0x28, 0x80, 0x81, 0x1f, 0xe7, 0x0f, 0x0e, 0xff,
+  0xfc, 0xf9, 0x00, 0x20, 0xb2, 0x36, 0x28, 0x80, 0x81, 0x1b, 0xe7, 0x07,
+  0x0e, 0x3f, 0xfc, 0xf8, 0x01, 0x50, 0x92, 0x51, 0x28, 0x80, 0x81, 0x3b,
+  0xe7, 0x00, 0x0e, 0x77, 0x1c, 0xb8, 0x03, 0xd8, 0x14, 0x53, 0x6c, 0x80,
+  0x81, 0x33, 0xe7, 0x01, 0x0e, 0xe7, 0x3c, 0x38, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x81, 0x73, 0xc7, 0x1f, 0x0e, 0xe7, 0xf8, 0x3b, 0x0e, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x81, 0x63, 0x87, 0x0f, 0x0e, 0xc7, 0xf1, 0x39,
+  0x1c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0xc3, 0x07, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0xc3, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x81, 0x83,
+  0xe7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xc1, 0x03, 0xe7, 0xc6, 0x83, 0x1f, 0x0f, 0x7e, 0x98, 0x0f, 0x1f, 0x3c,
+  0xc0, 0x80, 0x01, 0x00, 0xe0, 0xcc, 0x87, 0x3f, 0x1f, 0xfe, 0xdc, 0x87,
+  0x0f, 0x3e, 0xe0, 0x80, 0x01, 0x00, 0xe0, 0xdc, 0x85, 0x73, 0x17, 0xce,
+  0xdd, 0xc0, 0x01, 0x62, 0xe0, 0x80, 0x01, 0x00, 0xe0, 0xdc, 0x8d, 0x63,
+  0x37, 0x8e, 0xdd, 0xc1, 0x0f, 0x60, 0xd0, 0x80, 0x01, 0x00, 0xe0, 0xd8,
+  0x89, 0x33, 0x27, 0x8e, 0x9d, 0xc3, 0x07, 0x30, 0xc8, 0x80, 0x01, 0x00,
+  0xe0, 0xcf, 0x9d, 0x3f, 0x77, 0x8e, 0x1d, 0xc7, 0x01, 0x18, 0xc8, 0x80,
+  0x01, 0x00, 0xe0, 0xc0, 0x97, 0x73, 0x5f, 0x8e, 0x1d, 0xce, 0x01, 0x0c,
+  0xf8, 0x81, 0x01, 0x00, 0xe0, 0xc0, 0xb3, 0x63, 0xcf, 0xce, 0x1d, 0x9c,
+  0x1f, 0x7e, 0xc3, 0x80, 0x01, 0x00, 0xe0, 0xc0, 0xb1, 0x63, 0xc7, 0xfe,
+  0xdc, 0x0f, 0x0f, 0x7e, 0xc3, 0x80, 0x01, 0x00, 0xe0, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xc1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+  0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x01, 0x00, 0x00, 0xe0, 0xff, 0xff, 0x0f, 0x00, 0x80, 0xff, 0x03, 0x00,
+  0x00, 0x80, 0x01, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x30, 0x00, 0x00, 0x80, 0x01, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0xe0, 0x0f, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x7c, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x21, 0x00, 0x00, 0x00, 0x92, 0x5b, 0x75, 0x83, 0x00, 0x60,
+  0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x54, 0x0f, 0xa4, 0xc8, 0x73,
+  0x2f, 0xa0, 0x1e, 0x00, 0x00, 0x80, 0x01, 0x00, 0x40, 0x89, 0xa2, 0xa8,
+  0x00, 0x42, 0xad, 0x58, 0x00, 0x0e, 0x00, 0x80, 0x01, 0x20, 0x40, 0x12,
+  0x8b, 0xaa, 0x56, 0x09, 0x00, 0x58, 0x30, 0x04, 0x00, 0x80, 0x01, 0x00,
+  0x94, 0xaa, 0x3c, 0x00, 0x10, 0x10, 0x00, 0x00, 0x50, 0x80, 0x03, 0x80,
+  0x01, 0x00, 0x38, 0x24, 0xc0, 0x52, 0x4d, 0x49, 0x09, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x01, 0x00, 0x44, 0x45, 0x25, 0x02, 0x0c, 0xc0, 0x0f, 0x00,
+  0x00, 0x80, 0x70, 0x80, 0x01, 0x00, 0x1a, 0x42, 0x8a, 0x54, 0x01, 0x04,
+  0x00, 0xe0, 0x00, 0x00, 0xc0, 0x80, 0x01, 0x00, 0x40, 0x11, 0x23, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x20, 0x40,
+  0x44, 0x4d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x80, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x04, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00,
+  0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x44, 0xc1, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfe, 0x43, 0x00, 0x04, 0x00, 0x00,
+  0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x13, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xc0, 0x01, 0x00, 0xfe, 0x2b,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xe0, 0x07, 0x00,
+  0xfc, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xe0,
+  0x0f, 0x00, 0xfc, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+  0x00, 0x30, 0x0c, 0x00, 0xf8, 0x07, 0x80, 0xf0, 0x03, 0x00, 0x00, 0x80,
+  0x01, 0x00, 0x00, 0x60, 0x1c, 0x00, 0xf8, 0x07, 0x00, 0xfb, 0x03, 0x00,
+  0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x80, 0x07,
+  0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0xa0, 0x00, 0x00, 0xf8, 0x03,
+  0xc0, 0x07, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00,
+  0xff, 0x0f, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x80,
+  0x00, 0xc0, 0xbf, 0x6f, 0x18, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+  0x00, 0x80, 0x00, 0xf0, 0xcd, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+  0x01, 0x00, 0x00, 0x00, 0x01, 0xbc, 0x6f, 0xec, 0x41, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xff, 0x41, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0xe1, 0x1f,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0xf0, 0xff,
+  0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+  0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+  0xff, 0xff, 0xff, 0x7f, };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/inform.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,561 @@
+/* $Id: inform.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * inform.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include <string.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "gameconf.h"
+#ifdef SOUND
+#include "slib.h"
+#endif
+
+/* Display information about the nearest objext to mouse */
+
+/*
+** When the player asks for info, this routine finds the object
+** nearest the mouse, either player or planet, and pop up a window
+** with the desired information in it.
+**
+** We intentionally provide less information than is actually
+** available.  Keeps the fog of war up.
+**
+** There is a different sized window for each type player/planet
+** and we take care to keep it from extending beyond the main
+** window boundaries.
+*/
+
+/* Prototypes */
+static void inform_planet_paradise P((struct planet * k));
+static void Info_list_normal P((struct player * j));
+static void Info_list_paradise P((struct player * j));
+static void Info_list_small P((struct player * j));
+static void inform_planet_normal P((struct planet * k));
+
+int     last_key = 0;
+
+void
+inform(ww, x, y, key)
+    W_Window ww;
+    int     x, y;
+    char    key;
+{
+    char    buf[BUFSIZ];
+    int     line = 0;
+    register struct player *j;
+    register struct planet *k;
+    int     mx, my;
+    struct obtype *gettarget(), *target;
+    int     windowWidth, windowHeight;
+
+#ifdef SOUND
+    S_PlaySound(S_SENSORS);
+#endif
+    mx = x;
+    my = y;
+    last_key = key;
+    if (key == 'i') {
+	target = gettarget(ww, x, y, TARG_PLAYER | TARG_SELF | TARG_ASTRAL);
+    } else if (key == 'I') {
+	target = gettarget(ww, x, y, TARG_PLAYER | TARG_SELF);
+    } else {			/* control 'i' */
+	target = gettarget(ww, x, y, TARG_ASTRAL);
+	key = 'i';
+    }
+    if (target == NULL)
+	return;			/* NULL returned from gettarget indicates no
+				   target found. [BDyess] */
+    infomapped = 1;
+    if (keepInfo > 0 &&
+	key != 'I')		/* don't blast the long window */
+	infowin_up = keepInfo;
+
+    /*
+       This is pretty lame.  We make a graphics window for the info window so
+       we can accurately space the thing to barely fit into the galactic map
+       or whatever.
+    */
+
+    windowWidth = W_WindowWidth(ww);
+    windowHeight = W_WindowHeight(ww);
+    if (ww == playerw) {
+	windowWidth *= W_Textwidth;
+	windowHeight *= W_Textheight;
+    }
+    infotype = target->o_type;
+    if (target->o_type == PLAYERTYPE) {
+	/* Too close to the edge? */
+	if (mx + 23 * W_Textwidth + 2 > windowWidth)
+	    mx = windowWidth - 23 * W_Textwidth - 2;
+	if (my + 8 * W_Textheight + 2 > windowHeight)
+	    my = windowHeight - 8 * W_Textheight - 2;
+	if (key == 'i') {
+	    infow = W_MakeWindow("info", mx, my, 23 * W_Textwidth, 8 * W_Textheight,
+				 ww, (char *) 0, 2, foreColor);
+	    W_MapWindow(infow);
+	    j = &players[target->o_num];
+	    infothing = (void *) j;
+	    Info_list_small(j);
+	} else {		/* New information window! */
+	    if (!paradise) {	/* if a normal server then */
+		infow = W_MakeWindow("info", mx, my, 23 * W_Textwidth,
+			    8 * W_Textheight, ww, (char *) 0, 2, foreColor);
+		W_MapWindow(infow);
+		j = &players[target->o_num];
+		infothing = (void *) j;
+		(void) sprintf(buf, "%s (%c%c):", j->p_name,
+			     teaminfo[j->p_teami].letter, shipnos[j->p_no]);
+		W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+			    playerColor(j), buf, strlen(buf), shipFont(j));
+		Info_list_normal(j);
+	    } else {		/* else if a paradise server */
+		if (mx + 50 * W_Textwidth + 2 > windowWidth)
+		    mx = windowWidth - 50 * W_Textwidth - 2;
+		if (my + 25 * W_Textheight + 2 > windowHeight)
+		    my = windowHeight - 22 * W_Textheight - 2;
+		infow = W_MakeWindow("info", mx, my, 50 * W_Textwidth,
+			   22 * W_Textheight, ww, (char *) 0, 2, foreColor);
+		W_MapWindow(infow);
+		j = &players[target->o_num];
+		infothing = (void *) j;
+		(void) sprintf(buf, "%s (%c%c):", j->p_name,
+			     teaminfo[j->p_teami].letter, shipnos[j->p_no]);
+		W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+			    playerColor(j), buf, strlen(buf), shipFont(j));
+		Info_list_paradise(j);
+	    }
+	}
+    } else {			/* Planet */
+	if (paradise) {
+	    /* Too close to the edge? */
+	    if (mx + 25 * W_Textwidth + 2 > windowWidth)
+		mx = windowWidth - 25 * W_Textwidth - 2;
+	    if (my + 5 * W_Textheight + 2 > windowHeight)
+		my = windowHeight - 5 * W_Textheight - 2;
+
+	    infow = W_MakeWindow("info", mx, my, W_Textwidth * 25, W_Textheight * 5, ww,
+				 (char *) 0, 2, foreColor);
+	} else {
+	    /* Too close to the edge? */
+	    if (mx + 25 * W_Textwidth + 2 > windowWidth)
+		mx = windowWidth - 25 * W_Textwidth - 2;
+	    if (my + 3 * W_Textheight + 2 > windowHeight)
+		my = windowHeight - 5 * W_Textheight - 2;
+
+	    infow = W_MakeWindow("info", mx, my, W_Textwidth * 25, W_Textheight * 3, ww,
+				 (char *) 0, 2, foreColor);
+	}
+	W_MapWindow(infow);
+	k = &planets[target->o_num];
+	infothing = (void *) k;
+	/*
+	   dist = hypot((double) (me->p_x - k->pl_x), (double) (me->p_y -
+	   k->pl_y));
+	*/
+
+	if (!paradise) {	/* if not a paradise server */
+	    inform_planet_normal(k);
+	} else {		/* else must be a paradise server */
+	    inform_planet_paradise(k);	/* go display paradise info */
+	}
+    }
+}
+
+
+void
+destroyInfo()
+{
+    W_DestroyWindow(infow);
+    infow = 0;
+    infomapped = 0;
+    infotype = 0;
+    infoupdate = 0;
+}
+
+
+static void
+Info_list_small(j)
+    struct player *j;
+{
+    char    buf[100];
+    int     line = 0;
+    double  dist;
+
+    (void) sprintf(buf, "%s (%c%c):", j->p_name, teaminfo[j->p_teami].letter,
+		   shipnos[j->p_no]);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), shipFont(j));
+    (void) sprintf(buf, "Login   %-s", j->p_login);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf),
+		W_RegularFont);
+    (void) sprintf(buf, "Display %-s", j->p_monitor);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf),
+		W_RegularFont);
+    (void) sprintf(buf, "Speed   %-d", j->p_speed);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf),
+		W_RegularFont);
+    (void) sprintf(buf, "kills   %-4.2f", j->p_kills);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf),
+		W_RegularFont);
+    dist = hypot((double) (me->p_x - j->p_x),
+		 (double) (me->p_y - j->p_y)) / (double) GRIDSIZE;
+    (void) sprintf(buf, "dist    %-1.2f sectors", dist);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf),
+		W_RegularFont);
+    (void) sprintf(buf, "S-Class %-2.2s", j->p_ship->s_desig);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf),
+		W_RegularFont);
+
+    if (j->p_swar & idx_to_mask(me->p_teami))
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		    "WAR", 3,
+		    W_RegularFont);
+    else if (j->p_hostile & idx_to_mask(me->p_teami))
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		    "HOSTILE", 7,
+		    W_RegularFont);
+    else
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		    "PEACEFUL", 8,
+		    W_RegularFont);
+}
+
+static void
+inform_planet_normal(k)
+    struct planet *k;
+{
+    char    buf[100];
+    int     line = 0;
+
+    if (k->pl_info & idx_to_mask(me->p_teami)) {
+	(void) sprintf(buf, "%s (%c)", k->pl_name,
+		       teaminfo[mask_to_idx(k->pl_owner)].letter);
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k),
+		    buf, strlen(buf), planetFont(k));
+	(void) sprintf(buf, "Armies %d", k->pl_armies);
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+		    planetColor(k), buf, strlen(buf), W_RegularFont);
+	(void) sprintf(buf, "%s %s %s   %s",
+		       (k->pl_flags & PLREPAIR ? "RPR" : "      "),
+		       (k->pl_flags & PLFUEL ? "FUEL" : "    "),
+		       (k->pl_flags & PLAGRI ? "AGRI" : "    "),
+		       team_bit_string(k->pl_info));
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+		    planetColor(k), buf, strlen(buf), W_RegularFont);
+    } else {			/* else player has no info on planet */
+	(void) sprintf(buf, "%s", k->pl_name);
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k),
+		    buf, strlen(buf), W_RegularFont);
+	(void) sprintf(buf, "No other info");
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k),
+		    buf, strlen(buf), W_RegularFont);
+    }
+}
+
+
+/*  This function provides info about planets for a paradise version 2.0
+server.  */
+
+static void
+inform_planet_paradise(k)
+    struct planet *k;		/* the planet */
+{
+    char    buf[100];
+    int     line = 0;
+
+    if (k->pl_flags & PLSTAR) {	/* test if planet is a star */
+	(void) sprintf(buf, "%s", k->pl_name);
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, textColor,
+		    buf, strlen(buf), W_RegularFont);
+	(void) sprintf(buf, "STAR  ");
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+		    textColor, buf, strlen(buf), W_RegularFont);
+    } else if (!(k->pl_info & idx_to_mask(me->p_teami))) {	/* else if no info */
+	(void) sprintf(buf, "%s", k->pl_name);
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k),
+		    buf, strlen(buf), W_RegularFont);
+	(void) sprintf(buf, "No other info");
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k),
+		    buf, strlen(buf), W_RegularFont);
+    } else {			/* else we have info */
+	(void) sprintf(buf, "%s (%c)", k->pl_name,
+		       teaminfo[mask_to_idx(k->pl_owner)].letter);
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++, planetColor(k),
+		    buf, strlen(buf), W_RegularFont);
+	(void) sprintf(buf, "Armies %d", k->pl_armies);
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+		    planetColor(k), buf, strlen(buf), W_RegularFont);
+	(void) sprintf(buf, "%s %s %s %s",
+		       (k->pl_flags & PLREPAIR ? "RPR" : "      "),
+		       (k->pl_flags & PLFUEL ? "FUEL" : "    "),
+		       (k->pl_flags & PLAGRI ? "AGRI" : "    "),
+		       (k->pl_flags & PLSHIPYARD ? "SHPYD" : "     "));
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+		    planetColor(k), buf, strlen(buf), W_RegularFont);
+	(void) sprintf(buf, "atmos: ");
+	switch (k->pl_flags & PLATMASK) {
+	case PLPOISON:
+	    strcat(buf, "TOXC  surfc: ");
+	    break;
+	case PLATYPE3:
+	    strcat(buf, "TNTD  surfc: ");
+	    break;
+	case PLATYPE2:
+	    strcat(buf, "THIN  surfc: ");
+	    break;
+	case PLATYPE1:
+	    strcat(buf, "STND  surfc: ");
+	    break;
+	default:
+	    strcat(buf, "      surfc: ");
+	    break;
+	};
+	if (k->pl_flags & PLDILYTH)
+	    strcat(buf, "D");
+	else
+	    strcat(buf, " ");
+	if (k->pl_flags & PLMETAL)
+	    strcat(buf, "M");
+	else
+	    strcat(buf, " ");
+	if (k->pl_flags & PLARABLE)
+	    strcat(buf, "A");
+	else
+	    strcat(buf, " ");
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+		    planetColor(k), buf, strlen(buf), W_RegularFont);
+	sprintf(buf, "Time: %-5d Visit: %s",
+		((idx_to_mask(me->p_teami) == k->pl_owner) ? 0
+		 : (int) (status2->clock - k->pl_timestamp)),
+		team_bit_string(k->pl_info));
+	W_WriteText(infow, W_Textwidth, W_Textheight * line++,
+		    planetColor(k), buf, strlen(buf), W_RegularFont);
+    }
+}
+
+
+
+static void
+Info_list_normal(j)
+    struct player *j;		/* player to do info on */
+{
+    char    buf[80];
+    int     line = 0;
+    struct ratings r;
+
+    get_ratings(j, &r);
+    sprintf(buf, "%s (%c%c):", j->p_name, teaminfo[j->p_teami].letter,
+	    shipnos[j->p_no]);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    strcpy(buf, "        Rating Total");
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Bombing: %5.2f  %5d", r.r_bombrat, r.r_armies);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Planets: %5.2f  %5d", r.r_planetrat, r.r_planets);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Offense: %5.2f  %5d", r.r_offrat, r.r_kills);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Defense: %5.2f  %5d", r.r_defrat, r.r_losses);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "  Maxkills: %6.2f", r.r_maxkills);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "  Hours:    %6.2f", (float) j->p_stats.st_tticks / 36000.0);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+}
+
+static void
+Info_list_paradise(j)
+    struct player *j;		/* player to do info on */
+{
+    char    buf[80];
+    int     line = 0;
+    struct ratings r;
+
+    get_ratings(j, &r);
+
+    sprintf(buf, "Name: %s", j->p_name);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Rank: %s", ranks2[j->p_stats2.st_rank].name);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Royalty: %s", royal[j->p_stats2.st_royal].name);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Genocides: %4d", r.r_genocides);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "DI:     %7.2f", r.r_di);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Maxkills:%6.2f", j->p_stats2.st_tmaxkills);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Kills:     %4d", j->p_stats2.st_tkills);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Losses:    %4d", j->p_stats2.st_tlosses);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "T-hours: %6.2f", (float) j->p_stats2.st_tticks / 36000.0);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "   ");
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    strcpy(buf, "            Rating Total");
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Bombing:   %5.2f  %6d", r.r_bombrat, r.r_armies);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Planets:   %5.2f  %6d", r.r_planetrat, r.r_planets);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Resources: %5.2f  %6d", r.r_resrat, r.r_resources);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Dooshes:   %5.2f  %6d", r.r_dooshrat, r.r_dooshes);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Ratio:     %5.2f", j->p_stats2.st_tkills /
+	    ((j->p_stats2.st_tlosses) ? j->p_stats2.st_tlosses : 1.0));
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Offense:   %5.2f", r.r_offrat);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "   ");
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "RATINGS");
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Special ships: %7.2f", r.r_specrat);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Battle:        %7.2f", r.r_batrat);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Strategy:      %7.2f", r.r_stratrat);
+    W_WriteText(infow, W_Textwidth, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+
+    line = 1;
+    sprintf(buf, "   ");
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "JUMPSHIP STATS");
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Planets:    %7d", j->p_stats2.st_jsplanets);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Hours:      %7.2f", (float) j->p_stats2.st_jsticks / 36000.0);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "JS rating:  %7.2f", r.r_jsrat);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+
+    sprintf(buf, "   ");
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "STARBASE STATS");
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Kills:        %4d", j->p_stats2.st_sbkills);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Losses:       %4d", j->p_stats2.st_sblosses);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Hours:     %7.2f", (float) j->p_stats2.st_sbticks / 36000.0);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Maxkills:  %7.2f", j->p_stats2.st_sbmaxkills);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "SB rating: %7.2f", r.r_sbrat);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+
+    sprintf(buf, "   ");
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "WARBASE STATS");
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Kills:        %4d", j->p_stats2.st_wbkills);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Losses:       %4d", j->p_stats2.st_wblosses);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Hours:     %7.2f", (float) j->p_stats2.st_wbticks / 36000.0);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "Maxkills:  %7.2f", j->p_stats2.st_wbmaxkills);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+    sprintf(buf, "WB rating: %7.2f", r.r_wbrat);
+    W_WriteText(infow, W_Textwidth * 28, W_Textheight * line++, playerColor(j),
+		buf, strlen(buf), W_RegularFont);
+}
+
+/*
+   constantly updating info window code [BDyess]
+*/
+void
+updateInform()
+{
+    if (!infomapped || !paradise)
+	return;			/* disabled for Bronco servers */
+    if (infotype == PLAYERTYPE && last_key == 'i' && (redrawPlayer[me->p_no] ||
+			 redrawPlayer[((struct player *) infothing)->p_no]))
+	infoupdate = 1;
+    if (infoupdate) {
+	infoupdate = 0;
+	W_ClearWindow(infow);
+	if (infotype == PLAYERTYPE) {
+	    /* if(isAlive((struct player*)infothing)) { */
+	    if (last_key == 'i')/* use small info */
+		Info_list_small((struct player *) infothing);
+	    else if (!paradise)
+		Info_list_normal((struct player *) infothing);
+	    else
+		Info_list_paradise((struct player *) infothing);
+	    /*
+	       } else { destroyInfo(); }
+	    */
+	} else {		/* planet */
+	    if (!paradise)
+		inform_planet_normal((struct planet *) infothing);
+	    else
+		inform_planet_paradise((struct planet *) infothing);
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/input.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1199 @@
+/* $Id: input.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * input.c
+ *
+ * Modified to work as client in socket based protocol
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <sys/types.h>
+#ifdef RS6K
+#include <sys/select.h>
+#endif
+#ifdef hpux
+#include <time.h>
+#else				/* hpux */
+#include <sys/time.h>
+#endif				/* hpux */
+#include <signal.h>
+#include <errno.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif
+
+#define control(x) (x)+128
+
+/* Prototypes */
+static void buttonaction P((W_Event * data));
+static void keyaction P((W_Event * data));
+static void scan P((W_Window w, int x, int y));
+/*static void selectblkbozo P((W_Event *data));*/
+
+static int tmodeChange = 0;	/* handles first change of tmode; including */
+				/* when a play first joins a tmode game */
+
+void
+initinput()
+{
+    /* Nothing doing... */
+}
+
+void
+dispatch_W_key_event(evt)
+    W_Event *evt;
+{
+    int     i;
+
+    /* try to speed up response -JR */
+    if (!messageon && (evt->Window == w || evt->Window == mapw)) {
+	keyaction(evt);
+	return;
+    }
+    for (i = 0; i < WNUM; i++) {
+	if (evt->Window == messWin[i].window) {
+	    messageWinEvent(evt);
+	    return;
+	}
+    }
+    if (evt->Window == optionWin)
+	optionaction(evt);
+    else if (
+#ifdef NOWARP
+	     messageon ||
+#endif
+	     evt->Window == messagew ||
+	     evt->Window == tstatw ||
+	     evt->Window == warnw) {
+	smessage(evt->key);
+#ifdef SHORT_PACKETS
+    } else if (evt->Window == spWin) {
+	spaction(evt);
+#endif
+    } else if (evt->Window == motdWin) {
+	motdWinEvent(evt->key);
+    } else if (evt->Window == playerw) {
+	playerwEvent(evt);
+    } else if (evt->Window == defWin && evt->key == ' ') {
+	W_UnmapWindow(defWin);
+#ifdef SOUND
+    } else if (evt->Window == soundWin) {
+	soundaction(evt);
+#endif
+#ifdef TOOLS
+    } else if (evt->Window == toolsWin) {
+	smessage_ahead('!', evt->key);
+#endif
+    } else {
+	keyaction(evt);
+    }
+}
+
+void
+dispatch_W_button_event(evt)
+    W_Event *evt;
+{
+    int     i;
+
+    if (evt->Window == w || evt->Window == mapw) {
+	buttonaction(evt);
+	return;
+    }
+    for (i = 0; i < WNUM; i++) {
+	if (evt->Window == messWin[i].window) {
+	    messageWinEvent(evt);
+	    return;
+	}
+    }
+    if (evt->Window == war)
+	waraction(evt);
+    else if (evt->Window == optionWin)
+	optionaction(evt);
+#ifdef ATM
+    else if (evt->Window == udpWin)
+	udpaction(evt);		/* UDP */
+#endif				/* ATM */
+#ifdef SHORT_PACKETS
+    else if (evt->Window == spWin)
+	spaction(evt);
+#endif
+#ifdef SOUND
+    else if (evt->Window == soundWin)
+	soundaction(evt);
+#endif
+    else if (evt->Window == playerw)
+	selectblkbozo(evt);
+#ifdef MACROS
+    else if (evt->Window == macroWin)
+	switchmacros();
+#endif
+#ifdef XTREKRC_HELP
+    else if (evt->Window == defWin)
+	def_action(evt);
+#endif
+    else
+	buttonaction(evt);
+}
+
+void
+dispatch_W_expose_event(evt)
+    W_Event *evt;
+{
+    /*
+       if anything but the iconWin is refreshed, turn off the iconified flag.
+       [BDyess]
+    */
+    if (evt->Window != iconWin)
+	iconified = 0;
+    if (evt->Window == statwin)
+	redrawStats();
+    else if (evt->Window == tstatw)
+	redrawTstats();
+    else if (evt->Window == mapw)
+	redrawall = 1;
+    else if (evt->Window == iconWin)
+	drawIcon();
+    else if (evt->Window == helpWin)
+	fillhelp();
+    else if (evt->Window == macroWin)
+	fillmacro();
+    else if (evt->Window == playerw)
+	playerlist();
+    else if (evt->Window == planetw)
+	planetlist();
+    else if (evt->Window == planetw2)
+	planetlist();
+    else if (evt->Window == rankw)
+	ranklist();
+    else if (evt->Window == warnw)
+	W_ClearWindow(warnw);
+    else if (evt->Window == messagew)
+	message_expose();
+    else if (evt->Window == motdWin)
+	motdWinEvent('r');	/* 'r' is refresh */
+    /*
+       lag meter?  maybe later - RF else if (evt->Window == lMeter)
+       redrawLMeter();
+    */
+    else if (evt->Window == pStats)
+	redrawPStats();
+#ifdef XTREKRC_HELP
+    else if (defWin && (evt->Window == defWin))
+	showdef();
+#endif
+}
+
+void
+dispatch_W_event(evt)
+    W_Event *evt;
+{
+    switch ((int) evt->type) {
+    case W_EV_KEY:
+	dispatch_W_key_event(evt);
+	break;
+#ifdef AUTOKEY
+    case W_EV_KEY_OFF:
+	if (autoKey)
+	    autoKeyOff(evt);
+	break;
+#endif				/* AUTOKEY */
+    case W_EV_BUTTON:
+	dispatch_W_button_event(evt);
+	break;
+    case W_EV_EXPOSE:
+	dispatch_W_expose_event(evt);
+	break;
+    default:
+	break;
+    }
+}
+
+/* this figures out what to set war dec's */
+void autoWarDecl(scheme)
+     int scheme;
+{
+     extern int number_of_teams;
+     int i, j, k, *team, enemymask = 0;
+     struct player *pptr;
+
+     if((team = (int *)malloc(number_of_teams * sizeof(int))) == NULL) {
+        perror("autoWarDecl: malloc error\n");
+        return;
+     }
+     memset(team, 0, sizeof(int)*number_of_teams);
+     for(i=0, pptr=&players[i]; i < nplayers; i++, pptr++)
+        if(pptr->p_status != PFREE && !(pptr->p_status == POUTFIT &&
+                                     pptr->p_teami < 0)) {
+             team[pptr->p_teami]++;
+        }
+     switch(scheme) {
+     case 1:
+        /* war with all non-zero member team */
+        /* peace with teams with 0 players */
+        for(i=0; i < number_of_teams; i++) {
+             if(i != me->p_teami)
+                  enemymask ^= team[i] ? (1<<i) : 0;
+             /*printf("team: %i, #: %i\n", i, team[i]);
+              */
+        }
+        /*printf("mask: %i\n", enemymask);
+         */
+        break;
+     case 2:
+        /* war with only the largest enemy */
+        /* team; peace with everyone else*/
+        for(i=0; i < number_of_teams; i++) {
+             if ((i != me->p_teami) && (j < team[i])) {
+                  j = team[i];
+                  k = i;
+             }
+        }
+        enemymask = 0 | (1 << k);
+        break;
+     }
+     sendWarReq(enemymask);
+     free(team);
+} /* end of autoWarDecl */
+
+
+/* this new event loop allows more flexibility in state transitions */
+void
+input()
+{
+    W_Event data;
+    fd_set  readfds;
+    int     wsock = W_Socket();
+    int     old_tourn = paradise ? status2->tourn : status->tourn, new_tourn;
+
+#ifdef AUTOKEY
+    struct timeval timeout;
+
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 100000;
+#endif				/* AUTOKEY */
+
+#ifdef RECORDER
+    if (playback) {
+	pb_input(); /* recorder.c */
+	return;
+    }
+#endif
+    while (me->p_status == PALIVE ||
+	   me->p_status == PEXPLODE ||
+	   me->p_status == PDEAD ||
+	   me->p_status == POBSERVE) {
+
+#ifdef TIMELORD
+	/* we're playing.  Count the seconds */
+	update_timelord(0);
+#endif
+
+	if (keepInfo > 0) {
+	    if (infowin_up >= 0 &&
+		--infowin_up == -1 &&
+		infomapped) {
+		destroyInfo();
+		infowin_up = -2;
+	    }
+	}
+	exitInputLoop = 0;
+	while (W_EventsPending() && !exitInputLoop) {
+	    fastQuit = 0;	/* any event cancel fastquit */
+	    W_NextEvent(&data);
+	    dispatch_W_event(&data);
+	}
+
+#if 0
+	/*
+	   Do some enforcement of non-paradise feature disabling. The options
+	   menu doesn't deal with this too well.
+	*/
+	if (!paradise) {
+	    blk_zoom = 0;
+	    blk_showStars = 0;
+	}
+#endif
+#ifndef AMIGA
+	FD_ZERO(&readfds);
+	FD_SET(wsock, &readfds);
+	FD_SET(sock, &readfds);
+	if (udpSock >= 0)
+	    FD_SET(udpSock, &readfds);
+#ifdef AUTOKEY
+	    if (autoKey) {
+		doAutoKey();
+		if (select(32, &readfds, (fd_set *) 0, (fd_set *) 0, &timeout) == 0)	/* timeout */
+		    continue;
+	    } else
+#endif
+		select(32, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
+#else				/* AMIGA */
+#ifdef DNET
+	sigsPending = Wait(wsock | sockMask | udpSockMask | SIGBREAKF_CTRL_C);
+#else
+/* insert code here for Amiga with TCP/IP... */
+#endif				/* DNET */
+	if (sigsPending & SIGBREAKF_CTRL_C) {
+	    printf("User break, Ctrl-C, exiting!\n");
+	    exit(0);
+	}
+/* note: for DNET, FD_ISSET is faked, see amigadefs.h -JR */
+#endif				/* AMIGA */
+	if (FD_ISSET(sock, &readfds) ||
+	    (udpSock >= 0 && FD_ISSET(udpSock, &readfds))) {
+	    
+#ifdef HANDLER_TIMES
+	    start_log();
+#endif
+	    intrupt();
+#ifdef HANDLER_TIMES
+	    stop_log(64);
+#endif
+	    if (isServerDead()) {
+		printf("Whoops!  We've been ghostbusted!\n");
+		printf("Pray for a miracle!\n");
+		
+		/* UDP fail-safe */
+		commMode = commModeReq = COMM_TCP;
+		commSwitchTimeout = 0;
+		if (udpSock >= 0)
+		    closeUdpConn();
+		if (udpWin) {
+		    udprefresh(UDP_CURRENT);
+		    udprefresh(UDP_STATUS);
+		}
+		connectToServer(nextSocket);
+		printf("Yea!  We've been resurrected!\n");
+	    }
+	    /*
+	       beep if tmode status changes.  Idea from Roger Books. [BDyess]
+	    */
+	    new_tourn = paradise ? status2->tourn : status->tourn;
+
+	    /* change war dec's at transitions to */
+	    /* positive tmode */
+	    if (!tmodeChange && new_tourn) {
+		 autoWarDecl(autoSetWar);
+		 tmodeChange = 1;
+	    }
+
+	    if (old_tourn != new_tourn) {
+#ifndef SOUND
+		W_Beep();
+#else
+		S_PlaySound(S_TMODE);
+#endif
+		old_tourn = new_tourn;
+	    }
+	    continue;
+	}
+    }
+}
+
+
+static void
+keyaction(data)
+    W_Event *data;
+{
+    unsigned char course;
+    struct obtype *target;
+    int     key = data->key;
+    struct shiplist *temp;
+
+    if (data->Window != mapw && data->Window != w
+	&& data->Window != planetw && data->Window != planetw2
+	&& data->Window != rankw
+#ifdef ATM
+	&& data->Window != scanw
+#endif				/* ATM */
+	)
+	return;
+
+#ifdef RECORDER
+    if (playback)
+	pb_dokey(data);
+#endif
+    if (localflags & PFREFIT) {
+	temp = shiptypes;
+	while (temp) {
+	    if (temp->ship->s_letter == key) {
+		do_refit(temp->ship->s_type);
+		return;
+	    }
+	    temp = temp->next;
+	}
+    } else {
+	key = doKeymap(data);
+	if (key == -1)
+	    return;
+    }
+
+    switch (key) {
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+	set_speed(key - '0');
+	localflags &= ~(PFREFIT);
+	break;
+    case 'e':			/* Turn off docking permission, eject docked
+				   vessels. */
+	sendDockingReq(!(me->p_flags & PFDOCKOK));
+	break;
+    case 'r':
+	localflags |= PFREFIT;
+	warning(blk_refitstring);
+	break;
+    case control('0'):		/* ctrl 0-9, speed 10-19 */
+    case control('1'):
+    case control('2'):
+    case control('3'):
+    case control('4'):
+    case control('5'):
+    case control('6'):
+    case control('7'):
+    case control('8'):
+    case control('9'):
+	set_speed(10 + key - control('0'));
+	localflags &= ~(PFREFIT);
+	break;
+    case control(')'):		/* ctrl-shift 0-9, speed 20-29 */
+	set_speed(20);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('!'):		/* ctrl-shift-1, speed 21 */
+	set_speed(21);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('@'):		/* ctrl-shift-2, speed 22 */
+	set_speed(22);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('#'):		/* ctrl-shift-3, speed 23 */
+	set_speed(23);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('$'):		/* ctrl-shift-4, speed 24 */
+	set_speed(24);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('%'):		/* ctrl-shift-5, speed 25 */
+	set_speed(25);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('^'):		/* ctrl-shift-6, speed 26 */
+	set_speed(26);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('&'):		/* ctrl-shift-7, speed 27 */
+	set_speed(27);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('*'):		/* ctrl-shift-8, speed 28 */
+	set_speed(28);
+	localflags &= ~(PFREFIT);
+	break;
+    case control('('):		/* ctrl-shift-9, speed 29 */
+	set_speed(29);
+	localflags &= ~(PFREFIT);
+	break;
+    case '`':			/* afterburners */
+	set_speed(98);
+	localflags &= ~(PFREFIT);
+	break;
+    case '-':
+	set_speed(99);		/* warp! */
+	localflags &= ~(PFREFIT);
+	break;
+    case control('-'):		/* suspend warp toggle [BDyess] */
+	if (me->p_flags & PFWPSUSPENDED)
+	    set_speed(96);	/* unsuspend */
+	else
+	    set_speed(97);	/* suspend */
+	localflags &= ~(PFREFIT);
+	break;
+    case '%':			/* max impulse */
+	set_speed(me->p_ship->s_maxspeed);
+	localflags &= ~(PFREFIT);
+	break;
+    case '<':			/* speed -= 1 */
+	set_speed(me->p_speed - 1);
+	localflags &= ~(PFREFIT);
+	break;
+    case '>':			/* speed += 1 */
+	set_speed(me->p_speed + 1);
+	localflags &= ~(PFREFIT);
+	break;
+    case '#':			/* halfimpulse */
+	set_speed((me->p_ship->s_maxspeed + 1) / 2);
+	localflags &= ~(PFREFIT);
+	break;
+    case ':':			/* toggle message logging */
+	if (logmess)
+	    warning("Message logging disabled");
+	else
+	    warning("Message logging enabled");
+	logmess = !logmess;
+	break;
+    case '!':
+#if 1
+	showKitchenSink = !showKitchenSink;
+	warning(showKitchenSink ?
+		"Kitchen Sink activated.  Bad guys beware!" :
+		"Kitchen Sink deactivated.");
+#else
+	if (blk_altbits) {
+	    blk_altbits = 0;
+	    warning("Switching to old bitmaps.");
+	} else {
+	    blk_altbits = 1;
+	    warning("Switching to new bitmaps.");
+	}
+	localflags &= ~(PFREFIT);
+	if (optionWin)
+	    optionredrawoption(&blk_altbits);
+#endif
+	break;
+#ifdef TIMER
+    case '@':
+	timeBank[T_USR] = time(NULL);
+	timerType = T_USR;
+	break;
+    case control('t'):
+	timerType++;
+	if (timerType >= T_TOTAL)
+	    timerType = 0;
+	break;
+#endif				/* TIMER */
+#ifdef WIDE_PLIST
+    case 'K':			/* cycle playerlist [BDyess] */
+	while (*playerList && *playerList != ',')
+	    playerList++;
+	if (*playerList == ',')
+	    playerList++;
+	else if (*playerList == 0)
+	    playerList = playerListStart;
+	break;
+#endif				/* WIDE_PLIST */
+    case 'a':
+#ifdef ATM
+	if (!W_IsMapped(scanwin)) {
+	    scan(data->Window, data->x, data->y);
+	} else {
+	    if (scanmapped)
+		W_UnmapWindow(scanwin);
+	    scanmapped = 0;
+	}
+#endif				/* ATM */
+	break;
+    case 'm':			/* new from galaxy -- works here too */
+    case '\'':           /* ' starts message to 'T'eam */
+#ifdef NOWARP
+	message_on();
+#else
+	W_WarpPointer(messagew);
+#endif
+	if((key == '\'') && (messpend==0)) {
+	    smessage(lowercaset ? 't' : 'T');
+	}
+	break;
+    case 'k':			/* k = set course */
+	course = getcourse(data->Window, data->x, data->y);
+	set_course(course);
+	me->p_flags &= ~(PFPLOCK | PFPLLOCK);
+	localflags &= ~(PFREFIT);
+	break;
+    case 'p':			/* p = fire phasers */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyPhaserReqOn();
+	else {
+	    course = getcourse(data->Window, data->x, data->y);
+	    sendPhaserReq(course);
+	}
+#else
+	course = getcourse(data->Window, data->x, data->y);
+	sendPhaserReq(course);
+#endif				/* AUTOKEY */
+	break;
+    case 't':			/* t = launch torps */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyTorpReqOn();
+	else {
+	    course = getcourse(data->Window, data->x, data->y);
+	    sendTorpReq(course);
+	}
+#else
+	course = getcourse(data->Window, data->x, data->y);
+	sendTorpReq(course);
+#endif				/* AUTOKEY */
+	break;
+    case 'f':
+	/* f = launch plasma torpedos */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyPlasmaReqOn();
+	else {
+	    course = getcourse(data->Window, data->x, data->y);
+	    sendPlasmaReq(course);
+	}
+#else
+	course = getcourse(data->Window, data->x, data->y);
+	sendPlasmaReq(course);
+#endif				/* AUTOKEY */
+	break;
+    case 'd':			/* d = detonate other torps */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyDetReqOn();
+	else
+	    sendDetonateReq();
+#else
+	sendDetonateReq();
+#endif				/* AUTOKEY */
+	break;
+    case 'D':			/* D = detonate my torps */
+	detmine();
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyAllOff();	/* xx */
+#endif
+	break;
+    case '[':
+	shield_down();
+	break;
+    case ']':
+	shield_up();
+	break;
+    case 'u':			/* u = toggle shields */
+	shield_tog();
+	break;
+    case 's':			/* For Serge */
+	shield_tog();
+	break;
+    case 'b':			/* b = bomb planet */
+#ifdef AUTOKEY
+	if (autoKey && !(localflags & PFREFIT))
+	    autoKeyBombReqOn();
+	else
+	    bomb_planet();
+#else
+	bomb_planet();
+#endif				/* AUTOKEY */
+	break;
+    case 'z':			/* z = beam up */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyBeamUpReqOn();
+	else
+#endif
+	    beam_up();
+	break;
+    case 'x':			/* x = beam down */
+#ifdef AUTOKEY
+	if (autoKey)
+	    autoKeyBeamDownReqOn();
+	else
+#endif
+	    beam_down();
+	break;
+    case 'X':			/* X = enter macro mode */
+	macroState = 1;
+	warning("Macro mode");
+	break;
+    case 'R':			/* R = Go into repair mode */
+	sendRepairReq(1);
+	break;
+    case 'y':
+    case 'T':
+    case '_':			/* _ = turn on tractor beam */
+    case '^':			/* ^ = turn on pressor beam */
+	if (me->p_flags & (PFTRACT | PFPRESS)) {
+	    sendTractorReq(0, me->p_no);
+	    if (key == 'T' || key == 'y')
+		break;
+	}
+	target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
+	me->p_tractor = target->o_num;
+	if (key == 'T' || key == '_') {
+	    sendTractorReq(1, target->o_num);
+	} else {
+	    sendRepressReq(1, target->o_num);
+	}
+	break;
+    case '$':			/* turn off tractor/pressor beam */
+	sendTractorReq(0, me->p_no);
+	break;
+    case 'o':			/* o = dock at nearby starbase or orbit
+				   nearest planet */
+#ifdef AUTOKEY
+	if (autoKey && !(localflags & PFREFIT))
+	    autoKeyOrbitReqOn();
+	else
+	    sendOrbitReq(1);
+#else
+	sendOrbitReq(1);
+#endif				/* AUTOKEY */
+	break;
+    case 'O':			/* O = options Window */
+	if (optionWin != NULL && W_IsMapped(optionWin))
+	    optiondone();
+	else
+	    optionwindow();
+	break;
+    case 'Q':
+	sendQuitReq();
+	break;
+    case 'q':			/* fastquit */
+	fastQuit = 1;
+	sendQuitReq();
+	break;
+    case 'V':
+	{
+	    /* configurable showlocal rotation sequence [BDyess] */
+	    int     i, len = strlen(showLocalSequence);
+	    for (i = 0; i < len; i++) {
+		if (showLocalSequence[i] - '0' == showlocal) {
+		    showlocal = showLocalSequence[(i + 1) % len] - '0';
+		    break;
+		}
+	    }
+	    if (i == len)
+		showlocal = (*showLocalSequence) - '0';
+	    if (showlocal > 4)
+		showlocal = 4;
+	    else if (showlocal < 0)
+		showlocal = 0;
+	}
+	if (optionWin)
+	    optionredrawoption(&showlocal);
+	break;
+    case 'B':
+	{
+	    /* configurable showgalactic rotation sequence [BDyess] */
+	    int     i, len = strlen(showGalacticSequence);
+	    for (i = 0; i < len; i++) {
+		if (showGalacticSequence[i] - '0' == showgalactic) {
+		    showgalactic = showGalacticSequence[(i + 1) % len] - '0';
+		    break;
+		}
+	    }
+	    if (i == len)
+		showgalactic = (*showGalacticSequence) - '0';
+	    if (!paradise && showgalactic == 3)
+		showgalactic = 5;	/* force scout ages -> MOO */
+	    if (showgalactic > 5)
+		showgalactic = 5;
+	    else if (showgalactic < 0)
+		showgalactic = 0;
+	}
+	redrawall = 1;
+	if (optionWin)
+	    optionredrawoption(&showgalactic);
+	break;
+    case '?':			/* ? = Redisplay all message windows */
+	if (!W_IsMapped(messWin[WREVIEW].window)) {
+	    if (W_IsMapped(messWin[WALL].window)) {
+		int     i;
+		for (i = 0; i < WNUM; i++) {
+		    if (W_IsMapped(messWin[i].window))
+			W_UnmapWindow(messWin[i].window);
+		}
+	    } else {
+		W_MapWindow(messWin[WREVIEW].window);
+	    }
+	} else {
+	    W_UnmapWindow(messWin[WREVIEW].window);
+	    W_MapWindow(messWin[WALL].window);
+	    W_MapWindow(messWin[WTEAM].window);
+	    W_MapWindow(messWin[WINDIV].window);
+	    W_MapWindow(messWin[WKILL].window);
+	    W_MapWindow(messWin[WPHASER].window);
+	}
+	if (optionWin) {
+	    optionredrawtarget(messWin[WREVIEW].window);
+	    optionredrawtarget(messWin[WALL].window);
+	    optionredrawtarget(messWin[WKILL].window);
+	    optionredrawtarget(messWin[WTEAM].window);
+	    optionredrawtarget(messWin[WINDIV].window);
+	    optionredrawtarget(messWin[WPHASER].window);
+	}
+	break;
+    case 'c':			/* c = cloak */
+	cloak();
+	break;
+    case '{':			/* { = cloak, no toggle */
+	sendCloakReq(1);
+	break;
+    case '}':			/* } = uncloak, no toggle */
+	sendCloakReq(0);
+	break;
+    case 'C':			/* C = coups */
+	sendCoupReq();
+	break;
+    case ';':			/* ; = lock onto planet/base */
+	target = gettarget(data->Window, data->x, data->y,
+			   TARG_BASE | TARG_PLANET);
+	if (target->o_type == PLAYERTYPE) {
+	    sendPlaylockReq(target->o_num);	/* a base */
+	    me->p_playerl = target->o_num;
+	} else {		/* It's a planet */
+	    sendPlanlockReq(target->o_num);
+	    me->p_planet = target->o_num;
+	}
+	break;
+    case 'l':			/* l = lock onto */
+	target = gettarget(data->Window, data->x, data->y,
+			   TARG_PLAYER | TARG_ASTRAL);
+	if (target->o_type == PLAYERTYPE) {
+	    sendPlaylockReq(target->o_num);
+	    me->p_playerl = target->o_num;
+	} else {		/* It's a planet */
+	    sendPlanlockReq(target->o_num);
+	    me->p_planet = target->o_num;
+	}
+	break;
+    case '/':			/* toggle sorted player list */
+	sortPlayers = !sortPlayers;
+	break;
+    case '*':			/* send in practice robot */
+	sendPractrReq();
+	break;
+	/* Start of display functions */
+    case ' ':			/* ' ' = clear special windows */
+	W_UnmapWindow(planetw);
+	W_UnmapWindow(planetw2);
+	W_UnmapWindow(rankw);
+	if (infomapped)
+	    destroyInfo();
+	W_UnmapWindow(helpWin);
+	W_UnmapWindow(war);
+	if (optionWin)
+	    optiondone();
+#ifdef ATM
+	if (scanmapped) {
+	    W_UnmapWindow(scanwin);
+	    scanmapped = 0;
+	}
+	if (udpWin)
+	    udpdone();
+#endif				/* ATM */
+#ifdef XTREKRC_HELP
+	if (defWin)
+	    W_UnmapWindow(defWin);
+#endif
+	break;
+    case 'E':			/* E = send emergency call */
+	if (F_gen_distress)
+	    rcd(generic, data);
+	else
+	    emergency();
+	break;
+    case 'F':			/* F = send carry report */
+	if (F_gen_distress)
+	    rcd(carrying, data);
+	else
+	    carry_report();
+	break;
+    case 'L':			/* L = Player list */
+	if (W_IsMapped(playerw)) {
+	    W_UnmapWindow(playerw);
+	} else {
+	    W_MapWindow(playerw);
+	}
+	break;
+    case 'P':			/* P = Planet list */
+	if (W_IsMapped(planetw)) {
+	    W_UnmapWindow(planetw);
+	    W_UnmapWindow(planetw2);
+	} else {
+	    W_MapWindow(planetw);
+	    W_MapWindow(planetw2);
+	}
+	break;
+    case 'U':			/* U = Rank list */
+	if (W_IsMapped(rankw)) {
+	    W_UnmapWindow(rankw);
+	} else {
+	    W_MapWindow(rankw);
+	}
+	break;
+    case 'S':			/* S = toggle stat mode */
+	if (W_IsMapped(statwin)) {
+	    W_UnmapWindow(statwin);
+	} else {
+	    W_MapWindow(statwin);
+	}
+	break;
+#ifdef nodef			/* people hit this by accident and think the
+				   client crashed */
+    case 'M':			/* M = Toggle Map mode */
+	mapmode = !mapmode;
+	if (optionWin)
+	    optionredrawoption(&mapmode);
+	break;
+#endif
+    case 'M':			/* map the motd window */
+	showMotdWin();
+	break;
+    case 'N':			/* N = Toggle Name mode */
+	namemode = !namemode;
+	if (optionWin)
+	    optionredrawoption(&namemode);
+	break;
+    case 'i':			/* i = get information */
+    case 'I':			/* I = get extended information */
+    case control('i'):		/* ^i = info on a planet [BDyess] */
+	if (!infomapped)
+	    inform(data->Window, data->x, data->y, key);
+	else
+	    destroyInfo();
+	break;
+    case 'h':			/* h = Map help window */
+	if (W_IsMapped(helpWin)) {
+	    W_UnmapWindow(helpWin);
+	} else {
+	    W_MapWindow(helpWin);
+	}
+	if (optionWin)
+	    optionredrawtarget(helpWin);
+	break;
+    case 'w':			/* w = map war stuff */
+	if (W_IsMapped(war))
+	    W_UnmapWindow(war);
+	else
+	    warwindow();
+	break;
+#ifdef ATM
+    case '+':			/* UDP: pop up UDP control window */
+	if (udpWin != NULL && W_IsMapped(udpWin))
+	    udpdone();
+	else {
+	    char    buf[80];
+	    udpwindow();
+	    sprintf(buf, "UDP client version %.1f",
+		    (float) UDPVERSION / 10.0);
+	    warning(buf);
+	}
+	if (optionWin)
+	    optionredrawtarget(udpWin);
+	break;
+    case '=':			/* UDP: request for full update */
+	sendUdpReq(COMM_UPDATE);
+	break;
+#endif				/* ATM */
+
+    case 9:			/* tab */
+    case control('m'):		/* because you can't remap to tab */
+	                        /* actually, you can, put a literal
+				   TAB in a ckeymap entry and it works.
+				   So should we keep this? -JR */
+	if(paradise) {
+	    blk_zoom = !blk_zoom;
+	    redrawall = 1;
+	    auto_zoom_timer = udcounter+autoZoomOverride;
+	    if (optionWin)
+		optionredrawoption(&blk_zoom);
+	}
+	break;
+#ifdef SHORT_PACKETS
+    case '~':
+	if (spWin != NULL && W_IsMapped(spWin))
+	    spdone();
+	else
+	    spwindow();
+	if (optionWin)
+	    optionredrawtarget(spWin);
+	break;
+    case '\\':
+	sendShortReq(SPK_SALL);
+	break;
+    case '|':
+	sendShortReq(SPK_ALL);
+	break;
+#endif
+    case ',':
+	if (W_IsMapped(pStats)) {
+	    W_UnmapWindow(pStats);
+	} else {
+	    W_MapWindow(pStats);
+	    redrawPStats();
+	}
+	if (optionWin)
+	    optionredrawtarget(pStats);
+	break;
+    case '&':			/* reread defaults file */
+	if (defaultsFile) {
+	    char    buf[150];
+	    sprintf(buf, "Reading defaults from %s", defaultsFile);
+	    warning(buf);
+	    freeDefaults();
+	    defaultsFile = initDefaults(defaultsFile);
+	    resetDefaults();
+	} else {
+	    warning("No defaults file to read from!");
+	}
+	break;
+#ifdef ROTATERACE
+    case '(':
+	rotate--;
+	if (rotate < 0)
+	    rotate = 3;
+	if (optionWin)
+	    optionredrawoption(&rotate);
+	rotate_all();
+	break;
+    case ')':
+	rotate++;
+	if (rotate > 3)
+	    rotate = 0;
+	if (optionWin)
+	    optionredrawoption(&rotate);
+	rotate_all();
+	break;
+#endif
+
+#ifdef RECORDER
+    case control('r'):
+	stopRecorder();
+	break;
+#endif
+
+#ifdef SOUND
+    case control('s'):
+	S_SoundWindow();
+	break;
+#endif
+#ifdef TOOLS
+    case '\"':
+	showToolsWin();
+	break;
+#endif
+#ifdef AMIGA
+    case 'A':
+	{
+	    extern int flush_speech;
+	    flush_speech = 1;
+	    break;
+	}
+#endif				/* AMIGA */
+    default:
+	W_Beep();
+	break;
+    }
+}
+
+static void
+buttonaction(data)
+    W_Event *data;
+{
+    unsigned char course;
+
+#ifdef NOWARP
+    if (messageon)
+	message_off();		/* ATM */
+#endif
+
+    if (data->Window != w && data->Window != mapw
+#ifdef ATM
+	&& data->Window != scanwin
+#endif				/* ATM */
+	)
+	return;
+
+    data->key--;
+    if (data->key >= 0 && data->key < 12) {
+	if (myship->s_buttonmap[data->key] != '\0') {
+	    data->key = myship->s_buttonmap[data->key];
+#if 0				/* do NOT bypass keymap */
+	    data->key += 256;	/* simulate alt key so keymap is bypassed
+				   [BDyess] */
+#endif
+	    keyaction(data);
+	    return;
+	} else
+	    data->key = data->key % 3;
+	/* if alt key is pressed, do default */
+    } if (data->key > 11)
+	data->key -= 12;
+    data->key++;
+    if (data->key == W_RBUTTON) {
+	course = getcourse(data->Window, data->x, data->y);
+	set_course(course);
+    } else if (data->key == W_LBUTTON) {
+	course = getcourse(data->Window, data->x, data->y);
+	sendTorpReq(course);
+    } else if (data->key == W_MBUTTON) {
+	course = getcourse(data->Window, data->x, data->y);
+	sendPhaserReq(course);
+    }
+}
+
+/*
+ * changed from unsigned char to irint() for precise rounding (from Leonard
+ * Dickens)
+ *
+ *  changed from irint (which ULTRIX doesn't have in its math.h header) to
+ * floor(x+0.5) for portability.
+ */
+
+
+
+int
+getcourse(ww, x, y)
+    W_Window ww;
+    int     x, y;
+{
+    if (ww == mapw) {
+	int     me_x, me_y;
+	register gwidth, offsetx, offsety;
+
+	if (blk_zoom) {
+	    gwidth = blk_gwidth / 2;
+	    offsetx = zoom_offset(me->p_x);
+	    offsety = zoom_offset(me->p_y);
+	} else {
+	    gwidth = blk_gwidth;
+	    offsetx = 0;
+	    offsety = 0;
+	}
+	me_x = (me->p_x - offsetx) * WINSIDE / gwidth;
+	me_y = (me->p_y - offsety) * WINSIDE / gwidth;
+
+	return (unsigned char)(int)
+	  floor(0.5 + atan2((double) (x - me_x),
+			    (double) (me_y - y))
+		         / 3.14159 * 128.);
+
+
+    } else {
+
+      double	result = atan2((double) (x - WINSIDE / 2),
+			       (double) (WINSIDE / 2 - y)) / 3.14159 * 128.;
+
+      return (unsigned char) (int) floor (result + 0.5);
+    }
+}
+#ifdef ATM
+static void
+scan(w, x, y)
+    W_Window w;
+    int     x, y;
+{
+}
+#endif				/* ATM */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/interface.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,122 @@
+/* $Id: interface.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * interface.c
+ *
+ * This file will include all the interfaces between the input routines
+ *  and the daemon.  They should be useful for writing robots and the
+ *  like
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#ifndef sgi
+#include <sys/timeb.h>
+#endif				/* sgi */
+#include <signal.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+
+void
+set_speed(speed)
+    int     speed;
+{
+    /* don't repeat useless commands [BDyess] */
+    if (me->p_desspeed != speed || me->p_speed != speed)
+	sendSpeedReq(speed);
+    me->p_desspeed = speed;
+}
+
+void
+set_course(dir)
+    unsigned int dir;
+{
+    /* don't repeat commands [BDyess] */
+    if (me->p_desdir != dir || me->p_dir != dir)
+	sendDirReq(dir);
+    me->p_desdir = dir;
+}
+
+void
+shield_up()
+{
+    if (!(me->p_flags & PFSHIELD)) {
+	sendShieldReq(1);
+    }
+}
+
+void
+shield_down()
+{
+    if (me->p_flags & PFSHIELD) {
+	sendShieldReq(0);
+    }
+}
+
+void
+shield_tog()
+{
+    if (me->p_flags & PFSHIELD) {
+	sendShieldReq(0);
+    } else {
+	sendShieldReq(1);
+    }
+}
+
+void
+bomb_planet()
+{
+    if (!(me->p_flags & PFBOMB)) {
+	sendBombReq(1);
+    }
+}
+
+void
+beam_up()
+{
+    if (!(me->p_flags & PFBEAMUP)) {
+	sendBeamReq(1);		/* 1 means up... */
+    }
+}
+
+void
+beam_down()
+{
+    if (!(me->p_flags & PFBEAMDOWN)) {
+	sendBeamReq(2);		/* 2 means down... */
+    }
+}
+
+void
+cloak()
+{
+    if (me->p_flags & PFCLOAK) {
+	sendCloakReq(0);
+    } else {
+	sendCloakReq(1);
+    }
+}
+
+int
+mtime()
+{
+#if 0
+    struct timeb tm;
+
+    ftime(&tm);
+    /* mask off 16 high bits and add in milliseconds */
+    return (tm.time & 0x0000ffff) * 1000 + tm.millitm;
+#else
+    struct timeval tv;
+
+    gettimeofday(&tv, (struct timezone *) 0);
+    return (tv.tv_sec & 0x0ffff) * 1000 + tv.tv_usec / 1000;
+#endif
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/keymap.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,240 @@
+/* $Id: keymap.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * keymap.c
+ * Bill Dyess, 10/20/93
+ */
+
+#include "copyright.h"
+#include <stdio.h>
+/*#include <sys/types.h>
+#ifdef RS6K
+#include <sys/select.h>
+#endif
+#include <signal.h>
+#include <errno.h>
+#include "packets.h"*/
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+#define control(x) (x)+128
+
+int
+doKeymap(data)
+    W_Event *data;
+{
+    int     key = data->key;
+
+#ifdef MACROS
+    if (macroState) {		/* macro needed a destination or in macro
+				   mode */
+	if (key > 256 && data->type != W_EV_BUTTON) {	/* an alt-key will exit
+							   the macro mode */
+	    /*
+	       but let mouse buttons do macros! button conversion is done by
+	       calling function.
+	    */
+	    warning("             ");
+	} else {
+	    if (key > 256)
+		data->key -= 256;
+	    doMacro(data);
+	    return -1;
+	}
+    }
+#endif				/* MACROS */
+
+    if (key < 256) {		/* not alt key */
+	key = myship->s_keymap[key];
+
+#ifdef MACROS
+	if (macrotable[key] && (macrotable[key]->flags & MACSINGLE)) {
+	    data->key = key;
+	    doMacro(data);
+	    return -1;
+	}
+#endif				/* MACROS */
+
+    } else
+	key = key - 256;
+    return key;
+}
+
+unsigned char def_keymap[256];
+unsigned char def_buttonmap[12];
+void
+buildShipKeymap(shipp)
+    struct ship *shipp;
+{
+    char    keybuf[40], ckeybuf[40], buttonbuf[40], cbuttonbuf[40];
+    struct stringlist *l;
+
+    bcopy(def_keymap, shipp->s_keymap, 256);
+    bcopy(def_buttonmap, shipp->s_buttonmap, 12);
+
+    sprintf(keybuf, "keymap.%c%c", shipp->s_desig[0], shipp->s_desig[1]);
+    sprintf(ckeybuf, "ckeymap.%c%c", shipp->s_desig[0], shipp->s_desig[1]);
+    sprintf(buttonbuf, "buttonmap.%c%c", shipp->s_desig[0], shipp->s_desig[1]);
+    sprintf(cbuttonbuf, "cbuttonmap.%c%c", shipp->s_desig[0], shipp->s_desig[1]);
+
+    for (l = defaults; l; l = l->next) {
+	if (!strcmpi(keybuf, l->string))
+	    keymapAdd(l->value, shipp->s_keymap);
+	else if (!strcmpi(ckeybuf, l->string))
+	    ckeymapAdd(l->value, shipp->s_keymap);
+	else if (!strcmpi(buttonbuf, l->string))
+	    buttonmapAdd(l->value, shipp->s_buttonmap);
+	else if (!strcmpi(cbuttonbuf, l->string))
+	    cbuttonmapAdd(l->value, shipp->s_buttonmap);
+    }
+}
+
+void
+initkeymap(type)
+    int     type;
+{
+    char    keybuf[40], ckeybuf[40], buttonbuf[40], cbuttonbuf[40];
+    struct ship *sh;
+    int     i, j;
+    struct stringlist *l;
+
+    keybuf[0] = ckeybuf[0] = buttonbuf[0] = cbuttonbuf[0] = 0;
+
+    if (type < 0) {
+	for (i = 0; i < 256; i++)
+	    def_keymap[i] = i;
+
+	for (l = defaults; l; l = l->next) {
+	    if (!strcmpi("keymap", l->string))
+		keymapAdd(l->value, def_keymap);
+	    else if (!strcmpi("ckeymap", l->string))
+		ckeymapAdd(l->value, def_keymap);
+	    else if (!strcmpi("buttonmap", l->string))
+		buttonmapAdd(l->value, def_buttonmap);
+	    else if (!strcmpi("cbuttonmap", l->string))
+		cbuttonmapAdd(l->value, def_buttonmap);
+	}
+
+	for (j = 0; j < nshiptypes; j++) {
+	    buildShipKeymap(getship(j));
+	}
+    }
+}
+
+void
+keymapAdd(str, map)
+    char   *str, *map;
+{
+    if (str) {
+	/* parse non-control char keymap */
+	while (*str != '\0' && *(str + 1) != '\0') {
+	    if (*str >= 32 && *str < 127) {
+		map[(int) *str] = *(str + 1);
+	    }
+	    str += 2;
+	}
+    }
+}
+
+void
+ckeymapAdd(cstr, map)
+    char   *cstr, *map;
+{
+    unsigned char key[2];
+    short   state = 0;
+
+    if (cstr) {
+	/*
+	   control chars are allowed, so use ^char to mean control, and ^^ to
+	   mean ^
+	*/
+	while (*cstr != '\0') {
+	    if (*cstr == '^') {
+		cstr++;
+		if (*cstr == '^' || !*cstr)
+		    key[state] = '^';
+		else
+		    key[state] = 128 + *cstr;
+	    } else {
+		key[state] = *cstr;
+	    }
+	    if (*cstr)
+		cstr++;
+	    if (state)
+		map[key[0]] = key[1];
+	    state = 1 - state;
+	}
+    }
+}
+
+void
+buttonmapAdd(str, map)
+    char   *str, *map;
+{
+    unsigned char button, ch;
+
+    if (str) {
+	while (*str != '\0' && *(str + 1) != '\0') {
+	    if (*str < 'a')
+		button = *str++ - '1';
+	    else
+		button = 9 + *str++ - 'a';
+	    if (button > 11)
+		fprintf(stderr, "%c ignored in buttonmap\n", *(str - 1));
+	    else {
+		ch = *str++;
+		map[button] = ch;
+	    }
+	}
+    }
+}
+
+void
+cbuttonmapAdd(cstr, map)
+    char   *cstr, *map;
+{
+    unsigned char button, ch;
+
+    if (cstr) {
+	while (*cstr != '\0' && *(cstr + 1) != '\0') {
+	    /*
+	       code for cbuttonmap, which allows buttons to be mapped to
+	       control keys. [BDyess]
+	    */
+	    if (*cstr < 'a')
+		button = *cstr++ - '1';
+	    else
+		button = 9 + *cstr++ - 'a';
+	    if (button > 11)
+		fprintf(stderr, "%c ignored in cbuttonmap\n", *(cstr - 1));
+	    else {
+		ch = *cstr++;
+		if (ch == '^') {
+		    ch = *cstr++;
+		    if (ch != '^')
+			ch += 128;
+		}
+		map[button] = ch;
+	    }
+	}
+    }
+}
+
+#ifdef KEYMAP_DEBUG
+void
+dumpKeymap()
+{
+    int     i;
+
+    for (i = 0; i < 256; i++) {
+	printf("%3d %c : %3d %c\n",
+	       i,
+	       isprint(i) ? i : '_',
+	       myship->s_keymap[i],
+	       isprint(myship->s_keymap[i]) ? myship->s_keymap[i] : '_');
+    }
+}
+#endif				/* KEYMAP_DEBUG */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/macros.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1032 @@
+/* $Id: macros.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/* here's pretty much all the macro code.   */
+/* This bears little resemblance to the     */
+/* BRM code, i.e. it's somewhat organized :)*/
+/* Bill Dyess  10/05/93	            [BDyess]*/
+
+#ifdef MACROS
+#include"copyright.h"
+#include<stdio.h>
+#if !defined(SVR4) && !defined(sparc)
+#include<strings.h>
+#else
+#include<string.h>
+#endif				/* !SVR4 && !sparc */
+#include<ctype.h>
+#include<fcntl.h>
+#include<sys/types.h>
+#include"Wlib.h"
+#include"data.h"
+#include"defs.h"
+#include"struct.h"
+#include"gameconf.h"
+#include"proto.h"
+
+#define MAXMACRO 4096
+#if defined(__STDC__) || defined(RS6K) || defined(sgi)
+typedef signed char s_char;
+#else
+typedef char s_char;
+#endif
+ 
+/* prototypes */
+void doMacro2 P((struct macro * m, W_Event * data));
+void handle_dollar P((char **locpntr, char **destpntr, W_Event * data));
+void handle_special P((char **locpntr, char **destpntr, W_Event * data));
+char   *strtoupper P((char *buf));
+char   *strtolower P((char *buf));
+void handle_test P((char **locpntr, char **destpntr, W_Event * data));
+void handle_conditional P((char **locpntr, char **destpntr, W_Event * data));
+void getTestString P((char *buf, char **locpntr, char **destpntr, W_Event * data));
+void getConditionalString P((char **locpntr, char **destpntr, W_Event * data));
+void ignoreConditionalString P((char **locpntr));
+
+int     abortflag = 0;
+
+void
+initMacros()
+{
+    struct stringlist *s;
+    char   *loc;
+    unsigned char ch;
+    struct macro *m;
+    int     i;
+    struct dmacro_list *dm;
+    struct dmacro_list *dm_def;
+    int     notdone;
+    unsigned char	c;
+    char  *str;
+
+    /* initialize macro lookup tables */
+    bzero(macrotable, sizeof(struct macro *) * 256);
+
+#ifdef RC_DISTRESS
+    /* sizeof doesn't work if it isn't in the same source file, shoot me */
+    MCOPY(dist_defaults, dist_prefered, sizedist);
+#endif
+
+    for (s = defaults; s; s = s->next) {
+#ifdef RC_DISTRESS
+	if (strncmpi(s->string, "dist.", 5) == 0) {
+	    str = (s->string) + 5;
+	    if (*str == '^') {
+		str++;
+		if (*str == '^')
+		    c = '^';
+		else
+		    c = *str + 128;
+	    } else
+		c = *str;
+	    str++;
+	    if (*str != '.') {
+		str = (s->string) + 4;
+		c = '\0';
+	    }
+	    str++;
+
+	    notdone = 1;
+	    for (dm = &dist_prefered[take], dm_def = &dist_defaults[take], i = take;
+		 dm->name && notdone; dm++, dm_def++, i++) {
+		if (strcmpi(str, dm->name) == 0) {
+		    dm->macro = strdup(s->value);
+		    if (c) {
+			if (!macrotable[c]) {
+			    macrotable[c] = (struct macro *) malloc(sizeof(struct macro));
+			    bzero(macrotable[c], sizeof(struct macro));
+			}
+			macrotable[c]->flags |= MACRCD;
+			macrotable[c]->to = i;
+/*                        printf("dist.%c.%s: %s\n",c,dm->name,dm->macro);*/
+			dm->c = c;
+			dm_def->c = c;
+		    }
+		    notdone = 0;
+		}
+	    }
+	}
+#endif				/* RC_DISTRESS */
+#ifdef BEEPLITE
+
+	else if (strncmpi(s->string, "lite.", 5) == 0) {
+	    int     offset = 5;
+	    char  **lt;
+
+	    if (s->string[6] == '.')
+		offset = 7;
+
+	    notdone = 1;
+
+	    for (lt = &distlite[take], dm = &dist_prefered[take];
+		 dm->name && notdone; dm++, lt++) {
+		if (strcmpi(s->string + offset, dm->name) == 0) {
+		    *lt = strdup(s->value);
+/*                    printf("lite.%s: %s\n",dm->name,*lt);*/
+
+		    notdone = 0;
+		}
+	    }
+	    if (notdone)
+		fprintf(stderr, "Unknown lite %s\n", s->string + offset);
+	}
+#endif				/* BEEPLITE */
+	if (!strncmpi("mac", s->string, 3)) {
+	    if (s->string[3] == '.')
+		loc = s->string + 4;
+	    else if (strncmpi("ro.", s->string + 3, 3))
+		continue;
+	    else
+		loc = s->string + 6;
+	    if (*loc == '^') {	/* possible control char */
+		loc++;
+		if (*loc == '^' && *loc)
+		    ch = '^';
+		else
+		    ch = *loc + 128;
+	    } else
+		ch = *loc;
+	    loc++;
+	    if (!macrotable[ch]) {
+		/*
+		   make sure it doesn't already exist.  I've allowed people
+		   to have singlemacro: before the macro.*.* statements, so
+		   it is possible
+		*/
+		/*
+		   modified to allow multline macros by creating a linked
+		   list of macro structures. -JR
+		*/
+		if (ch == '?') {
+		    printf("Can't use '?' as a macro.  It is reserved for the macro window.  Ignoring.\n");
+		    continue;
+		}
+		macrotable[ch] = m = (struct macro *) malloc(sizeof(struct macro));
+		bzero(m, sizeof(struct macro));
+	    } else {
+#ifdef RC_DISTRESS
+		if (macrotable[ch]->flags & MACRCD) {
+		    m = macrotable[ch];
+		    m->flags &= ~(MACRCD);	/* in case singleMacro was
+						   set */
+		    m->next = 0;
+		} else
+#endif
+		{
+		    m = (struct macro *) malloc(sizeof(struct macro));
+		    m->next = macrotable[ch];
+		    macrotable[ch] = m;
+		    m->next->flags |= MACMULTI;
+		    m->flags = m->next->flags;
+		}
+	    }
+	    if (*(loc++) != '.')
+		m->to = -2;	/* no destination given */
+	    else {
+		ch = *loc;
+		if (ch == '%') {
+		    m->specialto = toupper(*(loc + 1));
+		    m->to = -1;
+		} else {
+		    m->to = ch;
+		}
+	    }
+	    m->string = strdup(s->value);
+	} else if (!strncmpi("singlemacro", s->string, 11)) {
+	    loc = s->value;
+	    while (*loc) {
+		ch = *(loc++);
+		if (ch == '^') {/* for control chars */
+		    if (*loc != '^' && *loc)
+			ch = *loc + 128;
+		    loc++;
+		}
+		if (!macrotable[ch]) {
+		    m = macrotable[ch] = (struct macro *) malloc(sizeof(struct macro));
+		    bzero(m, sizeof(struct macro));
+		    m->flags = MACSINGLE;
+		} else {
+		    for (m = macrotable[ch]; m; m = m->next)
+			m->flags |= MACSINGLE;
+		}
+	    }
+	}
+    }
+    for (i = 0; i < 256; i++) {
+	/* eliminate any macros that have (null) macro strings */
+	if (macrotable[i] && !(macrotable[i]->flags & MACRCD)) {
+	    struct macro *tmp, **scan;
+
+	    scan=&macrotable[i];
+	    while (*scan) {
+		if ( (*scan)->string ) {
+		    scan = &(*scan)->next;
+		} else {
+		    tmp = (*scan);
+		    *scan = tmp->next;
+		    free(tmp);
+		}
+	    }
+	    }
+	}
+#ifdef RC_DISTRESS
+    /*
+       make macro entries for the default RCD keys, if those keys don't have
+       macros defined
+    */
+    for (dm = &dist_prefered[take], i = take; dm->name; dm++, i++) {
+	if (!macrotable[dm->c]) {
+	    macrotable[dm->c] = (struct macro *) malloc(sizeof(struct macro));
+	    bzero(macrotable[dm->c], sizeof(struct macro));
+	    macrotable[dm->c]->flags = MACRCD;
+	    macrotable[dm->c]->to = i;
+	}
+    }
+#endif
+}
+
+void
+doMacro(data)
+    W_Event *data;
+/* takes a key as input and creates a string that is then sent to smessage*/
+{
+    static struct macro *m;
+    int     key = data->key;
+
+    if (key == '?') {
+	showMacroWin();
+	macroState = 0;
+	return;
+    }
+    if (macroState != 2)
+	m = macrotable[key];
+    if (!m) {
+	W_Beep();
+	warning("No such macro");
+	macroState = 0;
+	return;			/* no macro */
+    }
+#ifdef RC_DISTRESS
+    if (m->flags & MACRCD) {
+	rcd(m->to, data);
+	macroState = 0;
+	return;
+    }
+#endif
+    while (m) {
+	if (macroState == 2) {
+	    m->to = key;
+	    doMacro2(m, data);
+	    m->to = -2;
+	} else {
+	    doMacro2(m, data);
+	    if (macroState == 2)
+		return;
+	}
+	m = m->next;
+    }
+    macroState = 0;
+    warning("              ");
+}
+
+void
+doMacro2(m, data)
+    struct macro *m;
+    W_Event *data;
+{
+    int     group = -1, recip = 0;
+    char    buf[MAXMACRO], sourcebuf[MAXMACRO];
+    char   *loc, *dest;
+    struct obtype *target;
+
+    /* first figure out who I'm going to send it to */
+    if ((s_char)m->to == -1) {		/* special recipient */
+	switch (m->specialto) {
+	case 'I':		/* send a message to myself */
+	case 'C':
+	    group = MINDIV;
+	    recip = me->p_no;
+	    break;
+	case 'U':		/* send message to player nearest mouse */
+	case 'P':
+	    group = MINDIV;
+	    target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
+	    recip = target->o_num;
+	    break;
+	case 'T':		/* send message to team of the player nearest
+				   mouse */
+	case 'Z':
+	    group = MTEAM;
+	    target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
+	    recip = idx_to_mask(players[target->o_num].p_teami);
+	    break;
+	case 'G':		/* send message to nearest friendly player to
+				   my ship */
+	    group = MINDIV;
+	    target = gettarget((W_Window) 0, me->p_x, me->p_y,
+			       TARG_PLAYER | TARG_FRIENDLY);
+	    recip = target->o_num;
+	    break;
+	case 'H':		/* send message to nearest enemy player to my
+				   ship */
+	    group = MINDIV;
+	    target = gettarget((W_Window) 0, me->p_x, me->p_y,
+			       TARG_PLAYER | TARG_ENEMY);
+	    recip = target->o_num;
+	    break;
+	default:
+	    warning("Bad macro - incorrect 'to' field");
+	    break;
+	}
+    } else if ((s_char)m->to == -2) {	/* get recipient not provided, so change
+				   state to get one */
+	macroState = 2;
+	warning("Send macro to who?");
+	return;
+    } else
+	recip = m->to;
+    /* now parse the macro itself. */
+    strcpy(sourcebuf, m->string);
+    loc = sourcebuf;
+    dest = buf;
+    while (*loc) {
+	if (*loc == '$') {
+	    loc++;
+	    handle_dollar(&loc, &dest, data);	/* handle the special escape */
+	} else if (*loc == '%') {
+	    loc++;
+	    if (*loc == '*')
+		return;		/* %* means exit macro NOW */
+	    handle_special(&loc, &dest, data);	/* handle the special escape */
+	} else {
+	    *(dest++) = *(loc++);
+	}
+    }
+    *dest = 0;
+    if (buf[0] == 0 || abortflag) {	/* abortflag means somewhere there
+					   was a %* */
+	abortflag = 0;
+	macroState = 0;
+	return;			/* null message.  If you *really* want to
+				   print a null message, use <space> */
+    }
+    if (group == -1)
+	group = getgroup(recip, &recip);
+    if (group <= 0)
+	return;
+    if ((m->flags & MACMULTI) && (F_multiline_enabled || paradise))
+	group |= MMACRO;
+    pmessage(buf, recip, group);
+}
+
+void
+handle_special(locpntr, destpntr, data)
+    char  **locpntr, **destpntr;
+    W_Event *data;
+{
+    char    ch = **locpntr;
+    char   *buf = *destpntr;
+    struct obtype *target;
+    struct macro *m;
+    int     targettype = 0;
+    struct id *id;
+    /* for pingstats */
+#if 0
+    extern int ping_iloss_sc;	/* inc % loss 0--100, server to client */
+    extern int ping_iloss_cs;	/* inc % loss 0--100, client to server */
+#endif				/* 0 */
+    extern int ping_tloss_sc;	/* total % loss 0--100, server to client */
+    extern int ping_tloss_cs;	/* total % loss 0--100, client to server */
+#if 0
+    extern int ping_lag;	/* delay in ms of last ping */
+#endif				/* 0 */
+    extern int ping_av;		/* average rt */
+    extern int ping_sd;		/* standard deviation */
+
+    switch (ch) {
+    case 'a':			/* armies carried by sender */
+	sprintf(buf, "%d", me->p_armies);
+	break;
+    case 'd':			/* sender damage percentage */
+	sprintf(buf, "%d", 100 * me->p_damage / me->p_ship->s_maxdamage);
+	break;
+    case 's':			/* sender shield percentage */
+	sprintf(buf, "%d", 100 * me->p_shield / me->p_ship->s_maxshield);
+	break;
+    case 'f':			/* sender fuel percentage */
+	sprintf(buf, "%d", 100 * me->p_fuel / me->p_ship->s_maxfuel);
+	break;
+    case 'w':			/* sender wtemp percentage */
+	sprintf(buf, "%d", 100 * me->p_wtemp / me->p_ship->s_maxwpntemp);
+	break;
+    case 'e':			/* sender etemp percentage */
+	sprintf(buf, "%d", 100 * me->p_etemp / me->p_ship->s_maxegntemp);
+	break;
+    case 'r':			/* team id character of target player */
+	target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
+	buf[0] = teaminfo[players[target->o_num].p_teami].letter;
+	buf[1] = 0;
+	break;
+    case 't':			/* team id character of target planet */
+	target = gettarget(data->Window, data->x, data->y, TARG_PLANET);
+	buf[0] = teaminfo[mask_to_idx(planets[target->o_num].pl_owner)].letter;
+	buf[1] = 0;
+	break;
+    case 'p':			/* id character of target player */
+	targettype = TARG_PLAYER;
+    case 'g':			/* id character of target friendly player */
+	if (!targettype)
+	    targettype = TARG_PLAYER | TARG_FRIENDLY;
+    case 'h':			/* id char of target enemy player */
+	if (!targettype)
+	    targettype = TARG_PLAYER | TARG_ENEMY;
+	id = getTargetID(data->Window, data->x, data->y, targettype);
+	buf[0] = id->mapstring[1];
+	buf[1] = 0;
+	break;
+    case 'P':			/* id character of player nearest sender */
+	id = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER);
+	buf[0] = id->mapstring[1];
+	buf[1] = 0;
+	break;
+    case 'T':			/* team id character of sender team */
+	buf[0] = me->p_mapchars[0];
+	buf[1] = 0;
+	break;
+    case 'c':			/* sender id character */
+	buf[0] = me->p_mapchars[1];
+	buf[1] = 0;
+	break;
+    case 'C':			/* 1 if cloaked, 0 if not [BDyess] */
+	if (me->p_flags & PFCLOAK)
+	    buf[0] = '1';
+	else
+	    buf[0] = '0';
+	buf[1] = 0;
+	break;
+    case 'n':			/* armies on target planet */
+	target = gettarget(data->Window, data->x, data->y, TARG_PLANET);
+	sprintf(buf, "%d", planets[target->o_num].pl_info ?
+		planets[target->o_num].pl_armies :
+		-1);
+	break;
+    case 'E':			/* 1 if etemped, 0 if not */
+	if (me->p_flags & PFENG)
+	    buf[0] = '1';
+	else
+	    buf[0] = '0';
+	buf[1] = 0;
+	break;
+    case 'W':			/* 1 if wtemped, 0 if not */
+	if (me->p_flags & PFWEP)
+	    buf[0] = '1';
+	else
+	    buf[0] = '0';
+	buf[1] = 0;
+	break;
+    case 'S':			/* sender two character ship type */
+	strncpy(buf, me->p_ship->s_desig, 2);
+	buf[2] = 0;
+	break;
+    case 'G':			/* id char of friendly player nearest sender */
+	targettype = TARG_FRIENDLY;
+    case 'H':			/* id char of enemy player nearest sender */
+	if (!targettype)
+	    targettype = TARG_ENEMY;
+	id = getTargetID((W_Window) 0, me->p_x, me->p_y,
+			 TARG_PLAYER | targettype);
+	buf[0] = id->mapstring[1];
+	buf[1] = 0;
+	break;
+    case 'l':			/* three character name of target planet */
+    case 'L':
+	id = getTargetID(data->Window, data->x, data->y, TARG_PLANET);
+	strcpy(buf, id->mapstring);
+	buf[0] = tolower(buf[0]);
+	break;
+    case 'i':			/* sender full player name (16 character max) */
+    case 'I':
+	strncpy(buf, me->p_name, 16);
+	buf[16] = 0;
+	break;
+    case 'u':			/* full name of target player (16 character
+				   max) */
+    case 'U':
+	id = getTargetID(data->Window, data->x, data->y, TARG_PLAYER);
+	strncpy(buf, id->name, 16);
+	buf[16] = 0;
+	break;
+    case 'z':			/* 3 letter team id of target planet */
+    case 'Z':
+	id = getTargetID(data->Window, data->x, data->y, TARG_PLANET);
+	strcpy(buf, teaminfo[id->team].shortname);
+	strtolower(buf);
+	break;
+    case 'b':			/* nearest planet to sender */
+    case 'B':
+	id = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLANET);
+	strcpy(buf, id->mapstring);
+	buf[0] = tolower(buf[0]);
+	break;
+    case 'v':			/* average ping round trip time */
+	sprintf(buf, "%d", ping_av);
+	break;
+    case 'V':			/* ping stdev */
+	sprintf(buf, "%d", ping_sd);
+	break;
+    case 'y':			/* packet loss */
+	sprintf(buf, "%d", (2 * ping_tloss_sc + ping_tloss_cs) / 3);
+	break;
+    case 'm':			/* last message */
+    case 'M':
+	strcpy(buf, lastMessage);
+	break;
+    case 'o':			/* insert three letter team name */
+    case 'O':
+	strcpy(buf, teaminfo[me->p_teami].shortname);
+	break;
+    case ' ':			/* nothing.  This is so you can start a macro
+				   with spaces */
+	buf[0] = ' ';
+	buf[1] = 0;
+	break;
+    case '%':			/* insert % */
+	buf[0] = '%';
+	buf[1] = 0;
+	break;
+    case '?':			/* start test */
+	(*locpntr)++;
+	handle_test(locpntr, destpntr, data);
+	return;
+    case '{':			/* conditional */
+	handle_conditional(locpntr, destpntr, data);
+	return;
+    case '*':			/* abort! */
+	abortflag = 1;
+	return;
+    case '2':			/* is paradise?  sorry, ran out of good
+				   letters. '2' means, 'is Netrek II?'. */
+	buf[0] = paradise + '0';
+	buf[1] = 0;
+	break;
+    case '_':			/* call another macro. Added 1/24/94 [BDyess] */
+	(*locpntr)++;
+	if (**locpntr == '^') {	/* control char */
+	    (*locpntr)++;
+	    m = macrotable[**locpntr + (**locpntr == '^') ? 0 : 128];
+	} else {
+	    m = macrotable[(int) **locpntr];
+	}
+	if (m) {		/* does the macro exist? */
+	    char    temp[MAXMACRO];
+	    strcpy(temp, m->string);
+	    strcat(temp, *locpntr + 1);
+	    strcpy(*locpntr + 1, temp);
+	} else {		/* somebody screwed up */
+	    printf("Error: called macro ");
+	    if (&m - macrotable >= 128)
+		putchar('^');
+	    printf("%c doesn't exist.\n", **locpntr);
+	}
+	buf[0] = 0;
+	break;
+    default:
+	sprintf(buf, "Unknown %% escape: %%%c", ch);
+	warning(buf);
+	buf[0] = 0;
+	break;
+    }
+    if (isupper(ch))
+	strtoupper(buf);
+    (*locpntr)++;
+    while (**destpntr)
+	(*destpntr)++;
+    return;
+}
+
+void
+handle_test(locpntr, destpntr, data)
+    char  **locpntr, **destpntr;
+    W_Event *data;
+{
+    char    l[MAXMACRO], r[MAXMACRO], condition = 0;
+    short   trueflag = 0;
+
+    getTestString(l, locpntr, destpntr, data);
+    if (**locpntr != '%') {
+	condition = *((*locpntr)++);
+	getTestString(r, locpntr, destpntr, data);
+    }
+    switch (condition) {
+    case '=':
+	if (!strcmp(l, r))
+	    trueflag = 1;
+	break;
+    case '>':
+	if (atoi(l) > atoi(r))
+	    trueflag = 1;
+	break;
+    case '<':
+	if (atoi(l) < atoi(r))
+	    trueflag = 1;
+	break;
+    default:
+	if (atoi(l))
+	    trueflag = 1;
+    }
+    **destpntr = '0' + trueflag;
+    *(*destpntr + 1) = 0;
+    (*destpntr)++;
+    return;
+}
+
+void
+handle_conditional(locpntr, destpntr, data)
+    char  **locpntr, **destpntr;
+    W_Event *data;
+{
+    (*locpntr)++;
+    **destpntr = 0;
+    (*destpntr)--;
+    if (**destpntr == '0') {
+	ignoreConditionalString(locpntr);
+	getConditionalString(locpntr, destpntr, data);
+    } else {
+	getConditionalString(locpntr, destpntr, data);
+	ignoreConditionalString(locpntr);
+    }
+    (*locpntr) += 2;
+    while (**destpntr)
+	(*destpntr)++;
+    return;
+}
+
+void
+ignoreConditionalString(locpntr)
+    char  **locpntr;
+{
+    int     depth = 0, breakflag = 0;
+
+    while (**locpntr) {
+	if (**locpntr == '%') {
+	    switch (*(*locpntr + 1)) {
+	    case '!':
+		if (!depth)
+		    breakflag = 1;
+		(*locpntr) += 2;
+		break;
+	    case '}':
+		if (depth) {
+		    depth--;
+		    (*locpntr) += 2;
+		} else
+		    breakflag = 1;
+		break;
+	    case '{':
+		depth++;
+		(*locpntr) += 2;
+		break;
+	    case '*':
+		abortflag = 1;
+		return;
+	    default:
+		(*locpntr)++;
+	    }
+	    if (breakflag)
+		break;
+	} else
+	    (*locpntr)++;
+    }
+}
+
+void
+getConditionalString(locpntr, destpntr, data)
+    char  **locpntr, **destpntr;
+    W_Event *data;
+{
+    char   *dest = *destpntr;
+
+    while (**locpntr) {
+	if (**locpntr != '%' && **locpntr != '$' && **locpntr)
+	    *(dest++) = *((*locpntr)++);
+	else if (*(*locpntr + 1) == '!') {
+	    (*locpntr) += 2;
+	    break;
+	} else if (*(*locpntr + 1) == '}')
+	    break;
+	else if (**locpntr == '%') {
+	    (*locpntr)++;
+	    handle_special(locpntr, &dest, data);
+	    while (*(dest++));
+	    dest--;
+	} else {		/* **locpntr must equal '$' */
+	    (*locpntr)++;
+	    handle_dollar(locpntr, &dest, data);
+	    while (*(dest++));
+	    dest--;
+	}
+    }
+    *dest = 0;
+    return;
+}
+
+void
+getTestString(buf, locpntr, destpntr, data)
+    char   *buf, **locpntr, **destpntr;
+    W_Event *data;
+{
+    char   *dest = buf;
+
+    if (**locpntr == '%') {
+	(*locpntr)++;
+	handle_special(locpntr, &buf, data);
+    } else if (**locpntr == '$') {
+	(*locpntr)++;
+	handle_dollar(locpntr, &buf, data);
+    } else {
+	while (**locpntr != '%' && **locpntr != '$' && **locpntr != '<' &&
+	       **locpntr != '>' && **locpntr != '=' &&
+	       **locpntr)
+	    *(dest++) = *((*locpntr)++);
+	*dest = 0;
+    }
+    return;
+}
+
+char   *
+strtoupper(buf)
+    char   *buf;
+{
+    char   *s;
+    for (s = buf; *s; s++)
+	*s = toupper(*s);
+    return buf;
+}
+
+char   *
+strtolower(buf)
+    char   *buf;
+{
+    char   *s;
+    for (s = buf; *s; s++)
+	*s = tolower(*s);
+    return buf;
+}
+
+/**********************************************************************/
+
+/*
+   start with a $
+
+   field 1:
+   (n)earest
+   (t)arget
+   (s)elf	(doesn't have fields 2 and 3)
+   (_) ego	(has no other fields)
+
+   field 2:
+   (a)ny
+   (t)eammate
+   (f)riendly
+   (h)ostile
+
+   field 3:
+   (a)ny
+   (u)ser
+   (p)lanet (includes asteroids)
+   (s)tar
+   (n)ebula
+   (b)lack hole
+   (^) non-planet
+   (*) any stellar object
+
+   field 4: (optional)		NYI
+   (U)ppercase
+   (C)apitalize
+   (L)owercase
+
+   field 5:
+   full (n)ame (Hammor, Thought)
+   (i)dentifier (e.g. R5, Ka, Can, Sco)
+   (#) number (0-9a-z for players, %d for planets)
+   (t)eam name (Romulan)
+   (s)hort team id (ROM)
+   (l)etter of team (R)
+   (a)rmies
+   (@) sector
+   (A)rable, 0=not arable, 1=arable but not AGRI, 2=AGRI
+   (M)etal, 0, 1, 2(repair), or 3(sy)
+   (D)ilithium, 0, 1 or 2(fuel)
+
+   Any implementation of the paradise $ codes (subset or superset)
+   must implement and document the $_ code.      -- Robert Forsman
+*/
+
+void
+handle_dollar(locpntr, destpntr, data)
+    char  **locpntr, **destpntr;
+    W_Event *data;
+{
+    char   *buf = *destpntr;
+    struct id *target;
+    char    ch = *((*locpntr)++);
+    W_Window w;
+    int     x, y;
+    int     flags;
+    int     capitalize = 0;
+
+    buf[0] = 0;
+
+    if (ch == '_') {
+	strcpy(buf, "Paradise netrek $ codes are orthogonal and make sense.");
+	while (**destpntr)
+	    (*destpntr)++;
+	return;
+    } if (ch == 's') {
+	target = getTargetID((W_Window) 0, me->p_x, me->p_y, TARG_PLAYER | TARG_SELF);
+    } else {
+	switch (tolower(ch)) {
+	case 'n':
+	    w = 0;
+	    x = me->p_x;
+	    y = me->p_y;
+	    break;
+	case 't':
+	    w = data->Window;
+	    x = data->x;
+	    y = data->y;
+	    break;
+	default:
+	    printf("Invalid $ code field 1 : `%c'\n", ch);
+	    return;
+	}
+
+	ch = *((*locpntr)++);
+	switch (tolower(ch)) {
+	case 'a':
+	    flags = 0;
+	    break;
+	case 't':
+	    flags = TARG_TEAM;
+	    break;
+	case 'f':
+	    flags = TARG_FRIENDLY;
+	    break;
+	case 'h':
+	    flags = TARG_ENEMY;
+	    break;
+	default:
+	    printf("Invalid $ code field 2 : `%c'\n", ch);
+	    return;
+	}
+
+	ch = *((*locpntr)++);
+	switch (tolower(ch)) {
+	case 'a':
+	    flags |= TARG_PLAYER | TARG_ASTRAL;
+	    break;
+	case 'u':
+	    flags |= TARG_PLAYER;
+	    break;
+	case 'p':
+	    flags |= TARG_PLANET;
+	    break;
+	case 's':
+	    flags |= TARG_STAR;
+	    break;
+	case 'n':
+	    flags |= TARG_NEBULA;
+	    break;
+	case 'b':
+	    flags |= TARG_BLACKHOLE;
+	    break;
+	case '^':
+	    flags |= (TARG_ASTRAL & ~TARG_PLANET);
+	    /* fall through */
+	case '*':
+	    flags |= TARG_PLANET;
+	    break;
+	default:
+	    printf("Invalid $ code field 3 : `%c'\n", ch);
+	    return;
+	}
+
+	target = getTargetID(w, x, y, flags);
+    }
+
+    ch = tolower(*((*locpntr)++));
+    if (ch == 'l')
+	capitalize = -1;
+    else if (ch == 'c')
+	capitalize = 1;
+    else if (ch == 'u')
+	capitalize = 2;
+    else
+	(*locpntr)--;		/* oops, back up and try again */
+
+    ch = *((*locpntr)++);
+
+    switch (ch) {
+    case 'n':
+	strcpy(buf, target->name);
+	break;
+    case 'i':
+/*    if (target->type == PLANETTYPE) {*/
+	strcpy(buf, target->mapstring);
+/*
+    } else {
+      buf[0] = target->mapstring[1];
+      buf[1] = 0;
+    }*/
+	break;
+    case '#':
+	if (target->type == PLANETTYPE) {
+	    sprintf(buf, "%d", target->number);
+	} else {
+	    buf[0] = target->mapstring[1];
+	    buf[1] = 0;
+	}
+	break;
+    case 't':
+	strcpy(buf, teaminfo[target->team].name);
+	break;
+    case 's':
+	strcpy(buf, teaminfo[target->team].shortname);
+	break;
+    case 'l':
+	buf[0] = teaminfo[target->team].letter;
+	buf[1] = 0;
+	break;
+    case 'a':
+	sprintf(buf, "%d", (target->type == PLANETTYPE) ?
+		planets[target->number].pl_armies :
+		players[target->number].p_armies);
+	break;
+    case '@':
+	if (!paradise)
+	    break;
+	if (target->type == PLANETTYPE) {
+	    x = planets[target->number].pl_x;
+	    y = planets[target->number].pl_y;
+	} else {
+	    x = players[target->number].p_x;
+	    y = players[target->number].p_y;
+	}
+	sprintf(buf, "%d-%d", x / GRIDSIZE + 1, y / GRIDSIZE + 1);
+	break;
+    case 'A':			/* Arable or AGRI */
+	buf[0] = '0';
+	if (target->type == PLANETTYPE) {
+	    if (planets[target->number].pl_flags & PLARABLE)
+		buf[0] = '1';
+	    if (planets[target->number].pl_flags & PLAGRI)
+		buf[0] = '2';
+	}
+	buf[1] = 0;
+	break;
+    case 'M':			/* Metal, Repair, or SY */
+	buf[0] = '0';
+	if (target->type == PLANETTYPE) {
+	    if (planets[target->number].pl_flags & PLMETAL)
+		buf[0] = '1';
+	    if (planets[target->number].pl_flags & PLREPAIR)
+		buf[0] = '2';
+	    if (planets[target->number].pl_flags & PLSHIPYARD)
+		buf[0] = '3';
+	}
+	buf[1] = 0;
+	break;
+    case 'D':			/* Dilythium or Fuel */
+	buf[0] = '0';
+	if (target->type == PLANETTYPE) {
+	    if (planets[target->number].pl_flags & PLDILYTH)
+		buf[0] = '1';
+	    if (planets[target->number].pl_flags & PLFUEL)
+		buf[0] = '2';
+	}
+	buf[1] = 0;
+	break;
+    default:
+	printf("Invalid $ code field 4 : `%c'\n", ch);
+	return;
+    }
+
+    if (capitalize < 0) {
+	char   *s;
+	for (s = buf; *s; s++)
+	    *s = tolower(*s);
+    } else if (capitalize > 1) {
+	char   *s;
+	for (s = buf; *s; s++)
+	    *s = toupper(*s);
+    } else if (capitalize) {
+	char   *s;
+	s = buf;
+	*s = toupper(*s);
+	for (s++; *s; s++)
+	    *s = tolower(*s);
+    }
+    while (**destpntr)
+	(*destpntr)++;
+    return;
+}
+#endif				/* MACROS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/macrowin.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,335 @@
+/* $Id: macrowin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * macrowin.c from helpwin.c
+ * copyright 1993 Nick Trown
+ * copyright 1991 ERic mehlhaff
+ * Free to use, hack, etc. Just keep these credits here.
+ * Use of this code may be dangerous to your health and/or system.
+ * Its use is at your own risk.
+ * I assume no responsibility for damages, real, potential, or imagined,
+ * resulting  from the use of it.
+ * Yeah.....what Eric said...
+ */
+/* Modified for Paradise, 4/94  -JR */
+
+/*#include "config.h"*/
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include <sys/types.h>
+
+#include <time.h>
+/*#include INC_SYS_TIME*/
+/*#include INC_STRINGS*/
+
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+
+
+/*
+   Fills in macro window with the macros defined in the .xtrekrc.
+ */
+
+#define NUMLINES 80
+
+#define MAXMACRO 65
+/* maximum length in characters of key explanation */
+
+#define MACROLEN 255
+/* length of construction string since we don't know how long a macro can be */
+
+
+int     lineno = 0;
+char    maclines[10][MAXMACRO];
+int     maclevel = 0;
+int     macrocnt = 0;		/* a global from COW-lite, only needed here
+				   for Paradise. */
+
+int
+formatline(line)
+    char   *line;
+{
+    register int end;
+    char   *temp;
+    int     num = 0;
+
+    if (!line)
+	return 0;
+    if (strlen(line) <= MAXMACRO) {
+	strncpy(maclines[num], line, sizeof(maclines[0]));
+	lineno++;
+	return 1;
+    }
+    temp = line;
+    while (1) {
+	end = MAXMACRO - 1;
+	if (end > strlen(temp)) {
+	    lineno++;
+	    strncpy(maclines[num++], temp, sizeof(maclines[0]));
+	    return (num);
+	} else
+	    for (; temp[end] != '%'; end--);
+
+	lineno++;
+	strncpy(maclines[num++], temp, end);
+
+	temp = temp + end;
+    }
+}
+
+
+void
+filldist(fill)
+    int     fill;
+{
+    register int i;
+    register int row;
+    register int c;
+    int     num;
+    char    key[3];
+
+    lineno = 0;
+    for (i = 1, row = 5; distmacro[i].macro != '\0'; i++) {
+	if (fill) {
+	    if (distmacro[i].c < 128)
+		sprintf(key, " %c", distmacro[i].c);
+	    else
+		sprintf(key, "^%c", distmacro[i].c - 128);
+	    sprintf(maclines[0], "%-8s %s",
+		    key,
+		    distmacro[i].name);
+	    W_WriteText(macroWin, 2, row++, W_Yellow, maclines[0],
+			strlen(maclines[0]), W_RegularFont);
+	}
+	lineno++;
+	num = formatline(distmacro[i].macro);
+	if (fill) {
+	    for (c = 0; c < num; c++) {
+		W_WriteText(macroWin, 8, row++, textColor, maclines[c],
+			    strlen(maclines[c]), W_RegularFont);
+	    }
+	}
+	if (lineno > NUMLINES)
+	    continue;
+    }
+}
+
+
+
+void
+fillmacro()
+{
+    register int row, i;
+    char    macromessage[MACROLEN];
+    struct macro *m;
+
+    W_ClearWindow(macroWin);
+    sprintf(macromessage, "Packages active:  %s%s",
+	    (F_UseNewMacro ? ", NEWMACRO" : ""),
+	    (F_gen_distress ? ", RCD" : ""));
+    /* (UseSmartMacro ? ", SMARTMACRO" : "")); */
+
+    W_WriteText(macroWin, 2, 1, textColor,
+		macromessage, strlen(macromessage), W_RegularFont);
+
+    sprintf(macromessage, "Currently showing: %s",
+	    (maclevel ? "Macros" : "RCDS"));
+
+    W_WriteText(macroWin, 2, 2, textColor,
+		macromessage, strlen(macromessage), W_RegularFont);
+
+
+    if (maclevel == 0) {
+	W_WriteText(macroWin, 2, 4, W_Yellow,
+		    "Key     Distress Name", 21, W_RegularFont);
+	filldist(1);
+	return;
+    }
+    /* 4 column macro window. This may be changed depending on font size */
+    for (row = 4, i = 0; i < 256; i++) {
+	for (m = macrotable[i]; m; m = m->next, row++) {
+	    if (m->flags & MACRCD)
+		break;
+	    if (i <= 128)
+		sprintf(macromessage, "%c ", i);
+	    else
+		sprintf(macromessage, "^%c", i - 128);
+#ifdef NEWMOUSE
+	    if (macro[i].type == NEWMMOUSE) {
+		switch (macro[i].who) {
+		case MACRO_PLAYER:
+		    strcat(macromessage, " PL MS ");
+		    break;
+		case MACRO_TEAM:
+		    strcat(macromessage, " TM MS ");
+		    break;
+		default:
+		    strcat(macromessage, " SELF  ");
+		    break;
+		}
+	    } else {
+#endif
+		switch (m->to) {
+		case 'T':
+		    strcat(macromessage, " TEAM  ");
+		    break;
+		case 'A':
+		    strcat(macromessage, " ALL   ");
+		    break;
+		case 'F':
+		    strcat(macromessage, " FED   ");
+		    break;
+		case 'R':
+		    strcat(macromessage, " ROM   ");
+		    break;
+		case 'K':
+		    strcat(macromessage, " KLI   ");
+		    break;
+		case 'O':
+		    strcat(macromessage, " ORI   ");
+		    break;
+#ifdef MOO
+		case 'M':
+		    strcat(macromessage, " MOO   ");
+		    break;
+#endif
+#ifdef TOOLS
+		case '!':
+		    strcat(macromessage, " SHELL ");
+		    break;
+#endif
+#ifdef NEWMACRO
+		case '\0':
+		    strcat(macromessage, " SPEC  ");
+		    break;
+#endif
+		case -1:
+		    switch (m->specialto) {
+		    case 'I':
+		    case 'C':
+			strcat(macromessage, " SELF  ");
+			break;
+		    case 'U':
+		    case 'P':
+			strcat(macromessage, " PL MS ");
+			break;
+		    case 'T':
+		    case 'Z':
+			strcat(macromessage, " TM MS ");
+			break;
+		    case 'G':
+			strcat(macromessage, " NR FR ");
+			break;
+		    case 'H':
+			strcat(macromessage, " NR EN ");
+			break;
+		    }
+		    break;
+		case -2:
+		    strcat(macromessage, " QUERY ");
+		    break;
+		default:
+		    strcat(macromessage, " ----  ");
+		    break;
+		}
+
+#ifdef NEWMOUSE
+	    }
+#endif
+	    strcat(macromessage, m->string);
+	    macromessage[MAXMACRO] = '\0';
+	    W_WriteText(macroWin, 2, row, textColor,
+			macromessage, strlen(macromessage), W_RegularFont);
+	}
+    }
+}
+
+void
+switchmacros()
+{
+    int     num, i;
+    struct macro *m;
+
+    if (!macroWin)
+	return;			/* paranoia? */
+
+    maclevel = abs(maclevel - 1);
+
+    if (maclevel == 0) {
+	lineno = 0;
+	filldist(0);
+	num = lineno + 5;
+    } else {
+	for (i = 0, macrocnt = 0; i < 256; i++) {
+	    for (m = macrotable[i]; m; m = m->next) {
+		if (m->flags & MACRCD)
+		    break;
+		macrocnt++;
+#if 0
+		len = strlen(m->string);
+		while (len > 0) {
+		    totmacros++;
+		    len -= 70;
+		}
+#endif
+	    }
+	}
+	num = macrocnt + 5;
+    }
+    W_ResizeText(macroWin, 80, num);
+#if 0
+    W_SetWindowExposeHandler(macroWin, fillmacro);
+    W_SetWindowButtonHandler(macroWin, switchmacros);
+#endif
+    W_MapWindow(macroWin);
+}
+
+
+
+void showMacroWin()
+{
+    int     num, i;
+    struct macro *m;
+
+    if (!macroWin) {
+	if (maclevel == 0) {
+	    lineno = 0;
+	    filldist(0);
+	    num = lineno + 5;
+	} else {
+	    for (i = 0, macrocnt = 0; i < 256; i++) {
+		for (m = macrotable[i]; m; m = m->next) {
+		    if (m->flags & MACRCD)
+			break;
+		    macrocnt++;
+#if 0
+		    len = strlen(m->string);
+		    while (len > 0) {
+			totmacros++;
+			len -= 70;
+		    }
+#endif
+		}
+	    }
+	    num = macrocnt + 5;
+	}
+
+	macroWin = W_MakeTextWindow("macrow", WINSIDE + BORDER, BORDER,
+				    80, num, NULL, (char*)0, BORDER);
+
+	W_ResizeText(macroWin, 80, num);
+#if 0
+	W_DefineTrekCursor(macroWin);
+	W_SetWindowExposeHandler(macroWin, fillmacro);
+	W_SetWindowButtonHandler(macroWin, switchmacros);
+#endif
+	W_MapWindow(macroWin);
+    } else if (W_IsMapped(macroWin)) {
+	W_DestroyWindow(macroWin);
+	macroWin = 0;
+    } else
+	W_MapWindow(macroWin);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,865 @@
+/* $Id: main.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * main.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <pwd.h>
+#ifdef hpux
+#include <time.h>
+#else
+#include <sys/time.h>
+#include <sys/wait.h>
+#endif				/* hpux */
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+#include "gameconf.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif
+#include "sound.h"
+
+jmp_buf env;
+
+#ifdef AMIGA
+/* needed for metafork... implemented by running a whole new copy
+   don't honestly know why I bothered ;-) */
+char **command_line;
+int global_argc;
+#endif
+
+#ifdef GATEWAY
+#define DEFAULT_GATEWAY		"atlgw"	/* for Quar */
+
+static char *get_gw P((void));
+static unsigned long mkaddr P((char *m));
+static void getUdpPort P((void));
+#endif
+
+extern int UdpLocalPort;
+/* Prototypes */
+static void printUsage P((char *prog));
+static void show_credits ();
+
+int
+main(argc, argv)
+    int     argc;
+    char  **argv;
+{
+    int     intrupt();
+    int     team, s_type;
+    char   *dpyname = NULL;
+    int     usage = 0;
+    int     err = 0;
+    char   *name, *ptr, *cp;
+#if !defined(NeXT) && !defined(RS6K) && !defined(SVR4)
+    char   *rindex();
+#endif
+    struct passwd *pwent;
+    int     passive = 0;
+#ifdef METASERVER
+    int     usemeta = 0;
+#endif				/* METASERVER */
+/*    char *defaultsFile=NULL;*/
+
+    pseudo[0] = defpasswd[0] = '\0';
+
+#ifdef AMIGA
+    command_line = argv;
+    global_argc=argc;
+#endif
+
+    name = *argv++;
+    argc--;
+    if ((ptr = rindex(name, '/')) != NULL)
+	name = ptr + 1;
+#ifdef GATEWAY
+    netaddr = -1;		/* special NULL address */
+    serverName = get_gw();	/* default machine is gw */
+#endif
+    while (*argv) {
+	if (**argv != '-') {
+	    serverName = *argv;	/* don't abort argument processing */
+	    argv++;
+	    argc--;
+	} else {
+	    ++*argv;
+
+	    argc--;
+	    ptr = *argv++;
+	    while (*ptr) {
+		switch (*ptr) {
+		case 'C':	/* character name */
+		    (void) strncpy(pseudo, *argv, sizeof(pseudo));
+		    argv++;
+		    argc--;
+		    break;
+
+		case 'c':	/* Credits */
+		    show_credits();
+		    exit (0);
+		    break;
+
+		case 'P':	/* authorization password */
+		    (void) strncpy(defpasswd, *argv, sizeof(defpasswd));
+		    {
+			int     i;
+			for (i = 0; (*argv)[i]; i++)
+			    (*argv)[i] = 0;
+		    }
+		    argv++;
+		    argc--;
+		    break;
+
+		case 'u':
+		    usage++;
+		    break;
+		case 's':
+		    if (*argv) {
+			xtrekPort = atoi(*argv);
+			passive = 1;
+			argv++;
+			argc--;
+		    }
+		    break;
+		case 'p':
+		    if (*argv) {
+			xtrekPort = atoi(*argv);
+			argv++;
+			argc--;
+		    }
+		    break;
+		case 'd':
+		    dpyname = *argv;
+		    argc--;
+		    argv++;
+		    break;
+#ifdef METASERVER
+		case 'm':
+		    usemeta = 1;
+		    break;
+#endif				/* METASERVER */
+		case 'h':
+		    serverName = *argv;
+		    if (!serverName)
+			err++;
+#ifdef GATEWAY
+		    gw_mach = *argv;
+#endif
+		    argc--;
+		    argv++;
+		    break;
+#ifdef GATEWAY
+		case 'H':
+		    netaddr = mkaddr(*argv);
+		    argc--;
+		    argv++;
+		    break;
+#endif
+
+		case 't':
+		    title = *argv;
+		    argc--;
+		    argv++;
+		    break;
+		case 'r':
+		    defaultsFile = *argv;
+		    argv++;
+		    argc--;
+		    break;
+#ifdef AUTHORIZE
+		case 'o':
+		    RSA_Client = -1;
+		    break;
+		case 'R':
+		    RSA_Client = -2;
+		    break;
+#else
+		case 'o':
+		case 'R':
+		    printf("This client does not have binary authorization.\n");
+		    break;
+#endif
+		case 'e':
+#ifdef AUTHORIZE
+		    checkExpire(1);
+#else
+		    printf("This client does not RSA verify and will not expire.\n");
+#endif
+		    exit(0);
+		    break;
+		case 'f':	/* list ftp sites */
+		    fprintf(stderr, "\n\
+The newest version of the Paradise client can be found at:\n\
+      ftp.pnetrek.org in /pub/paradise/bin/\n\
+or    ftp.cs.umn.edu  in /users/glamm/paradise/bin/\n\
+\n\
+Quick ftp instructions:\n\
+This assumes you are bob@school.edu and are using a Sun workstation\n\
+('sparc' architecture).  Modify with your mailing address and architecture.\n\
+Type:\n\
+   ftp ftp.cs.umn.edu\n\
+   (at name prompt) anonymous\n\
+   (at password prompt) bob@school.edu\n\
+   (at ftp> prompt) cd users/glamm/paradise/bin\n\
+   (at ftp> prompt) binary\n\
+   (at ftp> prompt) dir\n\
+   (lots of files printed - pick out the latest release for your architecture.\n\
+    all the client binaries begin with 'netrek'.)\n\
+   (at ftp> prompt) get netrek.Sparc-SunOS-static\n\
+   (note: static and dynamic are functionally the same.\n\
+  (at ftp> prompt) bye\n\
+\n\
+That's it!\n");
+		    exit(0);
+		case 'G':
+		    if (*argv) {
+			ghoststart++;
+			ghost_pno = atoi(*argv);
+			printf("Emergency restart being attempted...\n");
+			argv++;
+			argc--;
+		    }
+		    break;
+		case '2':	/* force paradise */
+		    paradise = 1;
+		    break;
+#ifdef RECORDER
+		case 'F':	/* File playback */
+		    if (*argv) {
+			playFile = strdup(*argv);
+			playback = 1;
+			argv++;
+			argc--;
+		    }
+		    break;
+#endif
+		case 'U':
+		    if(*argv == NULL || (UdpLocalPort = atoi(*argv)) <= 0) {
+			fprintf(stderr, "Error: -U requires a port number\n");
+			usage++;
+			break;
+		    }
+		    argc--;
+		    argv++;
+		    break;
+		default:
+		    fprintf(stderr, "%s: unknown option '%c'\n", name, *ptr);
+		    err++;
+		    break;
+		}
+		ptr++;
+	    }
+	}
+    }
+#ifdef GATEWAY
+    if (netaddr == -1) {
+	fprintf(stderr,
+		"netrek: no remote address set (-H).  Restricted server will not work.\n");
+    }
+#endif
+
+
+
+    inittrigtables();
+
+    initStars();		/* moved from redraw.c at KAO\'s suggestion */
+
+    if (usage || err) {
+	printUsage(name);
+#ifdef AUTHORIZE
+	checkExpire(1);
+#endif
+	exit(0);
+	/* exit(err); Exits from checkExpire */
+    }
+    defaultsFile = initDefaults(defaultsFile);
+
+#ifdef AUTHORIZE
+    if (RSA_Client != -1)
+	checkExpire(0);
+#endif
+
+    /* compatability */
+    if (argc > 0)
+	serverName = argv[0];
+
+    srandom(getpid() + time((long *) 0));
+
+#ifdef RECORDER
+    if(playback || booleanDefault("playback",0)) {
+        defNickName = "playback";
+	usemeta=0;
+        serverName = "playback";
+    } else
+#endif
+    {
+        if (serverName) {
+	    char    temp[80], *s;
+	    sprintf(temp, "server.%s", serverName);
+	    if ((s = getdefault(temp))) {
+		s=strdup(s);
+		printf("Using nickname \"%s\" for server %s\n", serverName, s);
+		defNickName = serverName;
+		serverName = s;
+		defFlavor = getdefault("flavor");
+		if(defFlavor) 
+                    defFlavor=strdup(defFlavor);
+	    }
+	}
+	if (!serverName) {
+	    if(serverName = getdefault("server"))
+		serverName = strdup(serverName);
+        }
+	if (!serverName && !passive) {
+	    serverName = DEFAULT_SERVER;
+#ifdef METASERVER
+	    usemeta = 1;		/* no server specified, show the menu */
+#endif
+	}
+	if (passive)
+	    serverName = "passive";	/* newwin gets a wrong title otherwise */
+
+	if (xtrekPort < 0)
+	    xtrekPort = intDefault("port", -1);
+	if (xtrekPort < 0)
+	    xtrekPort = DEFAULT_PORT;
+#if 0
+#ifdef AUTHORIZE
+	if (RSA_Client >= 0)
+	    RSA_Client = booleanDefault("useRSA", RSA_Client);
+	else
+	    RSA_Client = (RSA_Client == -2);
+#endif
+#endif				/* 0 */
+
+    } /* playback */
+    build_default_configuration();
+
+#ifdef METASERVER
+    metaserverAddress = stringDefault("metaserver",
+				      "metaserver.ecst.csuchico.edu");
+    if (usemeta)
+	parsemeta();
+#endif				/* METASERVER */
+
+    W_Initialize(dpyname);
+#ifdef SOUND
+    S_Initialize();
+#endif
+
+
+#ifdef METASERVER
+    metaFork = booleanDefault("metaFork", metaFork);
+    /* do the metawindow thang */
+    if (usemeta) {
+	metawindow();
+	metainput();
+	if (metaFork)
+	    W_Initialize(dpyname);
+	newwin(dpyname, name);
+    } else
+#endif				/* METASERVER */
+
+	/* this creates the necessary x windows for the game */
+	newwin(dpyname, name);
+
+#ifdef TIMELORD
+    start_timelord();
+#endif
+
+    /* open memory...? */
+    openmem();
+#ifdef RECORDER
+    if (!startPlayback())
+#endif
+    {
+	if (!passive) {
+	    callServer(xtrekPort, serverName);
+	} else {
+	    connectToServer(xtrekPort);
+	}
+    }
+#ifdef FEATURE
+    sendFeature("FEATURE_PACKETS", 'S', 1, 0, 0);
+#endif
+
+    timeStart = time(NULL);
+    findslot();
+
+    /* sets all the settings from defaults file (.xtrekrc probably) */
+    resetDefaults();
+
+#ifdef UNIX_SOUND
+    init_sound();
+    play_sound(SND_PARADISE);
+#endif
+
+    mapAll();
+/*    signal(SIGINT, SIG_IGN);*/
+    signal(SIGCHLD, (void (*) ()) reaper);
+
+    /* Get login name */
+    if ((pwent = getpwuid(getuid())) != NULL)
+	(void) strncpy(login, pwent->pw_name, sizeof(login));
+    else
+	(void) strncpy(login, "Bozo", sizeof(login));
+    login[sizeof(login) - 1] = '\0';
+
+    if (pseudo[0] == '\0') {
+	if ((cp = getdefault("name")) != 0)
+	    (void) strncpy(pseudo, cp, sizeof(pseudo));
+	else
+	    (void) strncpy(pseudo, login, sizeof(pseudo));
+    }
+    pseudo[sizeof(pseudo) - 1] = '\0';
+
+    if (defpasswd[0] == '\0') {
+	char buf[100], buf2[100];  /* added password by character name -JR */
+	sprintf(buf,"password.%s",pseudo);
+        if (serverName)         /* password by server name -TH */
+            sprintf(buf2, "password.%s", serverName);
+	if((cp = getdefault(buf)) || (cp = getdefault(buf2)) ||
+ 		(cp = getdefault("password")))
+	    (void) strncpy(defpasswd, cp, sizeof(defpasswd));
+    }
+    defpasswd[sizeof(defpasswd) - 1] = '\0';
+
+    /*
+       sendLoginReq("Gray Lensman", "hh", "sfd", 0); loginAccept = -1; while
+       (loginAccept == -1) { socketPause(1,0); readFromServer(); }
+    */
+    getname(pseudo, defpasswd);
+    loggedIn = 1;
+#ifdef TIMER
+    timeBank[T_SERVER] = timeStart;
+    timeBank[T_DAY] = 0;
+#endif				/* TIMER */
+
+
+#ifdef AUTOKEY
+    /* autokey.c */
+    autoKeyDefaults();
+#endif				/* AUTOKEY */
+
+    /*
+       Set p_hostile to hostile, so if keeppeace is on, the guy starts off
+       hating everyone (like a good fighter should)
+    */
+    me->p_hostile = (1 << number_of_teams) - 1;
+
+    redrawTstats();
+
+    me->p_planets = 0;
+    me->p_genoplanets = 0;
+    me->p_armsbomb = 0;
+    me->p_genoarmsbomb = 0;
+    /* Set up a reasonable default */
+    me->p_whydead = KQUIT;
+    me->p_teami = -1;
+    s_type = defaultShip(CRUISER);	/* from rlb7h 11/15/91 TC */
+
+    if (booleanDefault("netStats", 1))
+	startPing();		/* tell the server that we support pings */
+
+#ifdef AUTOKEY
+    if (autoKey) {
+	/* XX: changes entire state of display */
+	W_AutoRepeatOff();
+    }
+#endif
+    /*
+       hack to make galaxy class ships work.  This could be more elegant, but
+       the configuration code would have to be modified quite a bit, since
+       the client doesn't know if it's on a paradise server until after it
+       connects, and it needs the configuration info before it connects.
+    */
+    init_galaxy_class();
+
+    initkeymap(-1);		/* needs to have ship types initialized -JR */
+
+    setjmp(env);		/* Reentry point of game */
+
+    if (ghoststart) {
+	int     i;
+
+	ghoststart = 0;
+
+	for (i = -1; i < 5; i++)
+	    if (teaminfo[i].letter == me->p_mapchars[0])
+		break;
+
+	me->p_teami = i;
+
+	if (me->p_damage > me->p_ship->s_maxdamage) {
+	    me->p_status = POUTFIT;
+	} else
+	    me->p_status = PALIVE;
+    } else
+	me->p_status = POUTFIT;
+
+    while (1) {
+	switch (me->p_status) {
+	case POUTFIT:
+	case PTQUEUE:
+	    /* give the player the motd and find out which team he wants */
+#if 1
+	    new_entrywindow(&team, &s_type);
+#else
+	    entrywindow(&team, &s_type);
+#endif
+	    allowPlayerlist = 1;
+	    if (W_IsMapped(playerw))
+		playerlist();
+
+#ifdef RECORDER
+	    if (!playback)
+#endif
+		if (team == -1) {
+		    W_DestroyWindow(w);
+#ifdef AUTOKEY
+		    if (autoKey)
+			W_AutoRepeatOn();
+#endif
+		    sendByeReq();
+		    sleep(1);
+		    printf("OK, bye!\n");
+		    EXIT(0);
+		}
+	    sendVersion();
+	    myship = getship(myship->s_type);
+
+	    currentship = myship->s_type;
+
+	    /*
+	       sendOptionsPacket(); /* this would totally blast any flags you
+	       had on the server
+	    */
+
+	    redrawall = 1;
+	    enter();
+	    calibrate_stats();
+	    W_ClearWindow(w);
+	    /*
+	       for (i = 0; i < NSIG; i++) { signal(i, SIG_IGN); }
+	    */
+
+	    me->p_status = PALIVE;	/* Put player in game */
+
+#ifdef UNIX_SOUND
+            kill_sound ();
+#endif
+            
+#ifdef HOCKEY
+	    hockeyInit();
+#endif /*HOCKEY*/
+
+#ifdef TIMER
+	    timeBank[T_SHIP] = time(NULL);
+#endif				/* TIMER */
+
+	    if (showStats)	/* Default showstats are on. */
+		W_MapWindow(statwin);
+
+#ifdef GATEWAY
+	    /* pick a nice set of UDP ports */
+	    getUdpPort();
+#endif
+
+#if ATM
+	    if (tryUdp && commMode != COMM_UDP) {
+		sendUdpReq(COMM_UDP);
+	    }
+#endif				/* ATM */
+#ifdef SHORT_PACKETS
+	    if (tryShort) {
+		sendShortReq(SPK_VON);
+		tryShort = 0;	/* only try it once */
+	    }
+#endif	/* SHORT_PACKETS */
+	    /* Send request for a full update */
+	    if (askforUpdate) {
+		if(recv_short)
+		    sendShortReq(SPK_SALL);
+		else
+		    sendUdpReq(COMM_UPDATE);
+	    }
+	    sendUpdatePacket(1000000 / updateSpeed);
+
+	    W_Deiconify(baseWin);
+
+	    break;
+	case PALIVE:
+	case PEXPLODE:
+	case PDEAD:
+	case POBSERVE:
+
+#ifdef TIMELORD
+	    /* reading the MOTD doesn't count against your playing time */
+	    update_timelord_notcount();
+#endif
+
+	    /* Get input until the player quits or dies */
+	    input();
+	    W_ClearWindow(mapw);
+#ifdef TIMELORD
+	    /* get any fractional minutes we missed */
+	    update_timelord(1);
+#endif
+	    break;
+	default:
+	    printf("client has p_status=%d.  how strange\n", me->p_status);
+	    me->p_status = POUTFIT;
+	}
+    }
+
+    /* NOTREACHED */
+}
+
+static void
+printUsage(prog)
+    char   *prog;
+{
+    fprintf(stderr, "Usage:\n  %s [ options ] [ ntserv-host ]\n\
+Where options are\n\
+    [-h] host          server host name\n\
+    [-p] port          server port number\n\
+    [-r] xtrekrc       defaults file to replace ~/.xtrekrc\n\
+    [-t] title         window manager title\n\
+    [-d] display       set Xwindows display\n\
+    [-C] name          netrek pseudonym\n\
+    [-P] passwd        passwd to use to attempt autologin\n\
+    [-R]               use RSA authorization (default)\n\
+    [-o]               use old (non-RSA) authorization\n\
+    [-s] port          wait for connection from ntserv on a port (debugging)\n\
+%s\
+%s\
+    [-U] port          specify base local UDP port number to use\n\
+    [-e]               check the expire time on the client\n\
+    [-f]               how to get the newest client\n\
+    [-u]               print usage\n\
+    [-c]               Paradise credits\n\
+  For emergency restart:\n\
+    [-2]               force paradise - use if you were on a paradise server\n\
+    [-G] playernum     specify player number to use\n\
+    [-s] port          specify socket number to use\n\
+Paradise Client %s\n\
+For more information on how to play Paradise, use Netscape or Internet\n\
+Explorer and connect to:\n\
+    http://www.pnetrek.org/               OR\n\
+    http://www.cs.umn.edu/users/glamm/paradise/\n\n", prog,
+#ifdef METASERVER
+	    "    [-m]               check metaserver for active servers\n",
+#else
+	    "",
+#endif				/* METASERVER */
+#ifdef RECORDER
+	    "    [-F] file          Replay from file instead of connecting\n",
+#else
+	    "",
+#endif
+	    CLIENTVERS);
+}
+
+void
+reaper()
+{
+#if defined(hpux) || defined(SVR4) || defined(AMIGA)
+    wait((int *) 0);
+#else
+    /* well, hell, just use NULL, it works for everything else anyway */
+/*    while (wait3((union wait *) 0, WNOHANG, NULL) > 0);*/
+    while(wait3(NULL, WNOHANG, NULL) > 0);
+#endif				/* hpux */
+}
+
+#ifdef GATEWAY
+static struct udpmap_t {
+    int     uid;
+    int     serv_port;
+    int     port;
+    int     local_port;
+}       udpmap[] = {
+    /* 5000, 5001, 5000 *//* generic */
+    {
+	1290, 5010, 5011, 5010
+    },				/* fadden */
+    {
+	757, 5020, 5021, 5020
+    },				/* user2 */
+};
+#define MAPSIZE (sizeof(udpmap) / sizeof(struct udpmap_t))
+
+static void
+getUdpPort()
+{
+    int     i;
+    uid_t   uid;
+    char   *gw_m, *gw_p, *gw_lp, *gw_sp, *err, *getenv();
+
+    /* should always be set prior, but in case not .. */
+    if (!gw_mach) {
+	gw_m = getenv("GW_MACH");
+	if (gw_m)
+	    gw_mach = gw_m;
+	else
+	    gw_mach = DEFAULT_GATEWAY;
+    }
+    uid = getuid();
+
+    for (i = 0; i < MAPSIZE; i++) {
+	if (uid == udpmap[i].uid) {
+	    gw_serv_port = udpmap[i].serv_port;
+	    gw_port = udpmap[i].port;
+	    gw_local_port = udpmap[i].local_port;
+	    return;
+	}
+    }
+
+    gw_p = getenv("GW_PORT");
+    gw_sp = getenv("GW_SPORT");
+    gw_lp = getenv("GW_LPORT");
+
+    if (gw_p) {
+	gw_port = strtol(gw_p, &err, 10);
+	if (err == gw_p) {
+	    fprintf(stderr, "netrek: malformed integer for GW_PORT: %s\n",
+		    gw_p);
+	    /* let something else complain about port 0 */
+	}
+    } else
+	gw_port = 5001;
+    if (gw_sp) {
+	gw_serv_port = strtol(gw_sp, &err, 10);
+	if (err == gw_sp) {
+	    fprintf(stderr, "netrek: malformed integer for GW_SPORT: %s\n",
+		    gw_sp);
+	    /* let something else complain about port 0 */
+	}
+    } else
+	gw_serv_port = 5000;
+
+    if (gw_lp) {
+	gw_local_port = strtol(gw_lp, &err, 10);
+	if (err == gw_lp) {
+	    fprintf(stderr, "netrek: malformed integer for GW_LPORT: %s\n",
+		    gw_lp);
+	    /* let something else complain about port 0 */
+	}
+    } else
+	gw_local_port = 5000;
+
+    /*
+       printf("gw_mach: \'%s\'\n", gw_mach); printf("gw_local_port: %d\n",
+       gw_local_port); printf("gw_serv_port: %d\n", gw_serv_port);
+       printf("gw_port: %d\n", gw_port);
+    */
+}
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+
+/*
+ * In the event of problems assiocated with the above include files the
+ * following routine can be alternately used to convert a string
+ * ("xxx.xxx.xxx.xxx") to an internet address number.
+ *
+ * (author: Andy McFadden)
+ */
+
+#ifdef notneeded
+unsigned long
+dotAddrToNetAddr(str)
+    char   *str;
+{
+    char   *t;
+    unsigned long answer = 0;
+    t = str;
+    for (i = 0; i < 4; i++) {
+	answer = (answer << 8) | atoi(t);
+	while (*t && *t != '.')
+	    t++;
+	if (*t)
+	    t++;
+    }
+    return answer;
+}
+#endif
+
+/*
+ * More network "correct" routine
+ */
+
+static unsigned long
+mkaddr(m)
+    char   *m;
+{
+    struct in_addr ad;
+    struct hostent *hp;
+
+    hp = gethostbyname(m);
+    if (!hp) {
+	ad.s_addr = inet_addr(m);
+	if (ad.s_addr == -1) {
+	    fprintf(stderr, "netrek: unknown host \'%s\'\n", m);
+	    exit(1);
+	}
+    } else
+	bcopy(hp->h_addr, (char *) &ad, hp->h_length);
+
+    return ad.s_addr;
+}
+
+static char *
+get_gw()
+{
+    char   *gw_m;
+
+    gw_m = getenv("GW_MACH");
+    if (gw_m)
+	gw_mach = gw_m;
+    else
+	gw_mach = DEFAULT_GATEWAY;
+
+    return gw_mach;
+}
+
+#endif
+
+void
+show_credits()
+{
+	printf ("Paradise Netrek\n\
+\n\
+Copyright (c) 1986	Chris Guthrie\n\
+Copyright (c) 1989	Kevin P. Smith\n\
+Copyright (c) 1993	Larry Denys, Kurt Olsen, Brandon Gillespie, and\n\
+			Robert Forsman\n\
+Copyright (c)		Eric Mehlaff, Sujal Patel, Robert Glamm, \n\
+			Lars Bernhardsson, Kurt Siegl, Nick Trown\n\
+\n\
+Paradise Developers\n\
+  Larry Deny                       Robert Forsman\n\
+  Brandon Gillespie                Kurt Olsen\n\
+\n\
+Paradise Contributors (In alphabetical order):\n\
+  Terence Chang                    Mike McGrath\n\
+  Bill Dyess                       Matthew Mead\n\
+  Jerry Frain                      Gary Parnes\n\
+  Robert Glamm                     Sujal Patel\n\
+  T. Hadley                        Joe Rumsey\n\
+  Heath A. Kehoe                   Rado Smiljanic\n\
+  Andy McFadden                    Joe Young\n\
+");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/motdwin.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,93 @@
+/* $Id: motdwin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/***  Pop-up motd window code.  [BDyess] 11/21/93  ***/
+
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include <sys/types.h>
+#ifdef hpux
+#include <time.h>
+#else				/* hpux */
+#include <sys/time.h>
+#endif				/* hpux */
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#ifdef SVR4
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+
+void
+motdWinEvent(key)
+    int     key;
+/* handles keystrokes in the motd window */
+{
+    static  valuesOn = 0;
+
+    switch (key) {
+    case 'f':			/* scroll forward */
+	if (currpage == NULL) {
+	    currpage = motddata;
+	    if (currpage == NULL)
+		break;
+	}
+	if (currpage->next == NULL)
+	    break;
+	if (currpage->next)
+	    currpage->next->prev = currpage;
+	currpage = currpage->next;
+	showMotd(motdWin);
+	break;
+    case 'b':			/* Scroll motd backward */
+	if (currpage == NULL || currpage->prev == NULL)
+	    break;
+	currpage = currpage->prev;
+	showMotd(motdWin);
+	break;
+    case ' ':			/* unmap window */
+	showMotdWin();
+	break;
+    case '\t':			/* tab: swap between sysdef and motd */
+	W_ClearWindow(motdWin);
+	if (!valuesOn) {
+	    showValues(motdWin);
+	    valuesOn = 1;
+	} else {
+	    showMotd(motdWin);
+	    valuesOn = 0;
+	}
+	break;
+    case 'r':			/* refresh */
+	if (valuesOn)
+	    showValues(motdWin);
+	else
+	    showMotd(motdWin);
+	break;
+    }
+}
+
+void
+showMotdWin()
+/* handles map/unmap requests */
+{
+    if (!motdWin) {
+	motdWin = W_MakeWindow(
+			       "Motd"
+			       ,-BORDER, -BORDER, WINSIDE, WINSIDE, NULL,
+			       (char *) 0, BORDER, foreColor);
+	W_MapWindow(motdWin);
+	currpage = motddata;
+	showMotd(motdWin);
+    } else if (W_IsMapped(motdWin)) {
+	W_UnmapWindow(motdWin);
+    } else {
+	W_MapWindow(motdWin);
+	currpage = motddata;
+	showMotd(motdWin);
+    }
+}
Binary file netrek.paradise has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/newwin.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1573 @@
+/* $Id: newwin.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * newwin.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <math.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <string.h>
+#ifdef hpux
+#include <time.h>
+#else				/* hpux */
+#include <sys/time.h>
+#endif				/* hpux */
+#ifdef RS6K
+#include <sys/select.h>
+#endif
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "gameconf.h"
+
+
+
+#include "oldbitmaps.h"
+#include "bitmaps_pr.h"
+#include "bitmaps3.h"
+#include "hullbitmaps.h"
+#include "planetbitmaps.h"
+#include "rabbitbitmaps.h"
+#include "starbitmaps.h"
+
+#ifdef BEEPLITE
+#include "emph_planet_seq.h"
+#include "emph_player_seq.h"
+#include "emph_player_seql.h"
+#endif
+
+#include "packets.h"
+#include "proto.h"
+
+#define NRHEADERS	4
+W_Icon  headerA, headerB, headerchanges[NRHEADERS];
+W_Icon  safepic;
+/* elapsed time in outfit window [BDyess] */
+int     elapsed;
+
+int     newMotdStuff = 0;	/* set to 1 when new motd packets arrive */
+static struct piclist *motdPics = NULL;
+/*static struct page *currpage = NULL;
+static struct page *motddata = NULL;*/
+
+#define LINESPERPAGE	38
+
+#define BOXSIDE		(WINSIDE / 5)
+#define TILESIDE	16
+#define MESSAGESIZE	20
+#define STATSIZE	(MESSAGESIZE * 2 + BORDER)
+#define YOFF		0
+
+#define stipple_width 16
+#define stipple_height 16
+static unsigned char stipple_bits[] = {
+    0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08,
+    0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80,
+    0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08,
+0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80};
+
+/* ATM: extra stuff for those who don't like my visible tractors */
+#define tract_width 5
+#define tract_height 5
+static char tract_bits[] = {
+0x1f, 0x04, 0x04, 0x04, 0x04};
+#define press_width 5
+#define press_height 5
+static char press_bits[] = {
+0x0f, 0x11, 0x0f, 0x01, 0x01};
+
+/* Prototypes */
+static void savebitmaps P((void));
+static int teamRequest P((int team, int ship));
+static int numShips P((int owner));
+static int checkBold P((char *line));
+void showMotd P((W_Window win));
+static void showPics P((W_Window win));
+void showValues P((W_Window win));
+static void getResources P((char *prog));
+static void getTiles P((void));
+static void redrawTeam P((W_Window win, int teamNo, int *lastnum));
+static void redrawQuit P((void));
+static void showTimeLeft P((int time, int max));
+
+/* from dashboard.c: */
+void light_erase P((void));
+
+extern int helpmessages;
+
+void
+newwin(hostmon, progname)
+    char   *hostmon, *progname;
+{
+    int     i;
+
+    /* W_Initialize(hostmon); */
+
+    baseWin = W_MakeWindow("netrek", 0, YOFF, WINSIDE * 2 + 1 * BORDER,
+			   WINSIDE + 2 * BORDER + 2 * MESSAGESIZE, NULL, "bomb here", BORDER, gColor);
+    iconWin = W_MakeWindow("netrek_icon", 0, 0, icon_width, icon_height, NULL,
+			   (char *) 0, BORDER, gColor);
+    W_SetIconWindow(baseWin, iconWin);
+    w = W_MakeWindow("local", -BORDER, -BORDER, WINSIDE, WINSIDE, baseWin,
+		     (char *) 0, BORDER, foreColor);
+    mapw = W_MakeWindow("map", WINSIDE, -BORDER, WINSIDE, WINSIDE, baseWin,
+			(char *) 0, BORDER, foreColor);
+    tstatw = W_MakeWindow("tstat", -BORDER, WINSIDE, WINSIDE, STATSIZE, baseWin,
+			  "xterm", BORDER, foreColor);
+    warnw = W_MakeWindow("warn", WINSIDE, WINSIDE, WINSIDE, MESSAGESIZE,
+			 baseWin, "xterm", BORDER, foreColor);
+    messagew = W_MakeWindow("message", WINSIDE, WINSIDE + BORDER + MESSAGESIZE,
+		 WINSIDE, MESSAGESIZE, baseWin, "xterm", BORDER, foreColor);
+    planetw = W_MakeTextWindow("planet", 10, 10, 75, (nplanets + 13) / 2, w, (char *) 0, 2);
+    planetw2 = W_MakeTextWindow("planet2", 10, 10, 75, (nplanets + 13) / 2, mapw, (char *) 0, 2);
+    rankw = W_MakeTextWindow("rank", 50, 100, 65, nranks2 + 8, w, (char *) 0, 2);
+    playerw = W_MakeTextWindow("player", 0, YOFF + WINSIDE + 2 * BORDER + 2 * MESSAGESIZE,
+			       83, (nplayers + 14) / 2, NULL, (char *) 0, 2);
+    helpWin = W_MakeTextWindow("help", 0, YOFF + WINSIDE + 2 * BORDER + 2 * MESSAGESIZE,
+		       160, helpmessages / 4 + 1, NULL, (char *) 0, BORDER);
+#ifdef METASERVER
+    /*
+       metaWin = W_MakeMenu ("MetaServer List", WINSIDE+10, -BORDER+10, 69,
+       num_servers + 2, NULL, 2);
+    */
+#endif				/* METASERVER */
+#if 0
+    W_SetWindowKeyDownHandler(metaWin, metaaction);
+    W_SetWindowButtonHandler(metaWin, metaaction);
+#endif				/* 0 */
+
+    initMessageWindows();
+
+    pStats = W_MakeWindow("Network Statistics", 500, 4, pStatsWidth(), pStatsHeight(),
+			  NULL, (char *) 0, 1, foreColor);
+    udpWin = W_MakeMenu("UDP", WINSIDE + 10, -BORDER + 10, 40, UDP_NUMOPTS,
+			NULL, 2);
+
+#ifdef SHORT_PACKETS
+    spWin = W_MakeMenu("network", WINSIDE + 10, -BORDER + 10, 40, SPK_NUMFIELDS,
+		       NULL, 2);
+#endif
+
+#ifdef TOOLS
+  toolsWin = W_MakeScrollingWindow("tools", WINSIDE + BORDER, BORDER,
+				   80, TOOLSWINLEN, NULL, "xterm", BORDER);
+#endif
+
+    motdWin = W_MakeWindow("Motd"
+			   ,-BORDER, -BORDER, WINSIDE, WINSIDE, NULL,
+			   (char *) 0, BORDER, foreColor);
+
+    for (i = 0; i < 4; i++) {
+	teamWin[i] = W_MakeWindow(teaminfo[i].shortname, i * BOXSIDE, 0,
+			  BOXSIDE, BOXSIDE, mapw, (char *) 0, 1, foreColor);
+    }
+    qwin = W_MakeWindow("quit", 4 * BOXSIDE, 0, BOXSIDE, BOXSIDE, mapw,
+			"pirate", 1, foreColor);
+
+/*    statwin = W_MakeWindow("stats", 422, 13, 160, 95, NULL, (char*)0,
+      5, foreColor);*/
+    statwin = W_MakeWindow("stats", 422, 13, 160, 80, NULL,
+			   (char *) 0, 5, foreColor);
+
+#define WARHEIGHT 2
+#define WARWIDTH 20
+#define WARBORDER 2
+
+    war = W_MakeMenu("war", WINSIDE + 10, -BORDER + 10, WARWIDTH, 6, baseWin,
+		     WARBORDER);
+
+
+    getResources(progname);
+    savebitmaps();
+}
+
+void
+mapAll()
+{
+    initinput();
+    W_MapWindow(mapw);
+    W_MapWindow(tstatw);
+    W_MapWindow(warnw);
+    W_MapWindow(messagew);
+    W_MapWindow(w);
+    W_MapWindow(baseWin);
+
+    /*
+       since we aren't mapping windows that have root as parent in
+       x11window.c (since that messes up the TransientFor feature) we have to
+       map them here. (If already mapped, W_MapWindow returns)
+    */
+
+    if (checkMapped("planet"))
+	W_MapWindow(planetw);
+    if (checkMapped("planet2"))
+	W_MapWindow(planetw2);
+    if (checkMapped("rank"))
+	W_MapWindow(rankw);
+    if (checkMapped("help"))
+	W_MapWindow(helpWin);
+    if (checkMapped("Motd"))
+	W_MapWindow(motdWin);
+    if (checkMapped("review_all"))
+	W_MapWindow(messWin[WALL].window);
+    if (checkMapped("review_team"))
+	W_MapWindow(messWin[WTEAM].window);
+    if (checkMapped("review_your"))
+	W_MapWindow(messWin[WINDIV].window);
+    if (checkMapped("review_kill"))
+	W_MapWindow(messWin[WKILL].window);
+    if (checkMapped("review_phaser"))
+	W_MapWindow(messWin[WPHASER].window);
+    if (booleanDefault("player.mapped", 1))
+	W_MapWindow(playerw);
+    if (booleanDefault("review.mapped", 1))
+	W_MapWindow(messWin[WREVIEW].window);
+    if (checkMapped("UDP"))
+	udpwindow();
+
+}
+
+static void
+savebitmaps()
+{
+    register int i;
+    int     tw, th, mw, mh;
+
+    /* slurp_ship_bitmaps(); */
+
+    clockpic = W_StoreBitmap(clock_width, clock_height, clock_bits,
+			     qwin);
+    safepic = W_StoreBitmap(safe_width, safe_height, safe_bits,
+			    qwin);
+
+#ifdef BEEPLITE
+    for (i = 0; i < emph_player_seq_frames; i++) {
+	emph_player_seq[emph_player_seq_frames - (i + 1)] =
+	    W_StoreBitmap(emph_player_seq_width, emph_player_seq_height,
+			  emph_player_seq_bits[i], mapw);
+    }
+
+    for (i = 0; i < emph_player_seql_frames; i++) {
+	emph_player_seql[emph_player_seql_frames - (i + 1)] =
+	    W_StoreBitmap(emph_player_seql_width, emph_player_seql_height,
+			  emph_player_seql_bits[i], w);
+    }
+
+    for (i = 0; i < emph_planet_seq_frames; i++) {
+	emph_planet_seq[emph_planet_seq_frames - (i + 1)] =
+	    W_StoreBitmap(emph_planet_seq_width, emph_planet_seq_height,
+			  emph_planet_seq_bits[i], mapw);
+    }
+#endif
+
+    load_default_teamlogos();
+
+    headerA = W_StoreBitmap(headerA_width, headerA_height,
+			    headerA_bits, motdWin);
+    headerB = W_StoreBitmap(headerB_width, headerB_height,
+			    headerB_bits, motdWin);
+    headerchanges[0] = W_StoreBitmap(header1_width, header1_height,
+				     header1_bits, motdWin);
+    headerchanges[1] = W_StoreBitmap(header2_width, header2_height,
+				     header2_bits, motdWin);
+    headerchanges[2] = W_StoreBitmap(header3_width, header3_height,
+				     header3_bits, motdWin);
+    headerchanges[3] = W_StoreBitmap(header4_width, header4_height,
+				     header4_bits, motdWin);
+    for (i = 0; i < HULL_FRAMES; i++)
+	hull[i] = W_StoreBitmap(hull_width, hull_height, hull_bits[i], w);
+
+    for (i = 0; i < 5; i++) {
+	cloud[i] = W_StoreBitmap(cloud_width, cloud_height, cloud_bits[4 - i], w);
+	plasmacloud[i] = W_StoreBitmap(plasmacloud_width,
+			    plasmacloud_height, plasmacloud_bits[4 - i], w);
+    }
+    etorp = W_StoreBitmap(etorp_width, etorp_height, etorp_bits, w);
+    mtorp = W_StoreBitmap(mtorp_width, mtorp_height, mtorp_bits, w);
+    for (i = 0; i < NDRONEVIEWS; i++) {
+	drone_bm[i] = W_StoreBitmap(drone_width, drone_height, drone_bits[i], w);
+    }
+    eplasmatorp =
+	W_StoreBitmap(eplasmatorp_width, eplasmatorp_height, eplasmatorp_bits, w);
+    mplasmatorp =
+	W_StoreBitmap(mplasmatorp_width, mplasmatorp_height, mplasmatorp_bits, w);
+    for (i = 0; i < VIEWS; i++) {
+	fighter[i] =
+	    W_StoreBitmap(fighter_width, fighter_height, fighter_bits[i], w);
+    };
+    warpbeacon = W_StoreBitmap(warpbeacon_width, warpbeacon_height, warpbeacon_bits, w);
+    wbflash = W_StoreBitmap(warpbeacon_width, warpbeacon_height, warpflash_bits, w);
+
+    tw = planet_width;
+    th = planet_height;
+    mw = mplanet_width;
+    mh = mplanet_height;
+
+    /* tactical screen planet bitmaps for team */
+
+    bplanets[0] = W_StoreBitmap(tw, th, indplanet_bits, w);
+    bplanets[1] = W_StoreBitmap(tw, th, fedplanet_bits, w);
+    bplanets[2] = W_StoreBitmap(tw, th, romplanet_bits, w);
+    bplanets[3] = W_StoreBitmap(tw, th, kliplanet_bits, w);
+    bplanets[4] = W_StoreBitmap(tw, th, oriplanet_bits, w);
+    bplanets[5] = W_StoreBitmap(tw, th, planet_bits, w);
+
+    /* galactic screen planet bitmaps for team */
+
+    mbplanets[0] = W_StoreBitmap(mw, mh, indmplanet_bits, mapw);
+    mbplanets[1] = W_StoreBitmap(mw, mh, fedmplanet_bits, mapw);
+    mbplanets[2] = W_StoreBitmap(mw, mh, rommplanet_bits, mapw);
+    mbplanets[3] = W_StoreBitmap(mw, mh, klimplanet_bits, mapw);
+    mbplanets[4] = W_StoreBitmap(mw, mh, orimplanet_bits, mapw);
+    mbplanets[5] = W_StoreBitmap(mw, mh, mplanet_bits, mapw);
+
+
+
+    /* tactical screen planet bitmaps for facilities */
+
+    bplanets2[0] = bplanets[0];
+    bplanets2[1] = W_StoreBitmap(tw, th, planet001_bits, w);
+    bplanets2[2] = W_StoreBitmap(tw, th, planet010_bits, w);
+    bplanets2[3] = W_StoreBitmap(tw, th, planet011_bits, w);
+    bplanets2[4] = W_StoreBitmap(tw, th, planet100_bits, w);
+    bplanets2[5] = W_StoreBitmap(tw, th, planet101_bits, w);
+    bplanets2[6] = W_StoreBitmap(tw, th, planet110_bits, w);
+    bplanets2[7] = W_StoreBitmap(tw, th, planet111_bits, w);
+    bplanets2[8] = W_StoreBitmap(tw, th, planet1010_bits, w);
+    bplanets2[9] = W_StoreBitmap(tw, th, planet1011_bits, w);
+    bplanets2[10] = bplanets2[8];
+    bplanets2[11] = bplanets2[9];
+    bplanets2[12] = W_StoreBitmap(tw, th, planet1110_bits, w);
+    bplanets2[13] = W_StoreBitmap(tw, th, planet1111_bits, w);
+    bplanets2[14] = bplanets2[12];
+    bplanets2[15] = bplanets2[13];
+
+    /* galactic screen planet bitmaps for facilities */
+
+    mbplanets2[0] = mbplanets[0];
+    mbplanets2[1] = W_StoreBitmap(mw, mh, mplanet001_bits, mapw);
+    mbplanets2[2] = W_StoreBitmap(mw, mh, mplanet010_bits, mapw);
+    mbplanets2[3] = W_StoreBitmap(mw, mh, mplanet011_bits, mapw);
+    mbplanets2[4] = W_StoreBitmap(mw, mh, mplanet100_bits, mapw);
+    mbplanets2[5] = W_StoreBitmap(mw, mh, mplanet101_bits, mapw);
+    mbplanets2[6] = W_StoreBitmap(mw, mh, mplanet110_bits, mapw);
+    mbplanets2[7] = W_StoreBitmap(mw, mh, mplanet111_bits, mapw);
+    mbplanets2[8] = W_StoreBitmap(mw, mh, mplanet1010_bits, mapw);
+    mbplanets2[9] = W_StoreBitmap(mw, mh, mplanet1011_bits, mapw);
+    mbplanets2[10] = mbplanets2[8];
+    mbplanets2[11] = mbplanets2[9];
+    mbplanets2[12] = W_StoreBitmap(mw, mh, mplanet1110_bits, mapw);
+    mbplanets2[13] = W_StoreBitmap(mw, mh, mplanet1111_bits, mapw);
+    mbplanets2[14] = mbplanets2[12];
+    mbplanets2[15] = mbplanets2[13];
+
+    /* tactical screen planet bitmaps for surface properties */
+
+    bplanetsr[0] = bplanets[0];
+    bplanetsr[1] = W_StoreBitmap(tw, th, planetr001_bits, w);
+    bplanetsr[2] = W_StoreBitmap(tw, th, planetr010_bits, w);
+    bplanetsr[3] = W_StoreBitmap(tw, th, planetr011_bits, w);
+    bplanetsr[4] = W_StoreBitmap(tw, th, planetr100_bits, w);
+    bplanetsr[5] = W_StoreBitmap(tw, th, planetr101_bits, w);
+    bplanetsr[6] = W_StoreBitmap(tw, th, planetr110_bits, w);
+    bplanetsr[7] = W_StoreBitmap(tw, th, planetr111_bits, w);
+
+    /* galactic screen planet bitmaps for surface properties */
+
+    mbplanetsr[0] = mbplanets[0];
+    mbplanetsr[1] = W_StoreBitmap(mw, mh, mplanetr001_bits, mapw);
+    mbplanetsr[2] = W_StoreBitmap(mw, mh, mplanetr010_bits, mapw);
+    mbplanetsr[3] = W_StoreBitmap(mw, mh, mplanetr011_bits, mapw);
+    mbplanetsr[4] = W_StoreBitmap(mw, mh, mplanetr100_bits, mapw);
+    mbplanetsr[5] = W_StoreBitmap(mw, mh, mplanetr101_bits, mapw);
+    mbplanetsr[6] = W_StoreBitmap(mw, mh, mplanetr110_bits, mapw);
+    mbplanetsr[7] = W_StoreBitmap(mw, mh, mplanetr111_bits, mapw);
+
+    /* tactical screen bitmaps for facilities, MOO-style */
+
+    bplanetsMOO[0] = W_StoreBitmap(tw, th, rmyplanet000_bits, w);
+    bplanetsMOO[1] = W_StoreBitmap(tw, th, rmyplanet001_bits, w);
+    bplanetsMOO[2] = W_StoreBitmap(tw, th, rmyplanet010_bits, w);
+    bplanetsMOO[3] = W_StoreBitmap(tw, th, rmyplanet011_bits, w);
+    bplanetsMOO[4] = W_StoreBitmap(tw, th, rmyplanet100_bits, w);
+    bplanetsMOO[5] = W_StoreBitmap(tw, th, rmyplanet101_bits, w);
+    bplanetsMOO[6] = W_StoreBitmap(tw, th, rmyplanet110_bits, w);
+    bplanetsMOO[7] = W_StoreBitmap(tw, th, rmyplanet111_bits, w);
+    bplanetsMOO[8] = W_StoreBitmap(tw, th, rmyplanet1010_bits, w);
+    bplanetsMOO[9] = W_StoreBitmap(tw, th, rmyplanet1011_bits, w);
+    bplanetsMOO[10] = bplanetsMOO[8];
+    bplanetsMOO[11] = bplanetsMOO[9];
+    bplanetsMOO[12] = W_StoreBitmap(tw, th, rmyplanet1110_bits, w);
+    bplanetsMOO[13] = W_StoreBitmap(tw, th, rmyplanet1111_bits, w);
+    bplanetsMOO[14] = bplanetsMOO[12];
+    bplanetsMOO[15] = bplanetsMOO[13];
+
+    /* galactic screen bitmaps for facilities, MOO-style */
+
+    mbplanetsMOO[0] = W_StoreBitmap(mw, mh, rmymplanet000_bits, mapw);
+    mbplanetsMOO[1] = W_StoreBitmap(mw, mh, rmymplanet001_bits, mapw);
+    mbplanetsMOO[2] = W_StoreBitmap(mw, mh, rmymplanet010_bits, mapw);
+    mbplanetsMOO[3] = W_StoreBitmap(mw, mh, rmymplanet011_bits, mapw);
+    mbplanetsMOO[4] = W_StoreBitmap(mw, mh, mplanet100_bits, mapw);
+    mbplanetsMOO[5] = W_StoreBitmap(mw, mh, mplanet101_bits, mapw);
+    mbplanetsMOO[6] = W_StoreBitmap(mw, mh, mplanet110_bits, mapw);
+    mbplanetsMOO[7] = W_StoreBitmap(mw, mh, mplanet111_bits, mapw);
+    mbplanetsMOO[8] = W_StoreBitmap(mw, mh, rmymplanet1010_bits, mapw);
+    mbplanetsMOO[9] = W_StoreBitmap(mw, mh, rmymplanet1011_bits, mapw);
+    mbplanetsMOO[10] = mbplanetsMOO[8];
+    mbplanetsMOO[11] = mbplanetsMOO[9];
+    mbplanetsMOO[12] = W_StoreBitmap(mw, mh, mplanet1110_bits, mapw);
+    mbplanetsMOO[13] = W_StoreBitmap(mw, mh, mplanet1111_bits, mapw);
+    mbplanetsMOO[14] = mbplanetsMOO[12];
+    mbplanetsMOO[15] = mbplanetsMOO[13];
+
+    for (i = 0; i < NSCOUTAGES; i++)
+	mbplanetsA[i] = W_StoreBitmap(mw, mh, age_bits[i], mapw);
+
+    /* star bitmaps */
+
+    for (i = 0; i < STARFRAMES; i++) {
+	starBM[i] = W_StoreBitmap(star_width, star_height, star_bitarray[i], w);
+    }
+    mstarBM = W_StoreBitmap(starm_width, starm_height, starm_bits, mapw);
+#ifdef VISIBLE_WORMHOLES
+    mholeBM = W_StoreBitmap(holem_width, holem_height, holem_bits, mapw);
+#endif /*VISIBLE_WORMHOLES*/
+    for (i = 0; i < WORMFRAMES; i++) {
+        wormBM[i] = W_StoreBitmap(wormhole_width, wormhole_height,
+				  wormhole_bitarray[i], w);
+     }
+
+/* set of 16 asteroid pics, and 3 asteroid fluff filler pics */
+    asteroidBM[0] = W_StoreBitmap(terrain_width, terrain_height,
+				  a0000_bits, w);
+    asteroidBM[1] = W_StoreBitmap(terrain_width, terrain_height,
+				  a0001_bits, w);
+    asteroidBM[2] = W_StoreBitmap(terrain_width, terrain_height,
+				  a0010_bits, w);
+    asteroidBM[3] = W_StoreBitmap(terrain_width, terrain_height,
+				  a0011_bits, w);
+    asteroidBM[4] = W_StoreBitmap(terrain_width, terrain_height,
+				  a0100_bits, w);
+    asteroidBM[5] = W_StoreBitmap(terrain_width, terrain_height,
+				  a0101_bits, w);
+    asteroidBM[6] = W_StoreBitmap(terrain_width, terrain_height,
+				  a0110_bits, w);
+    asteroidBM[7] = W_StoreBitmap(terrain_width, terrain_height,
+				  a0111_bits, w);
+    asteroidBM[8] = W_StoreBitmap(terrain_width, terrain_height,
+				  a1000_bits, w);
+    asteroidBM[9] = W_StoreBitmap(terrain_width, terrain_height,
+				  a1001_bits, w);
+    asteroidBM[10] = W_StoreBitmap(terrain_width, terrain_height,
+				  a1010_bits, w);
+    asteroidBM[11] = W_StoreBitmap(terrain_width, terrain_height,
+				  a1011_bits, w);
+    asteroidBM[12] = W_StoreBitmap(terrain_width, terrain_height,
+				  a1100_bits, w);
+    asteroidBM[13] = W_StoreBitmap(terrain_width, terrain_height,
+				  a1101_bits, w);
+    asteroidBM[14] = W_StoreBitmap(terrain_width, terrain_height,
+				  a1110_bits, w);
+    asteroidBM[15] = W_StoreBitmap(terrain_width, terrain_height,
+				  a1111_bits, w);
+    asteroidfluff[0] = W_StoreBitmap(terrain_width, terrain_height,
+				     a0_bits, w);
+    asteroidfluff[1] = W_StoreBitmap(terrain_width, terrain_height,
+				     a1_bits, w);
+    asteroidfluff[2] = W_StoreBitmap(terrain_width, terrain_height,
+				     a2_bits, w);
+    for (i = 0; i < 2; i++) {
+	basteroid2[i] = W_StoreBitmap(asteroid_width, asteroid_height, asteroid_bits, w);
+	mbasteroid2[i] = W_StoreBitmap(masteroid_width, masteroid_height, masteroid_bits, mapw);
+    }
+    for (i = 0; i < 6; i++) {
+	basteroid[i] = W_StoreBitmap(asteroid_width, asteroid_height, asteroid_bits, w);
+	mbasteroid[i] = W_StoreBitmap(masteroid_width, masteroid_height, masteroid_bits, mapw);
+    }
+
+    kitchenSink = W_StoreBitmap(sink_width, sink_height, sink_bits, w);
+
+    for (i = 0; i < EX_FRAMES; i++) {
+	expview[i] = W_StoreBitmap(ex_width, ex_height, ex_bits[i], w);
+    }
+    for (i = 0; i < SBEXPVIEWS; i++) {
+	sbexpview[i] = W_StoreBitmap(sbexp_width, sbexp_height, sbexp_bits[i], w);
+    }
+
+    cloakicon = W_StoreBitmap(cloak_width, cloak_height, cloak_bits, w);
+    icon = W_StoreBitmap(icon_width, icon_height, icon_bits, iconWin);
+    tractbits = W_StoreBitmap(tract_width, tract_height, tract_bits, w);
+    pressbits = W_StoreBitmap(press_width, press_height, press_bits, w);
+}
+
+void
+get_N_dispatch_outfit_event(team, s_type, lastplayercount)
+    int    *team;
+    int    *s_type;
+    int    *lastplayercount;
+{
+    W_Event event;
+    int     validshipletter = 0;
+    static int resetting = 0;
+    int     oldresetting;
+    int     i;
+
+    oldresetting = resetting;
+
+    W_NextEvent(&event);
+    switch ((int) event.type) {
+    case W_EV_KEY:
+	{
+	    struct shiplist *shipscan;
+	    validshipletter = 0;
+	    shipscan = shiptypes;
+	    while (shipscan) {
+		if (shipscan->ship->s_letter == event.key) {
+		    *s_type = shipscan->ship->s_type;
+		    validshipletter = 1;
+		    break;
+		}
+		shipscan = shipscan->next;
+	    }
+	}
+
+	if (me->p_status == PTQUEUE) {
+	    int     i;
+	    for (i = 0; i < WNUM; i++) {
+		if (event.Window == messWin[i].window) {
+		    messageWinEvent(&event);
+		    break;
+		}
+	    }
+	    if (i != WNUM)
+		break;
+	    if (event.Window == messagew ||
+		event.Window == tstatw ||
+		event.Window == warnw)
+		smessage(event.key);
+	}
+	if (event.Window == motdWin) {
+	    motdWinEvent(event.key);
+	    break;
+	} else if (event.Window == playerw || event.Window == infow) {
+	    /* allow 'i' 'I' and '^i' in playerw [BDyess] */
+	    playerwEvent(&event);
+	    break;
+	} else if (event.Window == w || event.Window == mapw) {
+	    switch (event.key) {
+#ifdef Q_OUTFITTING
+	    case 'q':
+		*team = number_of_teams;
+		me->p_status = PFREE;
+		break;
+#endif				/* Q_OUTFITTING */
+	    case 'R':
+		warning("Are you sure you want to reset your stats?");
+		resetting = 1;
+		break;
+	    case 'y':
+		if (resetting) {
+		    sendResetStatsReq('Y');
+		    warning("OK, your stats have been reset.");
+		    resetting = 0;
+		}
+		break;
+	    case 'n':
+		if (resetting) {
+		    warning("I didn't think so.");
+		    resetting = 0;
+		}
+		break;
+
+	    case 'f':		/* Scroll motd forward */
+		if (currpage == NULL)
+		    currpage = motddata;
+		if (currpage == NULL || currpage->next == NULL)
+		    break;
+		currpage->next->prev = currpage;
+		currpage = currpage->next;
+		showMotd(w);
+		resetting = 0;
+		break;
+	    case 'b':		/* Scroll motd backward */
+		if (currpage == NULL || currpage->prev == NULL)
+		    break;
+		currpage = currpage->prev;
+		showMotd(w);
+		resetting = 0;
+		break;
+		/* ok, let's have some info windows available on the TQ */
+
+	    default:		/* hmm, something that doesn't have to do
+				   with the MOTD, maybe it's an info window
+				   request */
+		switch (doKeymap(&event)) {
+		case 'U':	/* U = Rank list */
+		    if (W_IsMapped(rankw)) {
+			W_UnmapWindow(rankw);
+		    } else {
+			W_MapWindow(rankw);
+		    }
+		    break;
+		case 'P':	/* P = Planet list */
+		    if (W_IsMapped(planetw)) {
+			W_UnmapWindow(planetw);
+			W_UnmapWindow(planetw2);
+		    } else {
+			W_MapWindow(planetw);
+			W_MapWindow(planetw2);
+		    }
+		    break;
+		case 'h':	/* h = Map help window */
+		    if (W_IsMapped(helpWin)) {
+			W_UnmapWindow(helpWin);
+		    } else {
+			W_MapWindow(helpWin);
+		    }
+		    if (optionWin)
+			optionredrawtarget(helpWin);
+		    break;
+		case 'O':	/* O = options Window */
+		    if (optionWin != NULL && W_IsMapped(optionWin))
+			optiondone();
+		    else
+			optionwindow();
+		    break;
+		case 'w':	/* w = map war stuff */
+		    if (W_IsMapped(war))
+			W_UnmapWindow(war);
+		    else
+			warwindow();
+		    break;
+		case '&':
+		    if (defaultsFile) {
+			char    buf[150];
+			sprintf(buf, "Reading defaults from %s", defaultsFile);
+			warning(buf);
+			freeDefaults();
+			defaultsFile = initDefaults(defaultsFile);
+			resetDefaults();
+		    } else {
+			warning("No defaults file to read from!");
+		    }
+		}
+		break;
+	    }
+
+	    break;		/* switch event type */
+	}
+	if (event.Window == qwin)
+	    return;		/* normal keypresses can't make you quit */
+
+	if (event.Window == optionWin) {
+	    optionaction(&event);
+	    return;
+	}
+	if (!validshipletter)
+	    break;
+	/*
+	   it wasn't the main window, see if they hit the key in a team
+	   window to choose their ship... falling through
+	*/
+    case W_EV_BUTTON:
+
+	for (i = 0; i < number_of_teams; i++)
+	    if (event.Window == teamWin[i]) {
+		*team = i;
+		break;
+	    }
+	if (event.Window == qwin) {
+	    *team = number_of_teams;
+	    me->p_status = PFREE;
+	    break;
+	}
+	/* allow message scrollback [BDyess] */
+	for (i = 0; i < WNUM; i++) {
+	    if (event.Window == messWin[i].window) {
+		messageWinEvent(&event);
+		break;
+	    }
+	}
+	/* allow bozo selection in playerw [BDyess] */
+	if (event.Window == playerw) {
+	    playerwEvent(&event);
+	    break;
+	} else if (event.Window == war)
+	    waraction(&event);
+	else if (event.Window == optionWin)
+	    optionaction(&event);
+	if (*team != -1 && !teamRequest(*team, *s_type)) {
+	    *team = -1;
+	}
+	break;
+    case W_EV_EXPOSE:
+	for (i = 0; i < number_of_teams; i++)
+	    if (event.Window == teamWin[i]) {
+		lastplayercount[i] = -1;	/* force update */
+		redrawTeam(teamWin[i], i, &lastplayercount[i]);
+		break;
+	    }
+	if (event.Window == qwin)
+	    redrawQuit();
+	else if (event.Window == w)
+	    showMotd(w);
+	else if (event.Window == mapw) {
+#ifdef COW_HAS_IT_WHY_SHOULDNT_WE
+	    if(showMapAtMotd) {
+		map();
+		redraw_death_messages();
+	    } else
+#endif
+		showValues(mapw);
+	} else
+	    /* let the normal expose handler figure out who to redraw */
+	    dispatch_W_expose_event(&event);
+	break;
+    }
+
+    if (oldresetting && resetting) {
+	resetting = 0;
+	warning("Resetting of stats cancelled");
+    }
+}
+
+void
+new_entrywindow(team, s_type)
+    int    *team, *s_type;
+{
+    int     i;
+    int     lastplayercount[4];	/* number of players on each team */
+    int     okayMask, lastOkayMask;	/* teams you're allowed to choose */
+    char    buf[100];
+
+    /* OUTFIT timeout stuff */
+    long    startTime = -1;
+    long    lasttime = -1;
+    int     spareTime = 0;
+
+    if (fastQuit) {
+	*team = -1;
+	return;
+    }
+    lastOkayMask = okayMask = tournMask;
+
+#ifdef PACKET_LIGHTS
+    /* erase packet lights to make Bob happy [BDyess] */
+    light_erase();
+#endif				/* PACKET_LIGHTS */
+
+    /*
+       map all team selection windows, and stripe out those that are
+       unchoosable
+    */
+    for (i = 0; i < number_of_teams; i++) {
+	if (okayMask & (1 << i))
+	    W_UnTileWindow(teamWin[i]);
+	else
+	    W_TileWindow(teamWin[i], stipple);
+
+	W_MapWindow(teamWin[i]);
+	lastplayercount[i] = -1;
+    }
+    W_MapWindow(qwin);
+
+    /* no team selected yet */
+    *team = -1;
+    /*
+       set to team index (0..n-1) to choose a team. set to n if you want to
+       quit
+    */
+
+    /* I don't know why this restriction is in place - RF */
+    if (me->p_whydead != KWINNER && me->p_whydead != KGENOCIDE) {
+	showMotd(w);
+#ifdef COW_HAS_IT_WHY_SHOULDNT_WE
+	if(showMapAtMotd) {
+	    map();
+	    redraw_death_messages();
+	} else
+#endif
+	    showValues(mapw);
+    }
+    do {
+
+	/* set team to n if you want to quit */
+	while (!W_EventsPending() && (me->p_status == POUTFIT ||
+				      me->p_status == PTQUEUE)) {
+	    /* no window events, just process socket stuff */
+	    fd_set  mask;
+
+#ifdef PACKET_LIGHTS
+	    light_erase();
+#endif				/* PACKET_LIGHTS */
+
+	    readFromServer();
+
+	    if (me->p_status == POUTFIT || me->p_status == PTQUEUE) {
+		/* wait up to a half-second for input from the window system */
+		struct timeval tv;
+
+#ifndef AMIGA
+		tv.tv_sec = 0;
+		tv.tv_usec = 500000;
+
+		FD_ZERO(&mask);
+		FD_SET(W_Socket(), &mask);
+		select(W_Socket() + 1, &mask, 0, 0, &tv);
+#else
+		StartTimer(0, 500000);
+		while (1) {
+#ifdef DNET
+		    sigsPending = Wait(W_Socket() | portmask | sockMask | udpSockMask | SIGBREAKF_CTRL_C);
+#else
+/* something else.... */
+#endif
+		    if (sigsPending & SIGBREAKF_CTRL_C) {
+			printf("Ctrl-c break from entrywindow!\n");
+			StopTimer();
+			exit(0);
+		    }
+		    if ((sigsPending & (W_Socket() | sockMask | udpSockMask)) ||
+			(CheckIO(&(ior->tr_node))))
+			break;
+		}		/* timer returns false signals, wish I knew
+				   why. :-( */
+		StopTimer();
+#endif				/* AMIGA */
+	    }
+
+#ifdef COW_HAS_IT_WHY_SHOULDNT_WE
+	    if(showMapAtMotd) {
+		map();
+		redraw_death_messages();
+	    }
+#endif
+
+	    if (me->p_status == PTQUEUE)
+		startTime = -1;
+
+	    if (me->p_status == POUTFIT) {
+		/* time only elapses in OUTFIT mode */
+
+		if (startTime == -1) {	/* we were on the tqueue */
+		    /* I hate this [BDyess] */
+#if 1
+		    W_Deiconify(baseWin);	/* we changed status.  alert
+						   the user */
+#endif
+		    startTime = time(0);
+		    spareTime = 480;	/* Allow them extra time, as long */
+		    /* as they are active */
+		}
+		elapsed = time(0) - startTime;
+
+		if (elapsed > autoQuit) {
+		    printf("Auto-Quit.\n");
+		    *team = number_of_teams;
+		    break;
+		}
+	    }
+	    if (lasttime != time(0)) {
+		if (W_IsMapped(playerw))
+		    playerlist2();
+
+		if (newMotdStuff) {
+		    showMotd(w);
+#ifdef COW_HAS_IT_WHY_SHOULDNT_WE
+		    if(showMapAtMotd) {
+			map();
+			redraw_death_messages();
+		    } else
+#endif
+			showValues(mapw);
+		}
+		if (me->p_status == POUTFIT) {
+		    showTimeLeft(elapsed, autoQuit);
+		}
+		lasttime = time(0);
+	    }
+	    okayMask = tournMask;
+
+	    /* redraw those windows whose choosable status has changed */
+	    for (i = 0; i < number_of_teams; i++) {
+		if ((okayMask ^ lastOkayMask) & (1 << i)) {
+		    if (okayMask & (1 << i)) {
+			W_UnTileWindow(teamWin[i]);
+		    } else {
+			W_TileWindow(teamWin[i], stipple);
+		    }
+		    lastplayercount[i] = -1;	/* force update */
+		}
+		redrawTeam(teamWin[i], i, &lastplayercount[i]);
+	    }
+	    lastOkayMask = okayMask;
+	}
+
+#ifdef RECORDER
+	if (playback)  /* silly.  Shouldn't even be mapping team windows. */
+	    break;
+#endif
+	/* they quit or ran out of time */
+	if (*team == number_of_teams) {
+	    me->p_status = PFREE;	/* exit outer while loop */
+	    break;
+	}
+	/*
+	   this makes them eventually run out of time no matter how awake
+	   they are.  Only affects the OUTFIT screen.
+	*/
+	if (me->p_status == POUTFIT && startTime != -1) {
+	    if (time(0) - startTime <= spareTime) {
+		spareTime -= time(0) - startTime;
+		startTime = time(0);
+	    } else {
+		startTime += spareTime;
+		spareTime = 0;
+	    }
+	}
+	if (!W_EventsPending())
+	    continue;
+
+	/* ok, there's a window event pending */
+
+	/* thiswill set p_status to PFREE if they decide to quit */
+	get_N_dispatch_outfit_event(team, s_type, lastplayercount);
+
+    } while ((me->p_status == POUTFIT ||
+	      me->p_status == PTQUEUE)
+#ifdef RECORDER
+	     && (!pb_update)
+#endif
+	);
+
+    if (*team >= 0) {
+	strcpy(buf, "Welcome aboard ");
+	if (paradise)
+	    strcat(buf, ranks2[me->p_stats2.st_rank].name);
+	else
+	    strcat(buf, ranks[me->p_stats.st_rank].name);
+	sprintf(buf, "Welcome aboard %s!", get_players_rank_name(me));
+	warning(buf);
+    }
+#ifdef RECORDER
+    if (playback) {
+	extern int lastTeamReq;
+	*team = me->p_teami = lastTeamReq;
+    } else
+#endif
+	/* if they quit or ran out of time */
+    if (me->p_status == PFREE)
+	*team = -1;
+    else if (me->p_status == PALIVE ||
+	     me->p_status == POBSERVE)
+	if (*team == -1)
+	    *team = me->p_teami;
+	else
+	    me->p_teami = *team;
+
+
+    for (i = 0; i < number_of_teams; i++)
+	W_UnmapWindow(teamWin[i]);
+    W_UnmapWindow(qwin);
+}
+
+/* Attempt to pick specified team & ship */
+static int
+teamRequest(team, ship)
+    int     team, ship;
+{
+    int     lastTime;
+
+#ifdef RECORDER
+    extern int lastTeamReq;
+
+    if (!playback)
+	lastTeamReq = team;
+#endif
+#ifdef TIMELORD
+    if (!allowed_to_keep_playing()) {
+	warning("You've played enough for today.  Get back to work!");
+	return 0;
+    }
+#endif
+    pickOk = -1;
+    sendTeamReq(team, ship);
+    lastTime = time(NULL);
+    while (pickOk == -1) {
+	if (lastTime + 3 < time(NULL)) {
+	    sendTeamReq(team, ship);
+	    lastTime = time(NULL);
+	}
+	socketPause(0, 20000);
+	readFromServer();
+	if (isServerDead()) {
+	    printf("Whoops!  We've been ghostbusted!\n");
+	    printf("Pray for a miracle!\n");
+
+	    /* UDP fail-safe */
+	    commMode = commModeReq = COMM_TCP;
+	    commSwitchTimeout = 0;
+	    if (udpSock >= 0)
+		closeUdpConn();
+	    if (udpWin) {
+		udprefresh(UDP_CURRENT);
+		udprefresh(UDP_STATUS);
+	    }
+	    connectToServer(nextSocket);
+	    printf("Yea!  We've been resurrected!\n");
+	    pickOk = 0;
+	    break;
+	}
+#if 0				/* >this< is redundant ;-) */
+	if (me->p_status == PALIVE) {	/* well, something happened and we've
+					   got a ship! */
+	    pickOk = 1;
+	    break;
+	}
+#endif
+    }
+
+#if 1				/* this is not redundant? */
+    if (pickOk) {
+	me->p_status = PALIVE;	/* we got a ship.  We must be alive */
+#ifdef TIMER
+	timeBank[T_SHIP] = time(NULL);
+#endif				/* TIMER */
+    }
+#endif
+    return (pickOk);
+}
+
+static int
+numShips(owner)
+    int     owner;
+{
+    int     i, num = 0;
+    struct player *p;
+
+    for (i = 0, p = players; i < nplayers; i++, p++)
+	if ((p->p_status == PALIVE || p->p_status == PTQUEUE)
+	    && p->p_teami == owner)
+	    num++;
+    return (num);
+}
+
+#if 0
+int
+realNumShips(owner)
+    int     owner;
+{
+    int     i, num = 0;
+    struct player *p;
+
+    for (i = 0, p = players; i < MAXPLAYER; i++, p++)
+	if (p->p_status != PFREE &&
+	    p->p_team == owner)
+	    num++;
+    return (num);
+}
+#endif
+
+#if 0
+int
+deadTeam(owner)
+    int     owner;
+/* The team is dead if it has no planets and cannot coup it's home planet */
+{
+    int     i, num = 0;
+    struct planet *p;
+
+    if (planets[remap[owner] * 10 - 10].pl_couptime == 0)
+	return (0);
+    for (i = 0, p = planets; i < MAXPLANETS; i++, p++) {
+	if (p->pl_owner & owner) {
+	    num++;
+	}
+    }
+    if (num != 0)
+	return (0);
+    return (1);
+}
+#endif
+
+static int
+checkBold(line)
+/* Determine if that line should be highlighted on sign-on screen */
+/* Which is done when it is the players own score being displayed */
+    char   *line;
+{
+    char   *s, *t;
+    int     i;
+    int     end = 0;
+
+    if ((int) strlen(line) < 60)
+	return (0);
+    s = line + 4;
+    if (!me)
+	return (0);
+    t = me->p_name;
+
+    for (i = 0; i < 16; i++) {
+	if (!end) {
+	    if (*t == '\0')
+		end = 1;
+	    else if (*t != *s)
+		return (0);
+	}
+	if (end) {
+	    if (*s != ' ')
+		return (0);
+	}
+	s++;
+	t++;
+    }
+    return (1);
+}
+
+struct list {
+    char    bold;
+    struct list *next;
+    char   *data;
+};
+static struct list *sysdefptr = NULL;
+
+void
+showMotd(win)
+    W_Window win;
+{
+    FILE   *fopen();
+    int     i;
+    struct list *data;
+    int     count;
+    int     headernum;
+
+    newMotdStuff = 0;		/* clear the flag */
+
+    if (currpage == NULL)
+	currpage = motddata;
+    if (currpage == NULL)
+	return;
+    if (!W_IsMapped(win))
+	return;
+
+    headernum = currpage->page % NRHEADERS;
+    W_ClearWindow(win);
+    W_WriteWinBitmap(win, 0, 0, headerA, foreColor);
+    W_WriteWinBitmap(win, headerA_width, 0, headerB, foreColor);
+    W_WriteWinBitmap(win, headerA_width, headerB_height, headerchanges[headernum], foreColor);
+    if (headernum == 2) {	/* fill in client: */
+	/* note: font dependant */
+	W_WriteText(win, headerA_width + header3_x_hot, headerB_height + header3_y_hot
+		- 7, textColor, CLIENTVERS, strlen(CLIENTVERS), W_BoldFont);
+    } else if (headernum == 3) {/* fill in server: */
+	;
+    }
+    if (currpage->first) {
+	currpage->first = 0;
+	data = currpage->text;
+	while (data != NULL) {
+	    data->bold = checkBold(data->data);
+	    data = data->next;
+	}
+    }
+    data = currpage->text;
+    count = LINESPERPAGE;	/* Magical # of lines to display */
+    i = headerA_height / (paradise ? 10 : W_Textheight) + 1;
+    while (count > 0) {
+	if (data == NULL)
+	    break;
+
+	if (data->bold) {
+	    W_WriteText(win, 20, i * (paradise ? 10 : W_Textheight), textColor, data->data,
+			strlen(data->data), W_BoldFont);
+	} else {
+	    W_WriteText(win, 20, i * (paradise ? 10 : W_Textheight), textColor, data->data,
+			strlen(data->data), W_RegularFont);
+	}
+	data = data->next;
+	count--;
+	i++;
+    }
+    if (win == w) {
+	count = W_StringWidth(blk_refitstring, W_RegularFont) / 2;
+	W_WriteText(mapw, 250 - count, 480, textColor, blk_refitstring,
+		    strlen(blk_refitstring), W_RegularFont);
+    }
+    showPics(win);
+/*    showValues(mapw); Should be handled in event loop now RF */
+}
+
+static void
+showPics(win)
+    W_Window win;
+{
+    struct piclist *temp;
+    int     page;
+
+    page = currpage->page;
+    temp = motdPics;
+
+    while (temp != NULL) {
+	if (page == temp->page) {
+	    if (temp->thepic)
+		W_WriteWinBitmap(win, temp->x, temp->y, temp->thepic, foreColor);
+	    else {
+		W_MakeLine(win, temp->x, temp->y,
+			   temp->x + temp->width - 1, temp->y + temp->height - 1, W_Grey);
+		W_MakeLine(win, temp->x, temp->y + temp->height - 1,
+			   temp->x + temp->width - 1, temp->y, W_Grey);
+		W_MakeLine(win, temp->x, temp->y,
+			   temp->x + temp->width - 1, temp->y, W_Grey);
+		W_MakeLine(win, temp->x, temp->y,
+			   temp->x, temp->y + temp->height - 1, W_Grey);
+		W_MakeLine(win, temp->x, temp->y + temp->height - 1,
+			   temp->x + temp->width - 1, temp->y + temp->height - 1, W_Grey);
+		W_MakeLine(win, temp->x + temp->width - 1, temp->y + temp->height - 1,
+			   temp->x + temp->width - 1, temp->y, W_Grey);
+	    }
+	}
+	temp = temp->next;
+    }
+}
+
+/*
+ * ATM: show the current values of the .sysdef parameters.
+ */
+void
+showValues(win)
+    W_Window win;
+{
+    int     i;
+    struct list *data;
+
+    /* try to find the start of the info */
+    data = sysdefptr;
+
+    for (i = 12; i < 50; i++) {
+	if (data == NULL)
+	    break;
+	if (data->data[0] == '+')	/* quick boldface hack */
+	    W_WriteText(win, 20, i * W_Textheight, textColor, data->data + 1,
+			strlen(data->data) - 1, W_BoldFont);
+	else
+	    W_WriteText(win, 20, i * W_Textheight, textColor, data->data,
+			strlen(data->data), W_RegularFont);
+	data = data->next;
+    }
+}
+
+#define	BETWEEN_PAGES	0
+#define	IN_PAGE		1
+#define	IN_SYSDEF	3
+
+static int motdlinestate = BETWEEN_PAGES;
+static int pagecount = 0;
+static struct list **temp = NULL;
+static struct page **ptemp = NULL;
+static int linecount = 0;
+static struct piclist **motd_buftail = &motdPics;
+
+void
+erase_motd()
+{
+    struct piclist *temppic;
+    struct page *temppage;
+    struct list *templist;
+
+    while (motdPics) {
+	temppic = motdPics;
+	motdPics = temppic->next;
+	if (temppic->thepic)
+	    W_FreeBitmap(temppic->thepic);
+	free(temppic);
+    }
+    motd_buftail = &motdPics;
+
+    while (motddata) {
+	temppage = motddata;
+	motddata = temppage->next;
+	while (temppage->text) {
+	    templist = temppage->text;
+	    temppage->text = templist->next;
+	    free(templist->data);
+	    free(templist);
+	}
+	free(temppage);
+    }
+    motdlinestate = BETWEEN_PAGES;
+    currpage = 0;
+    pagecount = 0;
+    temp = 0;
+    ptemp = 0;
+    linecount = 0;
+
+    while (sysdefptr) {
+	templist = sysdefptr;
+	sysdefptr = templist->next;
+	free(templist->data);
+	free(templist);
+    }
+}
+
+void
+newMotdPic(x, y, width, height, bits, page)
+    int     x, y, page, width, height;
+    char   *bits;
+{
+    struct piclist *temp;
+
+    {
+	struct motd_pic_spacket dummy;
+	if ((width + 7) / 8 * height > sizeof(dummy.bits) && bits) {
+	    fprintf(stderr, "MOTD picture from server is too big!  %dx%d couldn't possibly fit in the %d data bytes of the packet\n",
+		    width, height, (int) sizeof(dummy.bits));
+	    return;
+	}
+    }
+    if ((currpage && page == currpage->page) || page == 0)
+	newMotdStuff = 1;	/* set flag for event loop */
+
+    temp = (*motd_buftail) = (struct piclist *) malloc(sizeof(struct piclist));
+    temp->next = NULL;
+    temp->x = x;
+    temp->y = y;
+    temp->width = width;
+    temp->height = height;
+    temp->thepic = bits ? W_StoreBitmap(width, height, bits, motdWin) : 0;
+    temp->page = page;
+    motd_buftail = &(temp->next);
+}
+
+void
+newMotdLine(line)
+    char   *line;
+{
+
+    /*
+       Do this first.  That way we don't even have to worry about it at all.
+    */
+
+    if (strncmp("BLK: ", line, 5) == 0) {
+	blk_parsemotd(line);
+	return;
+    }
+    if (strncmp("\t@@@", line, 4) == 0 && motdlinestate != IN_SYSDEF) {
+	motdlinestate = IN_SYSDEF;
+	temp = &sysdefptr;
+    }
+    if (strncmp("\t@@b", line, 4) == 0 && motdlinestate == IN_PAGE)
+	motdlinestate = BETWEEN_PAGES;
+
+    if (motdlinestate == BETWEEN_PAGES ||
+	(motdlinestate == IN_PAGE && linecount >= LINESPERPAGE)) {
+	if (motddata == NULL)
+	    ptemp = &motddata;
+	(*ptemp) = (struct page *) malloc(sizeof(struct page));
+	(*ptemp)->next = NULL;
+	(*ptemp)->first = 1;
+	(*ptemp)->prev = NULL;
+	(*ptemp)->page = pagecount++;
+	temp = &((*ptemp)->text);
+	(*ptemp)->text = NULL;
+	ptemp = &((*ptemp)->next);
+	motdlinestate = IN_PAGE;
+	linecount = 0;
+    }
+    if (strncmp("\t@@", line, 3) == 0)
+	return;
+
+    if (!currpage ||
+	(pagecount - 1) == currpage->page ||
+	motdlinestate == IN_SYSDEF)
+	newMotdStuff = 1;	/* set flag for event loop */
+
+    (*temp) = (struct list *) malloc(sizeof(struct list));
+    (*temp)->next = NULL;
+    (*temp)->data = (char *) malloc(strlen(line) + 1);
+    strcpy((*temp)->data, line);
+    temp = &((*temp)->next);
+
+    if (motdlinestate == IN_PAGE)
+	linecount++;
+}
+
+/*ARGSUSED*/
+static void
+getResources(prog)
+    char   *prog;
+{
+    getColorDefs();
+    getTiles();
+}
+
+static void
+getTiles()
+{
+    stipple = W_StoreBitmap(stipple_width, stipple_height, stipple_bits, w);
+}
+
+static void
+redrawTeam(win, teamNo, lastnum)
+    W_Window win;
+    int     teamNo;
+    int    *lastnum;
+{
+    char    buf[BUFSIZ];
+    int     num = numShips(teamNo);
+
+    /* Only redraw if number of players has changed */
+    if (*lastnum == num)
+	return;
+
+    drawIcon();
+
+    W_ClearWindow(win);
+    W_WriteBitmap(0, 0, teaminfo[teamNo].shield_logo, shipCol[teamNo + 1]);
+
+    (void) sprintf(buf, "%d", num);
+    W_MaskText(win, 5, 46, shipCol[teamNo + 1], buf, strlen(buf),
+	       W_BigFont);
+    *lastnum = num;
+}
+
+static void
+redrawQuit()
+{
+    /* W_WriteText(qwin, 5, 5, textColor, "Quit xtrek", 10, W_RegularFont); */
+    if (me->p_status == PTQUEUE) {
+	W_ClearArea(qwin, 0, 0, BOXSIDE, BOXSIDE);
+	W_WriteBitmap(0, 0, safepic, foreColor);
+    }
+}
+
+void
+drawIcon()
+{
+    if (!iconified) {
+	me_messages = 0;
+	team_messages = 0;
+	all_messages = 0;
+    }
+#ifdef AMIGA
+    /*
+       not sure this isn't appropriate for X as well.  This is called from
+       redrawTeam(),  so iconified is set, and then all my personal messages
+       beep...iconified or not.
+    */
+    if (W_IsMapped(iconWin))
+#endif
+	iconified = 1;
+    if (!infoIcon) {
+	W_WriteBitmap(0, 0, icon, W_White);
+    } else {			/* code for information icon 1/15 [BDyess] */
+	int     side, bottom, top, digits, x, i;
+	char    buf[50];
+
+	W_ClearWindow(iconWin);
+	side = icon_width / number_of_teams;
+	bottom = 0 + side;
+	top = 0;
+	W_MakeLine(iconWin, 0, bottom, icon_width, bottom, W_White);
+	for (i = 0; i <= number_of_teams; i++) {	/* draw the vertical
+							   lines */
+	    x = i * side;
+	    x = (x > icon_width) ? icon_width : x;
+	    W_MakeLine(iconWin, x, bottom, x, top, W_White);
+	}
+	for (i = 0; i < number_of_teams; i++) {
+	    sprintf(buf, "%d", numShips(i));
+	    digits = strlen(buf);
+	    W_WriteText(iconWin, i * side + side / 2 - digits * W_Textwidth / 2,
+			bottom - side / 2 - W_Textheight / 2,
+			shipCol[i + 1], buf, digits, W_RegularFont);
+	}
+	if (me->p_status == PALIVE) {
+#define TOP icon_height-10
+	    if (me->p_flags & PFGREEN)
+		W_FillArea(iconWin, 0, TOP, icon_width,
+			   icon_height, W_Green);
+	    else if (me->p_flags & PFYELLOW)
+		W_FillArea(iconWin, 0, TOP,
+			   icon_width, icon_height, W_Yellow);
+	    else if (me->p_flags & PFRED)
+		W_FillArea(iconWin, 0, TOP,
+			   icon_width, icon_height, W_Red);
+	}
+	if (me_messages) {
+	    sprintf(buf, "Personal: %d", me_messages);
+	    W_WriteText(iconWin, 1, bottom + 2, W_White, buf, strlen(buf),
+			W_RegularFont);
+	}
+	if (team_messages) {
+	    sprintf(buf, "Team:     %d", team_messages);
+	    W_WriteText(iconWin, 1, bottom + 2 + W_Textheight, W_White, buf,
+			strlen(buf), W_RegularFont);
+	}
+	if (all_messages) {
+	    sprintf(buf, "All:      %d", all_messages);
+	    W_WriteText(iconWin, 1, bottom + 2 + 2 * W_Textheight, W_White, buf,
+			strlen(buf), W_RegularFont);
+	}
+	if (me->p_status == POUTFIT) {
+	    sprintf(buf, "Time left: %d", autoQuit - elapsed);
+	    W_WriteText(iconWin, 1, bottom + 2 + W_Textheight, W_White, buf,
+			strlen(buf), W_RegularFont);
+	}
+    }
+}
+
+#define CLOCK_WID	BOXSIDE
+#define CLOCK_HEI	BOXSIDE
+#define CLOCK_BDR	0
+
+#ifndef PI
+#define PI		3.141592654
+#endif				/* PI */
+
+static void
+showTimeLeft(time, max)
+    int     time, max;
+{
+    char    buf[BUFSIZ];
+    int     cx, cy, ex, ey, tx, ty;
+
+    if ((max - time) < 10 && time & 1) {
+	W_Beep();
+	W_Deiconify(baseWin);
+    }
+    if (iconified)
+	drawIcon();
+    /* XFIX */
+    W_ClearArea(qwin, 0, 0, BOXSIDE, BOXSIDE);
+
+    W_WriteBitmap(0, 0, clockpic, foreColor);
+
+    cx = BOXSIDE / 2;
+    cy = BOXSIDE / 2 - 6;
+    ex = cx - 35 * Sin[((255 * time) / max + 64) % 256];
+    ey = cy - 35 * Cos[((255 * time) / max + 64) % 256];
+    W_MakeLine(qwin, cx, cy, ex, ey, foreColor);
+
+    sprintf(buf, "%d", max - time);
+    cy = BOXSIDE / 2 - 1;
+    tx = cx - W_StringWidth(buf, W_RegularFont) / 2.0;
+    ty = cy - W_Textheight;
+    W_WriteText(qwin, tx, ty, textColor, buf, strlen(buf), W_RegularFont);
+}
+
+
+void
+do_refit(type)
+    int     type;
+{
+    sendRefitReq(type);
+    localflags &= ~PFREFIT;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/oldbitmaps.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,832 @@
+/* $Id: oldbitmaps.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+static unsigned char ex_bits[5][512] = {{
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x01, 0x08,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0x08,
+	0x38, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x04, 0x0a, 0x00, 0x12, 0x00, 0x00, 0x10,
+	0x11, 0x00, 0x18, 0x00, 0x02, 0x00, 0x00, 0x00, 0x81, 0x06, 0x08, 0x10, 0x00, 0x00, 0x00,
+	0x08, 0x10, 0x1a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1c, 0x08, 0x02, 0x00, 0x00,
+	0x00, 0x04, 0x07, 0x0b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0b, 0x08, 0x18, 0x00, 0x00,
+	0x00, 0x00, 0xc4, 0xe0, 0x0f, 0x06, 0x00, 0x00, 0x00, 0x00, 0x70, 0x94, 0x15, 0x20, 0x00,
+	0x00, 0x00, 0x00, 0x30, 0xd5, 0x75, 0x20, 0x00, 0x00, 0x00, 0x00, 0x04, 0x95, 0x22, 0x00,
+	0x00, 0x00, 0x00, 0x20, 0x02, 0x60, 0x1b, 0x00, 0x00, 0x00, 0x80, 0x09, 0x00, 0xf4, 0x1e,
+	0x20, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0x01, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4,
+	0x26, 0x06, 0x00, 0x00, 0x00, 0x00, 0x04, 0x73, 0x28, 0x08, 0x00, 0x00, 0x00, 0x00, 0xc0,
+	0xa0, 0x26, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x00, 0x02, 0x00, 0x00, 0x00,
+	0x10, 0x00, 0x30, 0x0c, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x42, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x18, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x20, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xf0, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x01, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00},
+{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x40, 0x00,
+    0x00, 0x00, 0x80, 0x61, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x20, 0x00, 0xc0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x48, 0x04, 0x00,
+    0x00, 0x00, 0x08, 0x00, 0x4c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x04,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x04,
+    0x42, 0x01, 0x00, 0x00, 0x00, 0x00, 0x51, 0x08, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x40, 0x80, 0x00, 0x00, 0x04, 0x08, 0x00, 0x03, 0x00, 0x45, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0x07, 0x00, 0x80, 0x00, 0x00, 0x09, 0x08, 0x00, 0x89, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+    0x00, 0x03, 0xa0, 0xc0, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x25, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x20, 0x00, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x02, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x60, 0x12, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x22, 0x92, 0x00, 0x12,
+    0x00, 0x00, 0x10, 0x10, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x90, 0x00, 0x12, 0x42, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x48, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
+    0x47, 0x02, 0x00, 0x00, 0x00, 0x00, 0x20, 0x28, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x42, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x04, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0xc0, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x82, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00, 0x03, 0x00, 0x80, 0x00, 0x80, 0x01, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x20, 0xc0, 0x01, 0x00, 0xc0, 0x21, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+    0x00, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x60, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00},
+{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+    0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x40,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x48, 0x02, 0x00, 0x08, 0x00,
+    0x00, 0x80, 0x01, 0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x20,
+    0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+    0x08, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x04,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x09, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x91, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x20, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x40, 0x44, 0x40, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x30, 0x41, 0x82, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00, 0x05, 0x00,
+    0x05, 0x00, 0x00, 0x00, 0x01, 0x88, 0x06, 0x45, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x29,
+    0x00, 0x00, 0x00, 0x00, 0x30, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x20,
+    0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x22, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x12, 0x04, 0x00, 0x00, 0x00, 0x00,
+    0x01, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x90, 0x20, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x20, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01,
+    0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x80,
+    0x21, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00},
+{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+    0x40, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x11, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00,
+    0x00, 0x00, 0x02, 0x40, 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x02, 0x10, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+    0x40, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x82, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40, 0x00, 0x08, 0x02, 0x00,
+    0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+    0x80, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00,
+    0x00, 0x00, 0x04, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00,
+    0x00, 0x04, 0x00, 0x08, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
+    0x00, 0x00, 0x00, 0x08, 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x0c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x30, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00},
+{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x04, 0x04, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x20, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x24, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x42, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00,
+    0x00, 0x20, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00,
+    0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x44, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x80, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x09, 0x20, 0x00, 0x00, 0x00, 0x01, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00}};
+
+static unsigned char sbexp_bits[7][800] = {{
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x81, 0x04, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xf2, 0x1f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xbe, 0x7c, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xf6, 0x4f, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xde, 0x7d, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xea, 0xef, 0x01, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xff, 0x55, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xdd, 0xfd, 0x03, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xbf, 0xae, 0x22, 0x36, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0xdb, 0xf7, 0x3f, 0x1e, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x80, 0x50, 0xbf, 0xbf, 0x85, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xff, 0xe5, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xee, 0x7e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x74, 0x4b, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xe8, 0x3e, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0xf8, 0x49, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x54, 0x07, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x78, 0x91, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x60, 0xf1, 0x53, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x40, 0x97, 0x5c, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xa0, 0x0c, 0x8c, 0x1b, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xc4, 0x01, 0x00, 0xc8, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x88, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x60, 0x00, 0x02, 0x40, 0x02, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x70, 0x00, 0x0c, 0x40, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x70, 0xe0, 0x0d, 0x00, 0x04, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x72, 0xc8, 0x07, 0x40, 0x08, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x02, 0x78, 0x2f, 0x40, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x40, 0x02, 0xb0, 0x0a, 0x20, 0x77, 0x00, 0x00,
+    0x00, 0x00, 0x40, 0x13, 0x10, 0x33, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0xc0, 0x02, 0x78, 0xbb, 0x81, 0x09, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x02, 0xdc, 0xe7, 0x00, 0x09, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xac, 0x78, 0x00, 0x31, 0x00, 0x00,
+    0x00, 0x00, 0x40, 0x03, 0x74, 0x4b, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x02, 0xe8, 0x3e, 0x00, 0x01, 0x10, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0xf8, 0x49, 0x80, 0x09, 0x1c, 0x00,
+    0x00, 0x00, 0x00, 0x0c, 0x40, 0x07, 0x00, 0x05, 0x1c, 0x00,
+    0x00, 0x00, 0x80, 0x09, 0x04, 0x80, 0x00, 0x02, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x1d, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0xe3, 0x0b, 0x00, 0x22, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x8f, 0x10, 0x00, 0xa0, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x4f, 0x20, 0x78, 0x60, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x80, 0x79, 0x18, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x78, 0x7c, 0x05, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x03, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x02, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x18, 0xc0, 0x04, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x84, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x60, 0x06, 0x0c, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x07, 0x64, 0x3a, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x08, 0x72, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x3b, 0x00, 0x00, 0xc0, 0x33, 0x00, 0x00,
+    0x00, 0x00, 0xa0, 0x1b, 0x00, 0x00, 0x80, 0x42, 0x00, 0x00,
+    0x00, 0x00, 0xd0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0x00, 0x00, 0x6a, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00,
+    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x80, 0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+    0x00, 0x30, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x80, 0x03, 0x03, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0xe2, 0x82, 0x03, 0x00, 0x20, 0x00, 0x00, 0x40, 0x00,
+    0x00, 0x0e, 0x80, 0x03, 0x00, 0x4c, 0x00, 0x00, 0x10, 0x00,
+    0x00, 0x0e, 0x80, 0x03, 0xec, 0x10, 0x00, 0x00, 0x60, 0x00,
+    0x00, 0x12, 0x00, 0x00, 0x05, 0x93, 0x01, 0x00, 0x20, 0x00,
+    0x00, 0x12, 0x00, 0x00, 0x00, 0x5c, 0x0c, 0x00, 0x60, 0x00,
+    0x00, 0x30, 0x00, 0xc0, 0x05, 0x81, 0x10, 0x00, 0x00, 0x00,
+    0x00, 0x2c, 0x00, 0x00, 0xcc, 0x06, 0x00, 0x00, 0x20, 0x00,
+    0x00, 0x30, 0x00, 0x00, 0x28, 0x20, 0x02, 0x00, 0x00, 0x00,
+    0x00, 0x30, 0x80, 0x80, 0x22, 0x00, 0x02, 0x00, 0x00, 0x02,
+    0x00, 0x20, 0x00, 0x80, 0x02, 0x20, 0x08, 0x00, 0x20, 0x02,
+    0x00, 0x38, 0x00, 0x00, 0x00, 0x11, 0x28, 0x00, 0x20, 0x06,
+    0x00, 0x20, 0x00, 0x80, 0x0e, 0xc0, 0x21, 0x00, 0x5c, 0x00,
+    0x00, 0x24, 0x00, 0x90, 0x40, 0x58, 0x04, 0x00, 0x20, 0x01,
+    0x00, 0x24, 0x00, 0x10, 0x22, 0x02, 0x05, 0x00, 0x20, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x28, 0xb6, 0x00, 0x00, 0x20, 0x01,
+    0x00, 0x70, 0x00, 0x00, 0x18, 0xc1, 0x00, 0x00, 0xc0, 0x01,
+    0x00, 0xc0, 0x00, 0x00, 0x40, 0x83, 0x04, 0x00, 0xc0, 0x01,
+    0x00, 0x00, 0x01, 0x80, 0xfc, 0x41, 0x02, 0x00, 0x10, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x03, 0x30, 0x00, 0x00, 0x10, 0x00,
+    0x00, 0x10, 0x02, 0x00, 0x40, 0x1d, 0x00, 0x00, 0x20, 0x00,
+    0x00, 0x30, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x20, 0x00,
+    0x00, 0x00, 0x04, 0x00, 0x60, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+    0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
+    0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00,
+    0x00, 0x00, 0x38, 0x00, 0x81, 0x0f, 0x00, 0x00, 0x2a, 0x00,
+    0x00, 0x00, 0xf8, 0x02, 0x80, 0x0f, 0x00, 0x00, 0x10, 0x00,
+    0x00, 0x00, 0xf8, 0x02, 0x80, 0x0f, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x06, 0xc0, 0x01, 0x00, 0x00, 0x07, 0x00,
+    0x00, 0x00, 0x00, 0x14, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x70, 0x00, 0x00, 0x85, 0x00, 0x00,
+    0x00, 0x00, 0xc0, 0x00, 0x30, 0x00, 0x20, 0x3c, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xe0, 0xe0, 0x80, 0x00, 0x0b, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xe0, 0x79, 0x83, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x19, 0x22, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x28, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+    0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+    0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x80, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0xe0, 0x03, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x03, 0x00, 0x00, 0x00, 0x02, 0x90, 0x00, 0x00, 0x00, 0x40,
+    0x02, 0x02, 0x00, 0x80, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x40, 0x00, 0x00, 0x40, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x20, 0x00, 0x04, 0x02, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x30, 0x28, 0x90, 0x05, 0x00, 0x00, 0x40,
+    0x00, 0x00, 0x00, 0x48, 0x05, 0x00, 0x21, 0x00, 0x00, 0x0c,
+    0x00, 0x00, 0x00, 0x84, 0x00, 0x54, 0x05, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x40, 0x05, 0x80, 0x41, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x01, 0x00, 0x00, 0x20,
+    0x00, 0x00, 0x00, 0x08, 0x20, 0x20, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x84, 0x82, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x40,
+    0x04, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x21, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x90, 0x40, 0x40, 0x04, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x41, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x40, 0xa0, 0x00, 0x00, 0x00, 0x50,
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x40,
+    0x40, 0x00, 0x00, 0x00, 0x40, 0x02, 0x04, 0x00, 0x00, 0x30,
+    0x00, 0x00, 0x00, 0x80, 0x84, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0xc2, 0x20, 0x20, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x10, 0xc0, 0x05, 0x20, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x02, 0x00, 0x00, 0x10,
+    0x08, 0x00, 0x00, 0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x08,
+    0x10, 0x02, 0x00, 0x00, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+    0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x18, 0x08, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x08, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x3a, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x40, 0x04,
+    0x00, 0x60, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x04,
+    0x00, 0xb8, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x40, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x10, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+    0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x08, 0x00, 0x00,
+    0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x1f, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x40, 0x00, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00,
+    0x00, 0x00, 0x60, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x01, 0x00, 0x01, 0x10, 0x04, 0x00, 0x00,
+    0x00, 0x40, 0x00, 0x02, 0x02, 0x90, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x03, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x1c, 0x20, 0x05, 0x00, 0x04, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x14, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x40, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xc4, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x40, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x10, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00,
+    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x42, 0x00, 0x00, 0x04, 0x20, 0x01, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x81, 0x07, 0x01, 0x03, 0x00, 0x00,
+    0x00, 0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x02, 0x80, 0x20, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x80, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0xc0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x40, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x02, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x40, 0x0d, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1f, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+    0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
+    0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x00,
+    0x02, 0x02, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0xc0, 0x00, 0x40, 0x00, 0x02, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x00,
+    0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01,
+    0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+    0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x80, 0x06, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
+{
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x80, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+    0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+    0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
+/*#define drone_width 6*/
+/*#define drone_height 6*/
+
+#ifndef NDRONEVIEWS
+#define	NDRONEVIEWS	16
+#endif
+static unsigned char drone_bits[NDRONEVIEWS][6] = {
+    {0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x1e},
+    {0x18, 0x18, 0x0c, 0x0e, 0x0f, 0x0e},
+    {0x00, 0x18, 0x1c, 0x0f, 0x07, 0x06},
+    {0x00, 0x30, 0x3f, 0x0f, 0x07, 0x02},
+    {0x00, 0x03, 0x3f, 0x3f, 0x03, 0x00},
+    {0x02, 0x07, 0x0f, 0x3f, 0x30, 0x00},
+    {0x06, 0x07, 0x0f, 0x1c, 0x18, 0x00},
+    {0x0e, 0x0f, 0x0e, 0x0c, 0x18, 0x18},
+    {0x1e, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c},
+    {0x1c, 0x3c, 0x1c, 0x0c, 0x06, 0x06},
+    {0x18, 0x38, 0x3c, 0x0e, 0x06, 0x00},
+    {0x10, 0x38, 0x3c, 0x3f, 0x03, 0x00},
+    {0x00, 0x30, 0x3f, 0x3f, 0x30, 0x00},
+    {0x00, 0x03, 0x3f, 0x3c, 0x38, 0x10},
+    {0x00, 0x06, 0x0e, 0x3c, 0x38, 0x18},
+    {0x06, 0x06, 0x0c, 0x1c, 0x3c, 0x1c}
+};
+
+static unsigned char plasmacloud_bits[5][26] = {{
+	0x40, 0x00, 0xf2, 0x09, 0xfc, 0x07, 0xfc, 0x07, 0xfe, 0x0f, 0xfe, 0x0f, 0xff, 0x1f, 0xfe,
+0x0f, 0xfe, 0x0f, 0xfc, 0x07, 0xfc, 0x07, 0xf2, 0x09, 0x40, 0x00},
+{0x40, 0x00, 0x42, 0x08, 0x44, 0x04, 0xe8, 0x02, 0xf0, 0x01, 0xf8, 0x03, 0xff, 0x1f, 0xf8,
+0x03, 0xf0, 0x01, 0xe8, 0x02, 0x44, 0x04, 0x42, 0x08, 0x40, 0x00},
+{0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x48, 0x02, 0x50, 0x01, 0xe0, 0x00, 0xbc, 0x07, 0xe0,
+0x00, 0x50, 0x01, 0x48, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
+{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xb8, 0x03, 0x40,
+0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0xb8, 0x03, 0x40,
+0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
+static unsigned char cloud_bits[5][18] = {{
+	0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x28, 0x00, 0x54, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00},
+{0x00, 0x00, 0x28, 0x00, 0x54, 0x00, 0xaa, 0x00, 0x54, 0x00, 0xaa, 0x00, 0x54, 0x00, 0x28,
+0x00, 0x00, 0x00},
+{0x54, 0x00, 0xaa, 0x00, 0x55, 0x01, 0xaa, 0x00, 0x55, 0x01, 0xaa, 0x00, 0x55, 0x01, 0xaa,
+0x00, 0x54, 0x00},
+{0x00, 0x00, 0x28, 0x00, 0x54, 0x00, 0xaa, 0x00, 0x54, 0x00, 0xaa, 0x00, 0x54, 0x00, 0x28,
+0x00, 0x00, 0x00},
+{0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x28, 0x00, 0x54, 0x00, 0x28, 0x00, 0x10, 0x00, 0x00,
+0x00, 0x00, 0x00}};
+
+static unsigned char etorp_bits[] = {0x05, 0x02, 0x05};
+
+static unsigned char eplasmatorp_bits[] = {0x08, 0x2a, 0x1c, 0x7f, 0x1c, 0x2a, 0x08};
+
+static unsigned char mtorp_bits[] = {0x02, 0x07, 0x02};
+
+static unsigned char mplasmatorp_bits[] = {0x04, 0x0e, 0x1f, 0x0e, 0x04};
+
+/* Fighter bitmap */
+#ifndef fighter_width
+#define fighter_width 5
+#define fighter_height 5
+#endif
+static unsigned char fighter_bits[VIEWS][60] = {{
+0x04, 0x04, 0x0e, 0x1f, 0x04},
+{0x08, 0x04, 0x0f, 0x0e, 0x0a},
+{0x10, 0x0f, 0x0f, 0x0e, 0x0c},
+{0x01, 0x17, 0x0e, 0x07, 0x04},
+{0x02, 0x06, 0x1f, 0x06, 0x02},
+{0x04, 0x07, 0x0e, 0x17, 0x00},
+{0x0c, 0x0e, 0x0f, 0x0f, 0x10},
+{0x1a, 0x0e, 0x0f, 0x04, 0x08},
+{0x04, 0x1f, 0x0e, 0x04, 0x04},
+{0x0a, 0x0e, 0x1e, 0x04, 0x02},
+{0x06, 0x0e, 0x1e, 0x1e, 0x01},
+{0x04, 0x1c, 0x0e, 0x1d, 0x10},
+{0x08, 0x0c, 0x1f, 0x0c, 0x08},
+{0x00, 0x1d, 0x0e, 0x1c, 0x04},
+{0x01, 0x1e, 0x1e, 0x0e, 0x06},
+{0x02, 0x04, 0x1e, 0x0e, 0x0b}};
+
+static unsigned char warpbeacon_bits[] = {
+0x18, 0x24, 0x24, 0x24, 0x18, 0xdb, 0x3c, 0xdb, 0x18, 0x18, 0x3c, 0x18};
+
+static unsigned char warpflash_bits[] = {
+0x24, 0x18, 0x7e, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/option.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1029 @@
+/* $Id: option.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * option.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include "Wlib.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+
+#ifdef DEBUG
+#define IFDEBUG(foo)    foo
+#else
+#define IFDEBUG(foo)
+#endif
+
+static int notdone;		/* not done flag */
+static int oldzoom = -2;
+
+/* kludgy way to make options that do some action when clicked: */
+static int clearPhaserStats = 1;
+static int reloadShipBitmaps = 1;
+
+#ifdef ROTATERACE
+static int old_rotate, old_rotate_deg;
+#endif
+
+static int old_ping;
+
+/* static int updateSpeed= 5;*/
+static int lastUpdateSpeed = -1;
+
+static char newkeys[14];
+static char newckeys[14];
+static char newbuttons[14];
+static char newcbuttons[14];
+
+static int remapAllShips = 1;
+
+char *keymapmes[] = {
+    "Key/Buttonmap only affect THIS ship type",
+    "Key/Buttonmap affect ALL ship types",
+    ""
+};
+
+#ifdef TIMER
+char   *timermes[] =
+{"Timer shows nothing (off)",
+    "Timer shows time of day",
+    "Timer shows time on server",
+    "Timer shows time in ship",
+    "Timer shows user-set time",
+""};
+#endif				/* TIMER */
+
+char   *localmes[] =
+{"Show owner on local planets",
+    "Show facilities on local planets",
+    "Show nothing on local planets",
+    "Show surface properties on local planets",
+    "Show MOO facilities on local planets",
+""};
+
+char   *galacticmes[] =
+{"Show owner on galactic map",
+    "Show facilities on galactic map",
+    "Show nothing on galactic map",
+    "Show surface properties on galactic map",
+    "Show scout info age on galactic map",
+    "Show MOO facilities on galactic map",
+""};
+
+#ifdef ROTATERACE
+char   *rotatemess[] =
+{"Don't rotate galaxy",
+    "Rotate galaxy 90 degrees",
+    "Rotate galaxy 180 degrees",
+    "Rotate galaxy 270 degrees",
+    ""
+};
+#endif
+
+char   *mapupdates[] =
+{"Don't update galactic map",
+    "Update galactic map frequently",
+    "Update galactic map rarely",
+""};
+
+static char *lockoptions[] =
+{"Don't show lock icon",
+    "show lock icon on galactic map only",
+    "Show lock icon on tactical map only",
+"Show lock icon on both map windows", ""};
+
+static char *phaseroptions[] =
+{"Don't show phaser messages",
+    "Phaser messages in kill window",
+    "Phaser messages in phaser window",
+    "Phaser messages in phaser window only",
+    "Phaser messages in total review only",
+""};
+
+static char *dashboardoptions[] =
+{"Old Dashboard",
+    "New Dashboard",
+    "Color Dashboard",
+    "Rainbow Dashboard",
+""};
+
+static char *autoZoomOpts[] =
+{"Don't auto-zoom map",
+     "Auto-zoom map on Red OR Yellow Alert",
+     "Auto-zoom map on Red Alert",
+""};
+
+static char *autoUnZoomOpts[] =
+{"Don't auto-unzoom map",
+     "Auto-unzoom map on Green alert",
+     "Auto-unzoom map on Green OR Yellow Alert",
+""};
+
+static char *autoSetWarOpts[] = 
+{"Don't auto set war declarations",
+	"Set war with non-zero player teams",
+	"Set war with largest enemy team",
+""};
+
+/* useful for options that are an int with a range */
+struct int_range {
+    int     min_value;		/* value is >= this */
+    int     max_value;		/* value is <= this */
+    int     increment;		/* a click raises/lowers this amount */
+				/* do bitwise shift by 1 if increment */
+				/* == -1 */
+};
+
+
+/*
+ * Only one of op_option, op_targetwin, and op_string should be defined. If
+ * op_string is defined, op_size should be too and op_text is used without a
+ * "Don't" prefix. if op_range is defined, there should be a %d in op_text
+ * for it, op_size will be non-useful, and the 'Don't ' prefix won't appear
+ */
+struct option {
+    char   *op_text;		/* text to display when on */
+    int    *op_option;		/* variable to test/modify (optional) */
+    W_Window *op_targetwin;	/* target window to map/unmap (optional) */
+    char   *op_string;		/* string to modify (optional) */
+    int     op_size;		/* size of *op_string (optional) */
+    char  **op_array;		/* array of strings to switch between */
+    struct int_range *op_range;	/* struct definint an integer range option */
+
+    int     op_num;		/* used internally */
+};
+
+/* for the paged options menus */
+struct option_menu {
+    int     page_num;		/* page number of this menu */
+    struct option_menu *Next;
+    struct option *menu;	/* pointers to arrary of options */
+    int     numopt;		/* number of options in this menu page */
+    int     updated;		/* 1 if options can be changed externally */
+};
+
+/* pointer to first entry in the options menu list */
+static
+struct option_menu *FirstMenu = NULL;
+static
+struct option_menu *CurrentMenu = NULL;	/* menu currently looked at */
+int     MenuPage = 1;		/* current menu page */
+int     MaxOptions = 0;		/* maximum number of options in all menu
+				   pages */
+struct int_range MenuPages =
+{1, 1, 1};
+
+/* range of updates for keep-info-window-up option */
+struct int_range keepInfo_range =
+{0, 100, 1};
+
+/* updates: use of the int range thing... */
+struct int_range updates_range =
+{1, 10, 1};
+
+struct int_range redraw_delay_range =
+{0, 10, 1};
+
+/* range of menus. Will be updated when menu list is assembled */
+struct int_range Menus_Range =
+{1, 1, 1};
+
+#ifdef CONTINUOUS_MOUSE
+struct int_range clickDelay_range =
+{0, 20, 1};
+#endif				/* CONTINUOUS_MOUSE */
+
+#ifdef BEEPLITE
+struct int_range beeplite_planet_range =
+{0, 50, 1};
+struct int_range beeplite_player_range =
+{0, 50, 1};
+#endif
+
+struct int_range zoom_override_range =
+{0, 99, 1};
+
+#ifdef LOCAL_SHIPSTATS
+struct int_range statHeight_range =
+{4,100, 4};
+#endif
+
+/* range for tacPlanetInfo */
+struct int_range tacPlanetInfo_range = {0, 31, 1};
+
+/* menus */
+
+struct option Features_Menu[] =
+{
+    {"Defaults Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {0, &mapmode, 0, 0, 0, mapupdates, NULL},
+    {0, &showgalactic, 0, 0, 0, galacticmes, NULL},
+    {0, &showlocal, 0, 0, 0, localmes, NULL},
+#ifdef SHOW_IND
+    {"show IND planets", &showIND, 0, 0, 0, NULL, NULL},
+#endif
+    {"send MOTD bitmaps", &sendmotdbitmaps, 0, 0, 0, NULL, NULL},
+    {"reload ship bitmaps", &reloadShipBitmaps, 0, 0, 0, NULL, NULL},
+    {"stay peaceful when reborn", &keeppeace, 0, 0, 0, NULL, NULL},
+    {0, &remapAllShips, 0, 0, 0, keymapmes, NULL},
+    {"new keymap entries: %s_", 0, 0, newkeys, 13, NULL, NULL},
+    {"new ckeymap entries: %s_", 0, 0, newckeys, 13, NULL, NULL},
+    {"new buttonmap entries: %s_", 0, 0, newbuttons, 13, NULL, NULL},
+    {"new cbuttonmap entries: %s_", 0, 0, newcbuttons, 13, NULL, NULL},
+    {"report kill messages", &reportKills, 0, 0, 0, NULL, NULL},
+#if 0
+    /* need to figure out how to dispatch options */
+    {"recv variable packets", &recv_short, 0, 0, 0, NULL},
+    {"recv kill messages", &recv_kmesg, 0, 0, 0, NULL},
+#endif
+    {"keep info %d upds (0=forever)", &keepInfo, 0, 0, 0, 0, &keepInfo_range},
+    {"%d updates per second", &updateSpeed, 0, 0, 0, 0, &updates_range},
+    {"%d/10 sec screen refresh delay", &redrawDelay, 0, 0, 0, 0, &redraw_delay_range}, 
+    {"collect ping stats", &ping, 0, 0, 0, NULL, NULL},
+    {"avoid message kludge", &niftyNewMessages, 0, 0, 0, NULL, NULL},
+#ifdef CONTINUOUS_MOUSE
+    {"use continuous mouse", &continuousMouse, 0, 0, 0, NULL, NULL},
+    {"%d updates repeat delay", &clickDelay, 0, 0, 0, 0, &clickDelay_range},
+#endif				/* CONTINUOUS_MOUSE */
+#ifdef UNIX_SOUND
+    {"play sound effects", &playSounds, 0, 0, 0, NULL, NULL},
+#endif
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+struct option Window_Menu[] =
+{
+    {"Window Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"show \"all\" message window", 0, &messWin[WALL].window, 0, 0, NULL, NULL},
+    {"show \"team\" message window", 0, &messWin[WTEAM].window, 0, 0, NULL, NULL},
+    {"show \"your\" message window", 0, &messWin[WINDIV].window, 0, 0, NULL, NULL},
+    {"show \"kill\" message window", 0, &messWin[WKILL].window, 0, 0, NULL, NULL},
+    {"show \"phaser\" message window", 0, &messWin[WPHASER].window, 0, 0, NULL, NULL},
+    {"show \"joined\" message window", 0, &messWin[WREVIEW].window, 0, 0, NULL, NULL},
+    {"show ship statistics window", 0, &statwin, 0, 0, NULL, NULL},
+    {"show network statistics window", 0, &pStats, 0, 0, NULL, NULL},
+    {"show help window", 0, &helpWin, 0, 0, NULL, NULL},
+#ifdef XTREKRC_HELP
+    {"show xtrekrc defaults window", 0, &defWin, 0, 0, NULL, NULL},
+#endif
+#ifdef TOOLS
+    {"show shell tools window", 0, &toolsWin, 0, 0, NULL, NULL},
+#endif
+    {0, &showPhaser, 0, 0, 0, phaseroptions, NULL},
+    {"", &showLock, 0, 0, 0, lockoptions, NULL},
+    {"show lock line", &lockLine, 0, 0, 0, NULL, NULL},
+    {"sort planets by team", &mapSort, 0, 0, 0, NULL, NULL},
+#ifdef NOWARP
+    {"enable message warp", &warp, 0, 0, 0, NULL, NULL},
+#endif
+    {"use info icon", &infoIcon, 0, 0, 0, NULL, NULL},
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+struct option Display_Menu[] =
+{
+    {"Features Display Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+#ifdef ROTATERACE
+    {0, &rotate, 0, 0, 0, rotatemess, NULL},
+#endif
+    {"draw background stars", &blk_showStars, 0, 0, 0, NULL},
+    {"show warp/star streaks", &warpStreaks, 0, 0, 0, NULL, NULL},
+    {"show tractor/pressor", &showTractorPressor, 0, 0, 0, NULL, NULL},
+    {"show all tractors/pressors", &showAllTractorPressor, 0, 0, 0, NULL, NULL},
+    {"show shields", &showShields, 0, 0, 0, NULL, NULL},
+    {"show shield damage", &show_shield_dam, 0, 0, 0, NULL, NULL},
+#ifdef VARY_HULL
+    {"show hull damage indicators", &vary_hull, 0, 0, 0, NULL, NULL},
+#endif				/* VARY_HULL */
+
+    {"show tactical planet names", &namemode, 0, 0, 0, NULL, NULL},
+
+    {"zoom galactic map", &blk_zoom, 0, 0, 0, NULL, NULL},
+    {0,&autoZoom, 0, 0, 0, autoZoomOpts, NULL},
+    {0,&autoUnZoom, 0, 0, 0, autoUnZoomOpts, NULL},
+    {"Manual zoom overrides auto-zoom %d updates",&autoZoomOverride, 0, 0, 0, NULL, 
+	 &zoom_override_range},
+    {"draw galactic map grid", &drawgrid, 0, 0, 0, NULL},
+    {"show sector numbers", &sectorNums, 0, 0, 0, NULL, NULL},
+    {"show view box", &viewBox, 0, 0, 0, NULL, NULL},
+    {0, &autoSetWar, 0, 0, 0, autoSetWarOpts, NULL},
+    {"show planet info on tactical: %d", &tacPlanetInfo, 0, 0, 0, 0, &tacPlanetInfo_range},
+#ifdef BEEPLITE
+    {"use RCD highlighting", &UseLite, 0, 0, 0, NULL, NULL},
+    {"highlight/use default RCDs", &DefLite, 0, 0, 0, NULL, NULL},
+    {"No. of updates to highlight player: %d", &beep_lite_cycle_time_player,
+    0, 0, 0, NULL, &beeplite_player_range},
+    {"No. of updates to highlight planet: %d", &beep_lite_cycle_time_planet,
+    0, 0, 0, NULL, &beeplite_planet_range},
+#endif
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+struct option Playerdash_Menu[] =
+{
+    {"Playerlist/Dashboard Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"sort playerlist", &sortPlayers, 0, 0, 0, NULL, NULL},
+    {"show dead players in playerlist", &showDead, 0, 0, 0, NULL, NULL},
+    {"show players as they log in", &showPreLogins, 0, 0, 0, NULL, NULL},
+    {"hide 0.00 kills in playerlist", &hideNoKills, 0, 0, 0, NULL, NULL},
+    {"sort outfitting to bottom", &sortOutfitting, 0, 0, 0, NULL, NULL},
+    {0, &Dashboard, 0, 0, 0, dashboardoptions, NULL},
+#ifdef TIMER
+    {0, &timerType, 0, 0, 0, timermes, NULL},
+#endif				/* TIMER */
+#ifdef LOCAL_SHIPSTATS
+    {"show ship stats on local window",&localShipStats, 0, 0, 0, NULL, NULL},
+    {"Local ship stats height: %d",&statHeight, 0, 0, 0, NULL, &statHeight_range},
+#endif
+#ifdef PACKET_LIGHTS
+    {"show packet lights", &packetLights, 0, 0, 0, NULL, NULL},
+#endif
+    {"keep phaser statistics", &phaserStats,0,0,0,NULL, NULL},
+    {"clear phaser statistics", &clearPhaserStats, 0, 0, 0, NULL, NULL},
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+#ifdef HOCKEY
+struct option Hockey_Menu[] =
+{
+    {"Hockey Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"show tactical hockey lines", &tacticalHockeyLines, 0, 0, 0, NULL, NULL},
+    {"show galactic hockey lines", &galacticHockeyLines, 0, 0, 0, NULL, NULL},
+    {"show planets on the galactic", &cleanHockeyGalactic, 0, 0, 0, NULL, NULL},
+    {"color hockey lines by team", &teamColorHockeyLines, 0, 0, 0, NULL, NULL},
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+#endif /*HOCKEY*/
+
+#if 0
+struct option Network_Menu[] =
+{
+    {"Network menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+#endif				/* 0 */
+
+#if 0
+{
+    "show shields", &showShields, 0, 0, 0, NULL, NULL
+},
+{
+    "show UDP control window", 0, &udpWin, 0, 0, NULL, NULL
+},
+{
+    "show short packets window", 0, &spWin, 0, 0, NULL, NULL
+},
+struct option SillyFeatures_Menu[] =
+{
+    {"Silly Features Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click here to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"alert on extra border(s)", &extraBorder, 0, 0, 0, NULL, NULL},
+#ifdef BORGTEST
+    {"borg torp test", &bd, 0, 0, 0, NULL, NULL},	/* BORG TEST */
+#endif
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+#endif				/* 0 */
+
+#ifdef AMIGA
+
+static char *autopointmess[] = {
+    "AutoPoint: none",
+    "AutoPoint: Redirect input",
+    "AutoPoint: Activate window on input",
+    "AutoPoint: Full (inefficient)", ""
+};
+
+static char *dooshSoundMess[] = {
+    "Play doosh sound when YOU kill a carrier",
+    "Play doosh sound when ANY carrier dies",
+    ""
+};
+
+struct int_range soundVolRange = {0, 64, 4};
+struct int_range speechVolRange = {0, 64, 4};
+
+extern int speechVol;
+extern int S_AddPeriod;
+extern int monoBitmaps;
+
+struct option Amiga_Menu[] = {
+    {"Amiga Features Menu", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {"Page %d (click to change)", &MenuPage, 0, 0, 0, NULL, &Menus_Range},
+    {0, &autoPoint, 0, 0, 0, autopointmess, NULL},
+    {"do keyboard window depth", &W_KeyDepth, 0, 0, 0, NULL, NULL},
+    {"use AnimPointers", &animPointers, 0, 0, 0, NULL, NULL},
+    {"use one color bitmaps", &monoBitmaps, 0, 0, 0, NULL, NULL},
+    {"use Workbench screen", &useWorkbench, 0, 0, 0, NULL, NULL},
+    {"speak messages to \"all\"", &S_SpeakAll, 0, 0, 0, NULL, NULL},
+    {"speak messages to you", &S_SpeakYour, 0, 0, 0, NULL, NULL},
+    {"speak messages to team", &S_SpeakTeam, 0, 0, 0, NULL, NULL},
+    {"speak \"kill\" messages", &S_SpeakKill, 0, 0, 0, NULL, NULL},
+    {"speak messages from God", &S_SpeakGod, 0, 0, 0, NULL, NULL},
+    {"speak messages from YOU", &S_SpeakSelf, 0, 0, 0, NULL, NULL}, 
+    {"speak login/out messages", &S_SpeakLogins, 0, 0, 0, NULL, NULL},
+    {"ignore repeated messages", &S_IgnoreMultiple, 0, 0, 0, 0, 0},
+    {"add a period to the end of messages", &S_AddPeriod, 0, 0, 0, 0, 0},
+    {"Speech volume: %d", &speechVol, 0, 0, 0, NULL, &speechVolRange},
+#ifdef SOUND
+    {"play digitized sounds", &soundOn, 0, 0, 0, NULL, NULL},
+    {"Sound volume: %d", &soundVol, 0, 0, 0, NULL, &soundVolRange},
+    {"show sounds window", 0, &soundWin, 0, 0, NULL, NULL},
+    {0, &alwaysSoundDoosh, 0, 0, 0, dooshSoundMess, 0},
+#endif
+    {"done", &notdone, 0, 0, 0, NULL, NULL},
+    {NULL, 0, 0, 0, 0, NULL, NULL, /**/ -1}
+};
+
+#endif				/* AMIGA */
+
+#define NUMOPTIONS(menu) ((sizeof((menu))/sizeof((menu)[0]))-1)
+
+
+/* option menu sizes and such */
+#define OPTIONBORDER	2
+#define OPTIONLEN	40
+
+static void RefreshOptions P((void));
+static void SetMenuPage P((int pagenum));
+static int InitOptionMenus P((void));
+static void AddOptMenu P((struct option NewMenu[], int updated));
+static int NumOptions P((struct option OpMenu[]));
+/*static void UpdateOptions P((void));*/
+void optionrefresh P((register struct option * op));
+
+
+/* Set up the option menus and window. */
+void
+optionwindow()
+{
+    /* Init not done flag */
+    notdone = 1;
+
+    old_ping = ping;
+    old_rotate = rotate;
+    old_rotate_deg = rotate_deg;
+
+    *newkeys = '\0';
+    *newckeys = '\0';
+    *newbuttons = '\0';
+    *newcbuttons = '\0';
+    if (FirstMenu == NULL) {
+	if (!paradise) {	/* remove the extra planet settings */
+	    localmes[3] = "";
+	    galacticmes[3] = "";
+	}
+	MaxOptions = InitOptionMenus();
+	if (MaxOptions < 0) {
+	    fprintf(stderr, "InitOptionMenus() error %d!\n", MaxOptions);
+	    notdone = 0;
+	    return;
+	}
+    }
+    /* Create window big enough to hold option windows */
+    if (optionWin == NULL) {
+
+	optionWin = W_MakeMenu("option", WINSIDE + 10, -BORDER + 10, OPTIONLEN,
+			       MaxOptions, baseWin, OPTIONBORDER);
+	CurrentMenu = FirstMenu;
+
+	RefreshOptions();
+    }
+    W_ResizeMenu(optionWin, OPTIONLEN, CurrentMenu->numopt);
+    /* Map window */
+    W_MapWindow(optionWin);
+}
+
+/* refresh all current options */
+static void
+RefreshOptions()
+{
+    int     i;
+    struct option_menu *option;
+
+    if (notdone == 0 || (option = CurrentMenu) == NULL)
+	return;
+
+    for (i = 0; i < option->numopt; i++) {
+	optionrefresh(&(option->menu[i]));
+    }
+#ifdef nodef			/* if we resize, we don't need this */
+    if (option->numopt < MaxOptions)
+	for (i = option->numopt; i < MaxOptions; i++) {
+	    OptionClear(i);
+	}
+#endif
+}
+
+#ifdef nodef
+/* blank out option line 'i' */
+static void
+OptionClear(i)
+{
+    char   *blanktext = "                                               ";
+    if (optionWin && notdone)
+	W_WriteText(optionWin, 0, i, textColor, blanktext, OPTIONLEN, 0);
+}
+#endif
+
+/* Redraw the specified option entry */
+void
+optionredrawtarget(win)
+    W_Window win;
+{
+    register struct option *op;
+
+#ifdef nodef
+    if (notdone == 0)
+	return;
+#endif
+
+    for (op = CurrentMenu->menu; op->op_text; op++) {
+	if (op->op_targetwin && win == *op->op_targetwin) {
+	    optionrefresh(op);
+	    break;
+	}
+    }
+}
+
+/* Redraw the specified option option */
+void
+optionredrawoption(ip)
+    int    *ip;
+{
+    register struct option *op;
+
+#ifdef nodef
+    if (notdone == 0)
+	return;
+#endif
+
+    for (op = CurrentMenu->menu; op->op_num >= 0; op++) {
+	if (ip == op->op_option) {
+	    optionrefresh(op);
+	    break;
+	}
+    }
+}
+
+/* Refresh the option window given by the option struct */
+void
+optionrefresh(op)
+    register struct option *op;
+{
+    register int on;
+    char    buf[BUFSIZ];
+
+    if (op == NULL || notdone == 0)
+	return;
+
+    if (op->op_string) {
+	(void) sprintf(buf, op->op_text, op->op_string);
+    } else if (op->op_array) {	/* Array of strings */
+	strcpy(buf, op->op_array[*op->op_option]);
+    } else if (op->op_range) {
+	(void) sprintf(buf, op->op_text, *(op->op_option));
+    } else {
+	/* Either a boolean or a window */
+	if (op->op_option)
+	    on = *op->op_option;/* use int for status */
+	else if (op->op_targetwin)
+	    on = W_IsMapped(*op->op_targetwin);	/* use window for status */
+	else
+	    on = 1;		/* shouldn't happen */
+
+	if (!on)
+	    strcpy(buf, "Don't ");
+	else
+	    buf[0] = '\0';
+	strcat(buf, op->op_text);
+    }
+
+    if (islower(buf[0]))
+	buf[0] = toupper(buf[0]);
+
+    if (op->op_num == 0) {	/* title */
+	W_WriteText(optionWin, 0, op->op_num, W_Yellow, buf, strlen(buf), 0);
+    } else if (op->op_num == 1) {	/* "click" entry */
+	W_WriteText(optionWin, 0, op->op_num, W_Green, buf, strlen(buf), 0);
+    } else
+	W_WriteText(optionWin, 0, op->op_num, textColor, buf, strlen(buf), 0);
+}
+
+/* deal with events sent to the option window */
+int
+optionaction(data)
+    W_Event *data;
+{
+    register struct option *op;
+    int     i;
+    register char *cp;
+
+    if (data->y >= CurrentMenu->numopt) {
+	W_Beep();
+	return (0);
+    }
+    if (notdone == 0)
+	return (0);
+
+    op = &(CurrentMenu->menu[data->y]);
+
+    /* Update string; don't claim keystrokes for non-string options */
+    /* deal with options with string input first */
+    if (op->op_string == 0) {
+	if (data->type == W_EV_KEY)
+	    return (0);
+    } else {
+	if (data->type == W_EV_BUTTON)
+	    return (0);
+	switch (data->key) {
+
+	case '\b':		/* delete character */
+	case '\177':
+	    cp = op->op_string;
+	    i = strlen(cp);
+	    if (i > 0) {
+		cp += i - 1;
+		*cp = '\0';
+	    }
+	    break;
+
+	case '\027':		/* word erase */
+	    cp = op->op_string;
+	    i = strlen(cp);
+	    /* back up over blanks */
+	    while (--i >= 0 && isspace(cp[i]));
+	    i++;
+	    /* back up over non-blanks */
+	    while (--i >= 0 && !isspace(cp[i]));
+	    i++;
+	    cp[i] = '\0';
+	    break;
+
+	case '\025':		/* kill line */
+	case '\030':
+	    op->op_string[0] = '\0';
+	    break;
+
+	default:		/* add character to the list */
+	    if (data->key < 32 || data->key > 127)
+		break;
+	    cp = op->op_string;
+	    i = strlen(cp);
+	    if (i < (op->op_size - 1) && !iscntrl(data->key)) {
+		cp += i;
+		cp[1] = '\0';
+		cp[0] = data->key;
+	    } else
+		W_Beep();
+	    break;
+	}
+    }
+
+    /* Toggle int, if it exists */
+    if (op->op_array) {
+	if (data->key == W_LBUTTON) {
+	    (*op->op_option)++;
+	    if (*(op->op_array)[*op->op_option] == '\0') {
+		*op->op_option = 0;
+	    }
+	} else if (data->key == W_MBUTTON) {
+	    /* set option number to zero on the middle key to ease shutoff */
+	    *op->op_option = 0;
+	} else if (data->key == W_RBUTTON) {
+	    /* if right button, decrease option  */
+	    (*op->op_option)--;
+	    /* if decreased too far, set to top option */
+	    if (*(op->op_option) < 0) {
+		*op->op_option = 0;
+		while (*(op->op_array)[*op->op_option] != '\0') {
+		    (*op->op_option)++;
+		}
+		(*op->op_option)--;
+	    }
+	}
+	if(op->op_option == &showgalactic)
+	    redrawall=1;
+    } else if (op->op_range) {
+	 if (data->key == W_RBUTTON) {
+	      if (op->op_range->increment == -1) /* bitwise shifts by 1 */
+		   if (*op->op_option == 0)
+			(*op->op_option) = op->op_range->max_value;
+		   else
+			(*op->op_option) = (*op->op_option) >> 1;
+	      else
+		   (*op->op_option) -= op->op_range->increment;
+	} else if (data->key == W_MBUTTON) {
+	    (*op->op_option) = op->op_range->min_value;
+	} else if (data->key == W_LBUTTON) {
+	     if (op->op_range->increment == -1)
+		  if (*op->op_option == 0)
+		       (*op->op_option) = 1;
+		  else
+		       (*op->op_option) =  (*op->op_option) << 1;
+	     else
+		  (*op->op_option) += op->op_range->increment;
+	}
+	/* wrap value around within option range */
+	if (*(op->op_option) > op->op_range->max_value)
+	    *(op->op_option) = op->op_range->min_value;
+	if (*(op->op_option) < op->op_range->min_value)
+	    *(op->op_option) = op->op_range->max_value;
+    } else if (op->op_option) {
+	*op->op_option = !*op->op_option;
+	if(op->op_option == &blk_zoom) {
+	    if(!paradise) {
+		blk_zoom=0;
+	    } else {
+		redrawall=1;
+	    }
+	} else if((op->op_option == &blk_showStars) && !paradise)
+	    blk_showStars = 0;
+	else if((op->op_option == &drawgrid) ||
+		(op->op_option == &sectorNums))
+	    redrawall=1;
+	else if(op->op_option == &clearPhaserStats) {
+	    phasFired=phasHits=totalDmg=0;
+	    clearPhaserStats=1;
+	    warning("Phaser statistics reset!");
+	} else if(op->op_option == &reloadShipBitmaps) {
+	    free_shipshapes();
+	    slurp_ship_bitmaps();
+	    reloadShipBitmaps = 1;
+	    warning("Read ship bitmaps");
+	}
+#ifdef AMIGA
+	else if(op->op_option == &useWorkbench) {
+	    switchScreen();
+	}
+#endif
+    }
+    /* Map/unmap window, if it exists */
+    if (op->op_targetwin) {
+	if (W_IsMapped(*op->op_targetwin)) {
+	    if (*op->op_targetwin == udpWin)
+		udpdone();
+	    else if (*op->op_targetwin == spWin)
+		spdone();
+	    else
+		W_UnmapWindow(*op->op_targetwin);
+	} else {
+	    if (*op->op_targetwin == udpWin)
+		udpwindow();
+	    else if (*op->op_targetwin == spWin)
+		spwindow();
+#ifdef SOUND
+	    else if (*op->op_targetwin == soundWin)
+		S_SoundWindow();
+#endif
+	    else
+		W_MapWindow(*op->op_targetwin);
+	    if (*op->op_targetwin == pStats)
+		redrawPStats();
+#ifdef XTREKRC_HELP
+	    if (*op->op_targetwin == defWin)
+		showdef();
+#endif
+	}
+    }
+    /* deal with possible menu change */
+    if (MenuPage != CurrentMenu->page_num) {
+	SetMenuPage(MenuPage);
+	RefreshOptions();
+    }
+    if (!notdone)		/* if done, that is */
+	optiondone();
+    else
+	optionrefresh(op);
+
+
+    return (1);
+}
+
+/*
+ * find the menu in the menus linked list that matches the one in the *
+ * argument
+ */
+static void
+SetMenuPage(pagenum)
+    int     pagenum;
+{
+    int     i = 1;
+    if (FirstMenu != NULL)
+	for (CurrentMenu = FirstMenu; CurrentMenu->Next != NULL &&
+	     CurrentMenu->page_num != pagenum; i++, CurrentMenu = CurrentMenu->Next);
+    W_ResizeMenu(optionWin, OPTIONLEN, CurrentMenu->numopt);
+}
+
+void
+optiondone()
+{
+    int shpn;
+    struct ship *shp;
+
+    /* Unmap window */
+    W_UnmapWindow(optionWin);
+
+    if(remapAllShips) {
+	for(shpn=0;shpn<nshiptypes;shpn++) {
+	    shp=getship(shpn);
+	    keymapAdd(newkeys, shp->s_keymap);
+	    ckeymapAdd(newckeys, shp->s_keymap);
+	    buttonmapAdd(newbuttons, shp->s_buttonmap);
+	    cbuttonmapAdd(newcbuttons, shp->s_buttonmap);
+	}
+    } else { /* only affect current ship */
+	/* update keymap and buttonmap [Bdyess] */
+	keymapAdd(newkeys, myship->s_keymap);
+	ckeymapAdd(newckeys, myship->s_keymap);
+	buttonmapAdd(newbuttons, myship->s_buttonmap);
+	cbuttonmapAdd(newcbuttons, myship->s_buttonmap);
+    }
+
+    /* optionrefresh(&(option[KEYMAP])); Not sure why this is really needed */
+
+    sendOptionsPacket();	/* update server as to the client's options */
+
+    if (updateSpeed != lastUpdateSpeed) {
+	sendUpdatePacket(1000000 / updateSpeed);
+	lastUpdateSpeed = updateSpeed;
+    }
+    if (oldzoom != blk_zoom) {
+	redrawall = 1;
+	oldzoom = blk_zoom;
+    }
+    if (ping != old_ping) {
+	old_ping = ping;
+	if (ping)
+	    startPing();
+	else
+	    stopPing();
+    }
+#ifdef BEEPLITE
+    if (DefLite)
+	litedefaults();
+#endif
+
+#ifdef ROTATERACE
+    if (rotate != old_rotate) {
+
+	rotate_all();
+#if 0
+	register i;
+	register struct planet *l;
+	int     nplan = (paradise) ? nplanets : 40;
+
+	redrawall = 1;
+	reinitPlanets = 1;
+
+	for (i = 0, l = planets; i < nplan; i++, l++) {
+	    if (rotate) {
+		rotate_deg = -old_rotate_deg + rotate * 64;
+		rotate_coord(&l->pl_x, &l->pl_y, rotate_deg,
+			     blk_gwidth / 2, blk_gwidth / 2);
+		rotate_deg = rotate * 64;
+	    } else {
+		rotate_deg = -old_rotate_deg;
+		rotate_coord(&l->pl_x, &l->pl_y, rotate_deg,
+			     blk_gwidth / 2, blk_gwidth / 2);
+		rotate_deg = 0;
+	    }
+	}
+#endif
+	old_rotate = rotate;
+	old_rotate_deg = rotate_deg;
+
+    }
+#endif
+}
+
+/* set up menus linked list */
+static int
+InitOptionMenus()
+{
+    int     i = 1;
+    int     maxopts = 0;
+
+    IFDEBUG(printf("Adding OptionMenus\n");
+    )
+    /* AddOptMenu( &OptionsMenu, 0); */
+	AddOptMenu(Features_Menu, 0);
+    AddOptMenu(Window_Menu, 0);
+    AddOptMenu(Display_Menu, 0);
+    AddOptMenu(Playerdash_Menu, 0);
+#ifdef HOCKEY
+    AddOptMenu(Hockey_Menu, 0);
+#endif /*HOCKEY*/
+#ifdef AMIGA
+    AddOptMenu(Amiga_Menu, 0);
+#endif
+    /* AddOptMenu(SillyFeatures_Menu, 0); */
+    /* AddOptMenu(Network_Menu, 0); */
+
+    for (i = 1, CurrentMenu = FirstMenu; CurrentMenu != NULL;
+	 i++, CurrentMenu = CurrentMenu->Next) {
+	CurrentMenu->page_num = i;	/* repage the menus.. */
+	if (CurrentMenu->numopt > maxopts)
+	    maxopts = CurrentMenu->numopt;
+    }
+    CurrentMenu = FirstMenu;
+    Menus_Range.max_value = i - 1;
+    IFDEBUG(printf("OptionMenus Added! Maxopt = %d \n", i);
+    )
+	return maxopts;
+}
+
+static void
+AddOptMenu(NewMenu, updated)
+    struct option NewMenu[];
+    int     updated;
+{
+    struct option_menu *menuptr;
+    struct option_menu *newmenu;
+    int     i = 0;
+
+    IFDEBUG(printf("AddOptMenu\n");
+    )
+	menuptr = FirstMenu;
+
+    newmenu = (struct option_menu *) malloc(sizeof(struct option_menu));
+    if (newmenu == NULL) {
+	perror("Malloc Error adding a menu");
+	return;
+    }
+    /* add to list */
+    if (FirstMenu == NULL) {
+	FirstMenu = newmenu;
+    } else {
+	for (i = 0, menuptr = FirstMenu; menuptr->Next != NULL; menuptr = menuptr->Next)
+	    i++;
+	menuptr->Next = newmenu;
+    }
+    newmenu->page_num = i;
+    newmenu->Next = NULL;
+    newmenu->numopt = NumOptions(NewMenu);
+    newmenu->menu = NewMenu;
+    newmenu->updated = updated;
+    IFDEBUG(printf("Menu Added! \n", i);
+    )
+}
+
+static int
+NumOptions(OpMenu)
+    struct option OpMenu[];
+{
+    int     i = 0;
+    struct option *ptr;
+
+    ptr = &OpMenu[0];
+    for (i = 0; ptr->op_num != -1 && ptr->op_option != &notdone; i++) {
+	IFDEBUG(printf("Option #%d..\n", i);
+	)
+	    IFDEBUG(if (ptr->op_text != NULL) printf("OP_Text:%s\n", ptr->op_text);
+	)
+	    ptr = &OpMenu[i];
+	ptr->op_num = i;
+    }
+
+    IFDEBUG(printf("NumOptions in this menu: %d\n", i);
+    )
+	return i;
+}
+
+/*
+ * a function that could be called regularly, to deal with menus that * might
+ * be updated by external events. I.e. the udp menu!
+ */
+#if 0
+static void
+UpdateOptions()
+{
+    if (notdone == 0)
+	return;			/* don't update if menu isn't in use */
+    if (CurrentMenu->updated)
+	RefreshOptions();
+}
+#endif				/* 0 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packets.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,321 @@
+/* $Id: packets.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#include <stddef.h>
+
+#include "defs.h"
+#include "packets.h"
+#include "gppackets.h"
+#include "wtext.h"
+
+size_t  client_packet_sizes[] = {
+    0,
+    sizeof(struct mesg_cpacket),
+    sizeof(struct speed_cpacket),
+    sizeof(struct dir_cpacket),
+    sizeof(struct phaser_cpacket),
+    sizeof(struct plasma_cpacket),
+    sizeof(struct torp_cpacket),
+    sizeof(struct quit_cpacket),
+    sizeof(struct login_cpacket),
+    sizeof(struct outfit_cpacket),
+    /* 10 v */
+    sizeof(struct war_cpacket),
+    sizeof(struct practr_cpacket),
+    sizeof(struct shield_cpacket),
+    sizeof(struct repair_cpacket),
+    sizeof(struct orbit_cpacket),
+    sizeof(struct planlock_cpacket),
+    sizeof(struct playlock_cpacket),
+    sizeof(struct bomb_cpacket),
+    sizeof(struct beam_cpacket),
+    sizeof(struct cloak_cpacket),
+    /* 20 v */
+    sizeof(struct det_torps_cpacket),
+    sizeof(struct det_mytorp_cpacket),
+    sizeof(struct copilot_cpacket),
+    sizeof(struct refit_cpacket),
+    sizeof(struct tractor_cpacket),
+    sizeof(struct repress_cpacket),
+    sizeof(struct coup_cpacket),
+    sizeof(struct socket_cpacket),
+    sizeof(struct options_cpacket),
+    sizeof(struct bye_cpacket),
+    /* 30 v */
+    sizeof(struct dockperm_cpacket),
+    sizeof(struct updates_cpacket),
+    sizeof(struct resetstats_cpacket),
+    sizeof(struct reserved_cpacket),
+    sizeof(struct scan_cpacket),
+    sizeof(struct udp_req_cpacket),
+    sizeof(struct sequence_cpacket),
+    sizeof(struct rsa_key_cpacket),
+    sizeof(struct obvious_packet),
+    0,
+    /* 40 v */
+    0,
+    0,
+    sizeof(struct ping_cpacket),/* 42 */
+#ifdef SHORT_PACKETS
+    sizeof(struct shortreq_cpacket),
+    sizeof(struct threshold_cpacket),
+    0,				/* CP_S_MESSAGE */
+    0,				/* CP_S_RESERVED */
+    0,				/* CP_S_DUMMY */
+#else
+    0,
+    0,
+    0,
+    0,
+    0,				/* 47 */
+#endif
+    0,				/* 48 */
+    0,
+    /* 50 v */
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,
+    0,				/* 59 */
+#ifdef FEATURE
+    sizeof(struct feature_cpacket)	/* CP_FEATURE */
+#else
+  0
+#endif
+};
+
+#define num_cpacket_sizes	sizeof(client_packet_sizes)/sizeof(*client_packet_sizes)
+
+int 
+size_of_cpacket(pkt)
+    void   *pkt;
+{
+    CARD8   type;
+    CARD8   subtype;
+
+    type = ((CARD8 *) pkt)[0];
+    subtype = ((CARD8 *) pkt)[1];
+
+    if (type < num_cpacket_sizes && client_packet_sizes[type] > 0)
+	return client_packet_sizes[type];
+
+    switch (type) {
+#ifdef CP_FIRE_WEAPON
+    case CP_FIRE_WEAPON:
+	{
+	    struct fire_weapon_cpacket *fwp = pkt;
+	    return (fwp->mech == TM_POSITION) ? 12 : 4;
+	}
+#endif
+
+#ifdef SHORT_PACKETS
+    case CP_S_MESSAGE:
+	return ((unsigned char *) pkt)[3];
+    case CP_S_RESERVED:
+    case CP_S_DUMMY:
+	/* hmm? good question */
+	return 0;
+#endif				/* SHORT_PACKETS */
+
+    default:
+	return 0;
+    }
+}
+
+
+int     server_packet_sizes[] = {
+    0,				/* record 0 */
+    sizeof(struct mesg_spacket),/* SP_MESSAGE */
+    sizeof(struct plyr_info_spacket),	/* SP_PLAYER_INFO */
+    sizeof(struct kills_spacket),	/* SP_KILLS */
+    sizeof(struct player_spacket),	/* SP_PLAYER */
+    sizeof(struct torp_info_spacket),	/* SP_TORP_INFO */
+    sizeof(struct torp_spacket),/* SP_TORP */
+    sizeof(struct phaser_spacket),	/* SP_PHASER */
+    sizeof(struct plasma_info_spacket),	/* SP_PLASMA_INFO */
+    sizeof(struct plasma_spacket),	/* SP_PLASMA */
+    /* 10 v */
+    sizeof(struct warning_spacket),	/* SP_WARNING */
+    sizeof(struct motd_spacket),/* SP_MOTD */
+    sizeof(struct you_spacket),	/* SP_YOU */
+    sizeof(struct queue_spacket),	/* SP_QUEUE */
+    sizeof(struct status_spacket),	/* SP_STATUS */
+    sizeof(struct planet_spacket),	/* SP_PLANET */
+    sizeof(struct pickok_spacket),	/* SP_PICKOK */
+    sizeof(struct login_spacket),	/* SP_LOGIN */
+    sizeof(struct flags_spacket),	/* SP_FLAGS */
+    sizeof(struct mask_spacket),/* SP_MASK */
+    /* 20 v */
+    sizeof(struct pstatus_spacket),	/* SP_PSTATUS */
+    sizeof(struct badversion_spacket),	/* SP_BADVERSION */
+    sizeof(struct hostile_spacket),	/* SP_HOSTILE */
+    sizeof(struct stats_spacket),	/* SP_STATS */
+    sizeof(struct plyr_login_spacket),	/* SP_PL_LOGIN */
+    sizeof(struct reserved_spacket),	/* SP_RESERVED */
+    sizeof(struct planet_loc_spacket),	/* SP_PLANET_LOC */
+    sizeof(struct scan_spacket),/* SP_SCAN (ATM) */
+    sizeof(struct udp_reply_spacket),	/* SP_UDP_REPLY */
+    sizeof(struct sequence_spacket),	/* SP_SEQUENCE */
+    /* 30 v */
+    sizeof(struct sc_sequence_spacket),	/* SP_SC_SEQUENCE */
+    sizeof(struct rsa_key_spacket),	/* SP_RSA_KEY */
+    sizeof(struct motd_pic_spacket),	/* SP_MOTD_PIC */
+    sizeof(struct stats_spacket2),	/* SP_STATS2 */
+    sizeof(struct status_spacket2),	/* SP_STATUS2 */
+    sizeof(struct planet_spacket2),	/* SP_PLANET2 */
+    sizeof(struct obvious_packet),	/* SP_NEW_MOTD */
+    sizeof(struct thingy_spacket),	/* SP_THINGY */
+    sizeof(struct thingy_info_spacket),	/* SP_THINGY_INFO */
+    sizeof(struct ship_cap_spacket),	/* SP_SHIP_CAP */
+    /* 40 v */
+#ifdef SHORT_PACKETS
+    sizeof(struct shortreply_spacket),	/* SP_S_REPLY */
+    -1,				/* SP_S_MESSAGE */
+    -1,				/* SP_S_WARNING */
+    sizeof(struct youshort_spacket),	/* SP_S_YOU */
+    sizeof(struct youss_spacket),	/* SP_S_YOU_SS */
+    -1,				/* SP_S_PLAYER */
+#else
+    -1,
+    -1,
+    -1,
+    -1,
+    -1,
+    -1,
+#endif
+    sizeof(struct ping_spacket),/* SP_PING */
+    -1,				/* SP_S_TORP */
+    -1,				/* SP_S_TORP_INFO */
+    20,				/* SP_S_8_TORP */
+    /* 50 v */
+    -1,				/* SP_S_PLANET */
+    -1,				/* SP_GPARAM */
+    -1,				/* SP_PARADISE_EXT1 */
+    sizeof(struct terrain_packet2), /* SP_TERRAIN2 */
+    sizeof(struct terrain_info_packet2), /* SP_TERRAIN_INFO2 */
+    -1,
+    -1,
+    -1,
+    -1,
+    -1,
+    /* 60 v */
+#ifdef FEATURE
+    sizeof(struct feature_spacket),
+#else
+    -1,
+#endif
+    -1
+};
+
+#define num_spacket_sizes (sizeof(server_packet_sizes) / sizeof(server_packet_sizes[0]) - 1)
+
+#ifdef SHORT_PACKETS
+unsigned char numofbits[256] =
+{0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1,
+    2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1,
+    2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
+    3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1,
+    2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
+    3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
+    3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
+    4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1,
+    2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
+    3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
+    3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
+    4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2,
+    3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
+    4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
+    4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4,
+5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
+
+static int vtsize[9] =
+{4, 8, 8, 12, 12, 16, 20, 20, 24};	/* How big is the torppacket */
+int     vtisize[9] =
+{4, 7, 9, 11, 13, 16, 18, 20, 22};	/* 4 byte Header + torpdata */
+
+
+static int
+padto4(sz)
+    int     sz;
+{
+    return (sz % 4) ? (sz / 4 + 1) * 4 : sz;
+
+}
+#endif
+
+int
+size_of_spacket(pkt)
+    unsigned char *pkt;
+{
+    switch (pkt[0]) {
+    case SP_GPARAM:
+	switch (pkt[1]) {
+	case 0:
+	    return sizeof(struct gp_sizes_spacket);
+	case 1:
+	    return sizeof(struct gp_team_spacket);
+	case 2:
+	    return sizeof(struct gp_teamlogo_spacket);
+	case 3:
+	    return sizeof(struct gp_shipshape_spacket);
+	case 4:
+	    return sizeof(struct gp_shipbitmap_spacket);
+	case 5:
+	    return sizeof(struct gp_rank_spacket);
+	case 6:
+	    return sizeof(struct gp_royal_spacket);
+	case 7:
+	    return sizeof(struct gp_teamplanet_spacket);
+	default:
+	    return 0;
+	}
+#ifdef SHORT_PACKETS
+    case SP_S_MESSAGE:
+	return padto4(pkt[4]);	/* IMPORTANT  Changed */
+    case SP_S_WARNING:
+	if (pkt[1] == STEXTE_STRING ||
+	    pkt[1] == SHORT_WARNING) {
+	    return padto4(pkt[3]);
+	} else
+	    return 4;		/* Normal Packet */
+    case SP_S_PLAYER:
+	if (pkt[1] & 128) {	/* Small +extended Header */
+	    return padto4(((pkt[1] & 0x3f) * 4) + 4);
+	} else if (pkt[1] & 64) {	/* Small Header */
+	    return padto4(((pkt[1] & 0x3f) * 4) + 4);
+	} else {		/* Big Header */
+	    return padto4((pkt[1] * 4 + 12));
+	}
+    case SP_S_TORP:
+	return padto4(vtsize[numofbits[pkt[1]]]);
+    case SP_S_TORP_INFO:
+	return padto4((vtisize[numofbits[pkt[1]]] + numofbits[pkt[3]]));
+    case SP_S_PLANET:
+	return padto4((pkt[1] * VPLANET_SIZE) + 2);
+#endif
+    case SP_PARADISE_EXT1:
+	switch (pkt[1]) {
+	case SP_PE1_MISSING_BITMAP:
+	    return sizeof(struct pe1_missing_bitmap_spacket);
+	case SP_PE1_NUM_MISSILES:
+	    return sizeof(struct pe1_num_missiles_spacket);
+	default:
+	    return 0;
+	}
+#ifdef RECORDER
+    case REC_UPDATE:
+	{
+	    extern int playback;
+	    if (playback)	/* if not, something's very wrong... */
+		return 4;
+	}
+#endif
+    default:
+	return (*pkt < num_spacket_sizes && server_packet_sizes[*pkt] >= 0)
+	    ? server_packet_sizes[*pkt] : 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packets.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1115 @@
+/* $Id: packets.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*--------------------------------------------------------------------------
+NETREK II -- Paradise 2.1                    FILE: packets.h
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any NON-COMMERCIAL purpose (following the terms of
+the GNU General Public License (read the file 'COPYING')) and without
+fee is hereby granted, provided that this copyright notice appear in all
+copies.  No representations are made about the suitability of this
+software for any purpose.  This software is provided "as is" without
+express or implied warranty.
+
+    Xtrek Copyright 1986                            Chris Guthrie
+    Netrek (Xtrek II) Copyright 1989                Kevin P. Smith
+                                                    Scott Silvey
+    Paradise II (Netrek II) Copyright 1993          Larry Denys
+                                                    Kurt Olsen
+                                                    Brandon Gillespie
+    Paradise II by:
+       Larry Denys, Kurt Olsen, Brandon Gillespie, and Rob Forsman
+    and:
+       Heath Kehoe, Mike Lutz, Mike McGrath, Ted Hadley, and Mark Kolb
+--------------------------------------------------------------------------*/
+
+/*
+ * Include file for socket I/O xtrek.
+ *
+ * Kevin P. Smith 1/29/89
+ */
+
+#ifndef packets_h_
+#define packets_h_
+
+#define STATUS_TOKEN	"\t@@@"	/* ATM */
+
+/* the following typedefs allow portability to machines without the
+   ubiquitous 32-bit architecture (KSR1, Cray, DEC Alpha) */
+
+typedef unsigned int CARD32;
+typedef unsigned short CARD16;
+typedef unsigned char CARD8;
+
+typedef int INT32;
+typedef short INT16;
+#if __STDC__ || defined(sgi) || defined(RS6K)
+typedef signed char INT8;
+#else
+/* stupid compilers */
+typedef char INT8;
+#endif
+
+/*
+ * TCP and UDP use identical packet formats; the only difference is that,
+ * when in UDP mode, all packets sent from server to client have a sequence
+ * number appended to them.
+ *
+ * (note: ALL packets, whether sent on the TCP or UDP channel, will have
+ * the sequence number.  Thus it's important that client & server agree on
+ * when to switch.  This was done to keep critical and non-critical data
+ * in sync.)
+ */
+
+/* the various pad members of the structures are used for explicit
+   data alignment.  They do not contain any data.  All structures are
+   aligned to 4 bytes.  If your compiler forces 8 byte alignment, you
+   will not be adhering to the netrek protocol.
+   */
+
+/* packets sent from xtrek server to remote client */
+#define SP_MESSAGE 	1
+#define SP_PLAYER_INFO 	2	/* general player info not elsewhere */
+#define SP_KILLS	3	/* # kills a player has */
+#define SP_PLAYER	4	/* x,y for player */
+#define SP_TORP_INFO	5	/* torp status */
+#define SP_TORP		6	/* torp location */
+#define SP_PHASER	7	/* phaser status and direction */
+#define SP_PLASMA_INFO	8	/* player login information */
+#define SP_PLASMA	9	/* like SP_TORP */
+#define SP_WARNING	10	/* like SP_MESG */
+#define SP_MOTD		11	/* line from .motd screen */
+#define SP_YOU		12	/* info on you? */
+#define SP_QUEUE	13	/* estimated loc in queue? */
+#define SP_STATUS	14	/* galaxy status numbers */
+#define SP_PLANET 	15	/* planet armies & facilities */
+#define SP_PICKOK	16	/* your team & ship was accepted */
+#define SP_LOGIN	17	/* login response */
+#define SP_FLAGS	18	/* give flags for a player */
+#define SP_MASK		19	/* tournament mode mask */
+#define SP_PSTATUS	20	/* give status for a player */
+#define SP_BADVERSION   21	/* invalid version number */
+#define SP_HOSTILE	22	/* hostility settings for a player */
+#define SP_STATS	23	/* a player's statistics */
+#define SP_PL_LOGIN	24	/* new player logs in */
+#define SP_RESERVED	25	/* for future use */
+#define SP_PLANET_LOC	26	/* planet name, x, y */
+
+#define SP_SCAN		27	/* scan packet */
+#define SP_UDP_REPLY	28	/* notify client of UDP status */
+#define SP_SEQUENCE	29	/* sequence # packet */
+#define SP_SC_SEQUENCE	30	/* this trans is semi-critical info */
+#define SP_RSA_KEY	31	/* RSA data packet */
+
+#define SP_MOTD_PIC     32	/* motd bitmap pictures */
+#define SP_STATS2	33	/* new stats packet */
+#define SP_STATUS2	34	/* new status packet */
+#define SP_PLANET2	35	/* new planet packet */
+#define SP_NEW_MOTD     36	/* New MOTD info notification uses */
+#define SP_THINGY	37	/* thingy location */
+#define SP_THINGY_INFO	38	/* thingy status */
+#define SP_SHIP_CAP	39	/* ship capabilities */
+
+#ifdef SHORT_PACKETS
+#define SP_S_REPLY      40	/* reply to send-short request */
+#define SP_S_MESSAGE    41	/* var. Message Packet */
+#define SP_S_WARNING    42	/* Warnings with 4  Bytes */
+#define SP_S_YOU        43	/* hostile,armies,whydead,etc .. */
+#define SP_S_YOU_SS     44	/* your ship status */
+#define SP_S_PLAYER     45	/* variable length player packet */
+#endif
+
+#define SP_PING         46	/* ping packet */
+
+#ifdef SHORT_PACKETS
+#define SP_S_TORP       47	/* variable length torp packet */
+#define SP_S_TORP_INFO  48	/* SP_S_TORP with TorpInfo */
+#define SP_S_8_TORP     49	/* optimized SP_S_TORP */
+#define SP_S_PLANET     50	/* see SP_PLANET */
+
+/* variable length packets */
+#define VPLAYER_SIZE    4
+#define SHORTVERSION    10	/* other number blocks, like UDP Version */
+#endif
+
+#define SP_GPARAM	51	/* game params packet */
+
+/* the following is a family of packets with the same type, but a
+   discriminating subtype */
+#define SP_PARADISE_EXT1	52
+#define SP_PE1_MISSING_BITMAP	0
+#define SP_PE1_NUM_MISSILES	1
+/* end of packet 52 subtypes */
+#define SP_TERRAIN2	53	/* Terrain packets */
+#define SP_TERRAIN_INFO2 54	/* Terrain info */
+
+#ifdef FEATURE
+/* feature_spacket, response to feature_cpacket requests. identical structures */
+#define SP_FEATURE              60
+#endif
+
+#ifdef RECORDER
+/* special type tells us when to update the display on playback.
+   Not sent or received, only placed in the recorder file */
+#define REC_UPDATE 127
+#endif
+
+/* packets sent from remote client to xtrek server */
+#define CP_MESSAGE      1	/* send a message */
+#define CP_SPEED	2	/* set speed */
+#define CP_DIRECTION	3	/* change direction */
+#define CP_PHASER	4	/* phaser in a direction */
+#define CP_PLASMA	5	/* plasma (in a direction) */
+#define CP_TORP		6	/* fire torp in a direction */
+#define CP_QUIT		7	/* self destruct */
+#define CP_LOGIN	8	/* log in (name, password) */
+#define CP_OUTFIT	9	/* outfit to new ship */
+#define CP_WAR		10	/* change war status */
+#define CP_PRACTR	11	/* create practice robot? */
+#define CP_SHIELD	12	/* raise/lower sheilds */
+#define CP_REPAIR	13	/* enter repair mode */
+#define CP_ORBIT	14	/* orbit planet/starbase */
+#define CP_PLANLOCK	15	/* lock on planet */
+#define CP_PLAYLOCK	16	/* lock on player */
+#define CP_BOMB		17	/* bomb a planet */
+#define CP_BEAM		18	/* beam armies up/down */
+#define CP_CLOAK	19	/* cloak on/off */
+#define CP_DET_TORPS	20	/* detonate enemy torps */
+#define CP_DET_MYTORP	21	/* detonate one of my torps */
+#define CP_COPILOT	22	/* toggle copilot mode */
+#define CP_REFIT	23	/* refit to different ship type */
+#define CP_TRACTOR	24	/* tractor on/off */
+#define CP_REPRESS	25	/* pressor on/off */
+#define CP_COUP		26	/* coup home planet */
+#define CP_SOCKET	27	/* new socket for reconnection */
+#define CP_OPTIONS	28	/* send my options to be saved */
+#define CP_BYE		29	/* I'm done! */
+#define CP_DOCKPERM	30	/* set docking permissions */
+#define CP_UPDATES	31	/* set number of usecs per update */
+#define CP_RESETSTATS	32	/* reset my stats packet */
+#define CP_RESERVED	33	/* for future use */
+
+#define CP_SCAN		34	/* ATM: request for player scan */
+
+#define CP_UDP_REQ	35	/* request UDP on/off */
+#define CP_SEQUENCE	36	/* sequence # packet */
+#define CP_RSA_KEY	37	/* request MOTD */
+#define CP_ASK_MOTD	38	/* request MOTD */
+
+#define CP_PING_RESPONSE 42	/* client response */
+
+#ifdef SHORT_PACKETS
+#define CP_S_REQ                43
+#define CP_S_THRS               44
+#define CP_S_MESSAGE    45	/* vari. Message Packet */
+#define CP_S_RESERVED       46
+#define CP_S_DUMMY      47
+#endif
+
+#ifdef FEATURE
+#define CP_FEATURE   60
+#endif
+
+#define SOCKVERSION 	4
+#define UDPVERSION	10	/* changing this blocks other */
+ /* versions */
+
+struct packet_handler {
+    void    (*handler) ();
+};
+
+
+/*
+ * These are server --> client packets
+ */
+
+struct mesg_spacket {
+    INT8    type;		/* SP_MESSAGE */
+    CARD8   m_flags;
+    CARD8   m_recpt;
+    CARD8   m_from;
+    char    mesg[80];
+};
+
+struct plyr_info_spacket {
+    INT8    type;		/* SP_PLAYER_INFO */
+    INT8    pnum;
+    INT8    shiptype;
+    INT8    team;
+};
+
+struct kills_spacket {
+    INT8    type;		/* SP_KILLS */
+    INT8    pnum;
+    INT8    pad1;
+    INT8    pad2;
+    CARD32  kills;		/* where 1234=12.34 kills and 0=0.00 kills */
+};
+
+struct player_spacket {
+    INT8    type;		/* SP_PLAYER */
+    INT8    pnum;
+    CARD8   dir;
+    INT8    speed;
+    INT32   x, y;
+};
+
+struct torp_info_spacket {
+    INT8    type;		/* SP_TORP_INFO */
+    INT8    war;
+    INT8    status;		/* TFREE, TDET, etc... */
+    INT8    pad1;		/* pad needed for cross cpu compatibility */
+    INT16   tnum;
+    INT16   pad2;
+};
+
+struct torp_spacket {
+    INT8    type;		/* SP_TORP */
+    CARD8   dir;
+    INT16   tnum;
+    INT32   x, y;
+};
+
+/* Shapes of thingys.  It would be best to add to the end of this list and
+   try to coordinate your additions with other hackers. */
+enum thingy_types {
+    SHP_BLANK, SHP_MISSILE, SHP_BOOM, SHP_TORP, SHP_PLASMA, SHP_MINE,
+    SHP_PBOOM, SHP_FIGHTER, SHP_WARP_BEACON
+};
+
+struct thingy_info_spacket {
+    INT8    type;		/* SP_THINGY_INFO */
+    INT8    war;
+    INT16   shape;		/* a thingy_types */
+    INT16   tnum;
+    INT16   owner;
+};
+
+struct thingy_spacket {
+    INT8    type;		/* SP_THINGY */
+    CARD8   dir;
+    INT16   tnum;
+    INT32   x, y;
+};
+
+struct phaser_spacket {
+    INT8    type;		/* SP_PHASER */
+    INT8    pnum;
+    INT8    status;		/* PH_HIT, etc... */
+    CARD8   dir;
+    INT32   x, y;
+    INT32   target;
+};
+
+struct plasma_info_spacket {
+    INT8    type;		/* SP_PLASMA_INFO */
+    INT8    war;
+    INT8    status;		/* TFREE, TDET, etc... */
+    INT8    pad1;		/* pad needed for cross cpu compatibility */
+    INT16   pnum;
+    INT16   pad2;
+};
+
+struct plasma_spacket {
+    INT8    type;		/* SP_PLASMA */
+    INT8    pad1;
+    INT16   pnum;
+    INT32   x, y;
+};
+
+struct warning_spacket {
+    INT8    type;		/* SP_WARNING */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+    char    mesg[80];
+};
+
+struct motd_spacket {
+    INT8    type;		/* SP_MOTD */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+    char    line[80];
+};
+
+struct you_spacket {
+    INT8    type;		/* SP_YOU */
+    INT8    pnum;		/* Guy needs to know this... */
+    INT8    hostile;
+    INT8    swar;
+    INT8    armies;
+    INT8    tractor;		/* ATM - visible tractor (was pad1) */
+    CARD8   pad2;
+    CARD8   pad3;
+    CARD32  flags;
+    INT32   damage;
+    INT32   shield;
+    INT32   fuel;
+    INT16   etemp;
+    INT16   wtemp;
+    INT16   whydead;
+    INT16   whodead;
+};
+
+struct queue_spacket {
+    INT8    type;		/* SP_QUEUE */
+    INT8    pad1;
+    INT16   pos;
+};
+
+struct status_spacket {
+    INT8    type;		/* SP_STATUS */
+    INT8    tourn;
+    INT8    pad1;
+    INT8    pad2;
+    CARD32  armsbomb;
+    CARD32  planets;
+    CARD32  kills;
+    CARD32  losses;
+    CARD32  time;
+    CARD32  timeprod;
+};
+
+struct planet_spacket {
+    INT8    type;		/* SP_PLANET */
+    INT8    pnum;
+    INT8    owner;
+    INT8    info;
+    INT16   flags;
+    INT16   pad2;
+    INT32   armies;
+};
+
+/* terrain info for Paradise terrain */
+/* 5/16/95 rpg */
+
+struct terrain_info_packet2 {
+    CARD8   type;		/* SP_TERRAIN_INFO2 */
+    CARD8   pad;
+    CARD16  pad2;
+    CARD16  xdim;
+    CARD16  ydim;
+};
+
+struct terrain_packet2 {
+    CARD8   type;		/* SP_TERRAIN2 */
+    CARD8   sequence;
+    CARD8   total_pkts;
+    CARD8   length;
+    CARD8   terrain_type[128];	/* Ugh... this needs to be fixed 5/16/95 rpg */
+ /* CARD16  terrain_alt1[128]; */
+ /* CARD16  terrain_alt2[128]; */
+};
+
+struct pickok_spacket {
+    INT8    type;		/* SP_PICKOK */
+    INT8    state;
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct login_spacket {
+    INT8    type;		/* SP_LOGIN */
+    INT8    accept;		/* 1/0 */
+    INT8    pad2;
+    INT8    pad3;
+    INT32   flags;
+    char    keymap[96];
+};
+
+struct flags_spacket {
+    INT8    type;		/* SP_FLAGS */
+    INT8    pnum;		/* whose flags are they? */
+    INT8    tractor;		/* ATM - visible tractors */
+    INT8    pad2;
+    CARD32  flags;
+};
+
+struct mask_spacket {
+    INT8    type;		/* SP_MASK */
+    INT8    mask;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct pstatus_spacket {
+    INT8    type;		/* SP_PSTATUS */
+    INT8    pnum;
+    INT8    status;
+    INT8    pad1;
+};
+
+struct badversion_spacket {
+    INT8    type;		/* SP_BADVERSION */
+    INT8    why;
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct hostile_spacket {
+    INT8    type;		/* SP_HOSTILE */
+    INT8    pnum;
+    INT8    war;
+    INT8    hostile;
+};
+
+struct stats_spacket {
+    INT8    type;		/* SP_STATS */
+    INT8    pnum;
+    INT8    pad1;
+    INT8    pad2;
+    INT32   tkills;		/* Tournament kills */
+    INT32   tlosses;		/* Tournament losses */
+    INT32   kills;		/* overall */
+    INT32   losses;		/* overall */
+    INT32   tticks;		/* ticks of tournament play time */
+    INT32   tplanets;		/* Tournament planets */
+    INT32   tarmies;		/* Tournament armies */
+    INT32   sbkills;		/* Starbase kills */
+    INT32   sblosses;		/* Starbase losses */
+    INT32   armies;		/* non-tourn armies */
+    INT32   planets;		/* non-tourn planets */
+    INT32   maxkills;		/* max kills as player * 100 */
+    INT32   sbmaxkills;		/* max kills as sb * 100 */
+};
+
+struct plyr_login_spacket {
+    INT8    type;		/* SP_PL_LOGIN */
+    INT8    pnum;
+    INT8    rank;
+    INT8    pad1;
+    char    name[16];
+    char    monitor[16];
+    char    login[16];
+};
+
+struct reserved_spacket {
+    INT8    type;		/* SP_RESERVED */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+    INT8    data[16];
+};
+
+struct planet_loc_spacket {
+    INT8    type;		/* SP_PLANET_LOC */
+    INT8    pnum;
+    INT8    pad2;
+    INT8    pad3;
+    INT32   x;
+    INT32   y;
+    char    name[16];
+};
+
+struct scan_spacket {		/* ATM */
+    INT8    type;		/* SP_SCAN */
+    INT8    pnum;
+    INT8    success;
+    INT8    pad1;
+    INT32   p_fuel;
+    INT32   p_armies;
+    INT32   p_shield;
+    INT32   p_damage;
+    INT32   p_etemp;
+    INT32   p_wtemp;
+};
+
+struct udp_reply_spacket {	/* UDP */
+    INT8    type;		/* SP_UDP_REPLY */
+    INT8    reply;
+    INT8    pad1;
+    INT8    pad2;
+    INT32   port;
+};
+
+struct sequence_spacket {	/* UDP */
+    INT8    type;		/* SP_SEQUENCE */
+    INT8    pad1;
+    CARD16  sequence;
+};
+struct sc_sequence_spacket {	/* UDP */
+    INT8    type;		/* SP_CP_SEQUENCE */
+    INT8    pad1;
+    CARD16  sequence;
+};
+
+/*
+ * Game configuration.
+ * KAO 1/23/93
+ */
+
+struct ship_cap_spacket {	/* Server configuration of client */
+    INT8    type;		/* screw motd method */
+    INT8    operation;		/* 0 = add/change a ship, 1 = remove a ship */
+    INT16   s_type;		/* SP_SHIP_CAP */
+    INT16   s_torpspeed;
+    INT16   s_phaserrange;
+    INT32   s_maxspeed;
+    INT32   s_maxfuel;
+    INT32   s_maxshield;
+    INT32   s_maxdamage;
+    INT32   s_maxwpntemp;
+    INT32   s_maxegntemp;
+    INT16   s_width;
+    INT16   s_height;
+    INT16   s_maxarmies;
+    INT8    s_letter;
+    INT8    pad2;
+    char    s_name[16];
+    INT8    s_desig1;
+    INT8    s_desig2;
+    INT16   s_bitmap;
+};
+
+struct motd_pic_spacket {
+    INT8    type;		/* SP_MOTD_PIC */
+    INT8    pad1;
+    INT16   x, y, page;
+    INT16   width, height;
+    INT8    bits[1016];
+};
+
+
+ /* This is used to send paradise style stats */
+struct stats_spacket2 {
+    INT8    type;		/* SP_STATS2 */
+    INT8    pnum;
+    INT8    pad1;
+    INT8    pad2;
+
+    INT32   genocides;		/* number of genocides participated in */
+    INT32   maxkills;		/* max kills ever * 100  */
+    INT32   di;			/* destruction inflicted for all time * 100 */
+    INT32   kills;		/* Kills in tournament play */
+    INT32   losses;		/* Losses in tournament play */
+    INT32   armsbomb;		/* Tournament armies bombed */
+    INT32   resbomb;		/* resources bombed off */
+    INT32   dooshes;		/* armies killed while being carried */
+    INT32   planets;		/* Tournament planets conquered */
+    INT32   tticks;		/* Tournament ticks */
+    /* SB/WB/JS stats are entirely separate */
+    INT32   sbkills;		/* Kills as starbase */
+    INT32   sblosses;		/* Losses as starbase */
+    INT32   sbticks;		/* Time as starbase */
+    INT32   sbmaxkills;		/* Max kills as starbase * 100 */
+    INT32   wbkills;		/* Kills as warbase */
+    INT32   wblosses;		/* Losses as warbase */
+    INT32   wbticks;		/* Time as warbase */
+    INT32   wbmaxkills;		/* Max kills as warbase * 100 */
+    INT32   jsplanets;		/* planets assisted with in JS */
+    INT32   jsticks;		/* ticks played as a JS */
+    INT32   rank;		/* Ranking of the player */
+    INT32   royal;		/* royaly, specialty, rank */
+};
+
+ /* status info for paradise stats */
+struct status_spacket2 {
+    INT8    type;		/* SP_STATUS2 */
+    INT8    tourn;
+    INT8    pad1;
+    INT8    pad2;
+    CARD32  dooshes;		/* total number of armies dooshed */
+    CARD32  armsbomb;		/* all t-mode armies bombed */
+    CARD32  resbomb;		/* resources bombed */
+    CARD32  planets;		/* all t-mode planets taken */
+    CARD32  kills;		/* all t-mode kills made */
+    CARD32  losses;		/* all t-mode losses */
+    CARD32  sbkills;		/* total kills in SB's */
+    CARD32  sblosses;		/* total losses in Sb's */
+    CARD32  sbtime;		/* total time in SB's */
+    CARD32  wbkills;		/* kills in warbases */
+    CARD32  wblosses;		/* losses in warbases */
+    CARD32  wbtime;		/* total time played in wb's */
+    CARD32  jsplanets;		/* total planets taken by jump ships */
+    CARD32  jstime;		/* total time in a jump ship */
+    CARD32  time;		/* t mode time in this game */
+    CARD32  timeprod;		/* t-mode ship ticks--sort of like */
+};
+
+
+ /* planet info for a paradise planet */
+struct planet_spacket2 {
+    INT8    type;		/* SP_PLANET2 */
+    INT8    pnum;		/* planet number */
+    INT8    owner;		/* owner of the planet */
+    INT8    info;		/* who has touched planet */
+    INT32   flags;		/* planet's flags */
+    INT32   timestamp;		/* timestamp for info on planet */
+    INT32   armies;		/* armies on the planet */
+};
+
+struct obvious_packet {
+    INT8    type;		/* SP_NEW_MOTD */
+    INT8    pad1;		/* CP_ASK_MOTD */
+};
+
+struct rsa_key_spacket {
+    INT8    type;		/* SP_RSA_KEY */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+    CARD8   data[KEY_SIZE];
+};
+
+
+struct ping_spacket {
+    INT8    type;		/* SP_PING */
+    CARD8   number;		/* id (ok to wrap) */
+    CARD16  lag;		/* delay of last ping in ms */
+
+    CARD8   tloss_sc;		/* total loss server-client 0-100% */
+    CARD8   tloss_cs;		/* total loss client-server 0-100% */
+
+    CARD8   iloss_sc;		/* inc. loss server-client 0-100% */
+    CARD8   iloss_cs;		/* inc. loss client-server 0-100% */
+};
+
+struct paradiseext1_spacket {
+    INT8    type;
+    CARD8   subtype;
+    INT16   pad;
+};
+
+struct pe1_missing_bitmap_spacket {
+    INT8    type;
+    CARD8   subtype;
+
+    INT16   page;
+
+    INT16   x, y;
+    INT16   width, height;
+};
+
+struct pe1_num_missiles_spacket {
+    INT8    type;		/* SP_PARADISE_EXT1 */
+    CARD8   subtype;		/* SP_PE1_NUM_MISSILES */
+
+    INT16   num;		/* number of missiles */
+};
+
+/*
+ * These are the client --> server packets
+ */
+
+struct mesg_cpacket {
+    INT8    type;		/* CP_MESSAGE */
+    INT8    group;
+    INT8    indiv;
+    INT8    pad1;
+    char    mesg[80];
+};
+
+struct speed_cpacket {
+    INT8    type;		/* CP_SPEED */
+    INT8    speed;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct dir_cpacket {
+    INT8    type;		/* CP_DIRECTION */
+    CARD8   dir;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct phaser_cpacket {
+    INT8    type;		/* CP_PHASER */
+    CARD8   dir;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct plasma_cpacket {
+    INT8    type;		/* CP_PLASMA */
+    CARD8   dir;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct torp_cpacket {
+    INT8    type;		/* CP_TORP */
+    CARD8   dir;		/* direction to fire torp */
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct quit_cpacket {
+    INT8    type;		/* CP_QUIT */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct login_cpacket {
+    INT8    type;		/* CP_LOGIN */
+    INT8    query;
+    INT8    pad2;
+    INT8    pad3;
+    char    name[16];
+    char    password[16];
+    char    login[16];
+};
+
+struct outfit_cpacket {
+    INT8    type;		/* CP_OUTFIT */
+    INT8    team;
+    INT8    ship;
+    INT8    pad1;
+};
+
+struct war_cpacket {
+    INT8    type;		/* CP_WAR */
+    INT8    newmask;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct practr_cpacket {
+    INT8    type;		/* CP_PRACTR */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct shield_cpacket {
+    INT8    type;		/* CP_SHIELD */
+    INT8    state;		/* up/down */
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct repair_cpacket {
+    INT8    type;		/* CP_REPAIR */
+    INT8    state;		/* on/off */
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct orbit_cpacket {
+    INT8    type;		/* CP_ORBIT */
+    INT8    state;		/* on/off */
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct planlock_cpacket {
+    INT8    type;		/* CP_PLANLOCK */
+    INT8    pnum;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct playlock_cpacket {
+    INT8    type;		/* CP_PLAYLOCK */
+    INT8    pnum;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct bomb_cpacket {
+    INT8    type;		/* CP_BOMB */
+    INT8    state;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct beam_cpacket {
+    INT8    type;		/* CP_BEAM */
+    INT8    state;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct cloak_cpacket {
+    INT8    type;		/* CP_CLOAK */
+    INT8    state;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct det_torps_cpacket {
+    INT8    type;		/* CP_DET_TORPS */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct det_mytorp_cpacket {
+    INT8    type;		/* CP_DET_MYTORP */
+    INT8    pad1;
+    INT16   tnum;
+};
+
+struct copilot_cpacket {
+    INT8    type;		/* CP_COPLIOT */
+    INT8    state;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct refit_cpacket {
+    INT8    type;		/* CP_REFIT */
+    INT8    ship;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct tractor_cpacket {
+    INT8    type;		/* CP_TRACTOR */
+    INT8    state;
+    INT8    pnum;
+    INT8    pad2;
+};
+
+struct repress_cpacket {
+    INT8    type;		/* CP_REPRESS */
+    INT8    state;
+    INT8    pnum;
+    INT8    pad2;
+};
+
+struct coup_cpacket {
+    INT8    type;		/* CP_COUP */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct socket_cpacket {
+    INT8    type;		/* CP_SOCKET */
+    INT8    version;
+    INT8    udp_version;	/* was pad2 */
+    INT8    pad3;
+    CARD32  socket;
+};
+
+struct options_cpacket {
+    INT8    type;		/* CP_OPTIONS */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+    CARD32  flags;
+    INT8    keymap[96];
+};
+
+struct bye_cpacket {
+    INT8    type;		/* CP_BYE */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct dockperm_cpacket {
+    INT8    type;		/* CP_DOCKPERM */
+    INT8    state;
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct updates_cpacket {
+    INT8    type;		/* CP_UPDATES */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+    CARD32  usecs;
+};
+
+struct resetstats_cpacket {
+    INT8    type;		/* CP_RESETSTATS */
+    INT8    verify;		/* 'Y' - just to make sure he meant it */
+    INT8    pad2;
+    INT8    pad3;
+};
+
+struct reserved_cpacket {
+    INT8    type;		/* CP_RESERVED */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+    INT8    data[16];
+    INT8    resp[16];
+};
+
+struct scan_cpacket {		/* ATM */
+    INT8    type;		/* CP_SCAN */
+    INT8    pnum;
+    INT8    pad1;
+    INT8    pad2;
+};
+
+struct udp_req_cpacket {	/* UDP */
+    INT8    type;		/* CP_UDP_REQ */
+    INT8    request;
+    INT8    connmode;		/* respond with port # or just send UDP
+				   packet? */
+    INT8    pad2;
+    INT32   port;		/* compensate for hosed recvfrom() */
+};
+
+struct sequence_cpacket {	/* UDP */
+    INT8    type;		/* CP_SEQUENCE */
+    INT8    pad1;
+    CARD16  sequence;
+};
+
+struct rsa_key_cpacket {
+    INT8    type;		/* CP_RSA_KEY */
+    INT8    pad1;
+    INT8    pad2;
+    INT8    pad3;
+    CARD8   global[KEY_SIZE];
+    CARD8   public[KEY_SIZE];
+    CARD8   resp[KEY_SIZE];
+};
+
+/* the CP_ASK_MOTD packet is the same as temp_spacket */
+
+struct ping_cpacket {
+    INT8    type;		/* CP_PING_RESPONSE */
+    CARD8   number;		/* id */
+    INT8    pingme;		/* if client wants server to ping */
+    INT8    pad1;
+
+    INT32   cp_sent;		/* # packets sent to server */
+    INT32   cp_recv;		/* # packets recv from server */
+};
+
+
+#ifdef FEATURE
+/* feature_cpacket and _spacket are identical! */
+struct feature_cpacket {	/* CP_FEATURE */
+    INT8    type;
+    char    feature_type;	/* either 'C' or 'S' */
+    CARD8   arg1;               /* could be INT8 depending on feature */
+    CARD8   arg2;               /* but only BEEP_LITE uses it, for now */
+    INT32   value;
+    char    name[80];
+};
+
+struct feature_spacket {	/* SP_FEATURE */
+    INT8    type;
+    char    feature_type;	/* either 'C' or 'S' */
+    CARD8   arg1;
+    CARD8   arg2;
+    INT32    value;
+    char    name[80];
+};
+#endif				/* FEATURE */
+
+/*
+ * short stuff
+ */
+
+#ifdef SHORT_PACKETS
+struct shortreq_cpacket {	/* CP_S_REQ */
+    INT8    type;
+    INT8    req;
+    INT8    version;
+    INT8    pad2;
+};
+
+struct threshold_cpacket {	/* CP_S_THRS */
+    INT8    type;
+    INT8    pad1;
+    CARD16  thresh;
+};
+
+struct shortreply_spacket {	/* SP_S_REPLY */
+    INT8    type;
+    INT8    repl;
+    CARD16  winside;
+    INT32   gwidth;
+};
+
+struct youshort_spacket {	/* SP_S_YOU */
+    INT8    type;
+
+    INT8    pnum;
+    INT8    hostile;
+    INT8    swar;
+
+    INT8    armies;
+    INT8    whydead;
+    INT8    whodead;
+
+    INT8    pad1;
+
+    CARD32  flags;
+};
+
+struct youss_spacket {		/* SP_S_YOU_SS */
+    INT8    type;
+    INT8    pad1;
+
+    CARD16  damage;
+    CARD16  shield;
+    CARD16  fuel;
+    CARD16  etemp;
+    CARD16  wtemp;
+};
+
+#define VPLANET_SIZE 6
+
+struct planet_s_spacket {	/* body of SP_S_PLANET  */
+    INT8    pnum;
+    INT8    owner;
+    INT8    info;
+    CARD8   armies;		/* more than 255 Armies ? ...  */
+    INT16   flags;
+};
+struct warning_s_spacket {	/* SP_S_WARNING */
+    INT8    type;
+    CARD8   whichmessage;
+    INT8    argument, argument2;/* for phaser  etc ... */
+};
+
+struct player_s_spacket {
+    INT8    type;		/* SP_S_PLAYER Header */
+    INT8    packets;		/* How many player-packets are in this packet
+				   ( only the first 6 bits are relevant ) */
+    CARD8   dir;
+    INT8    speed;
+    INT32   x, y;		/* To get the absolute Position */
+};
+
+/* The format of the body:
+struct player_s_body_spacket {	Body of new Player Packet
+	CARD8 pnum;	 0-4 = pnum, 5 local or galactic, 6 = 9. x-bit, 7 9. y-bit
+	CARD8 speeddir;	 0-3 = speed , 4-7 direction of ship
+	CARD8 x;	 low 8 bits from X-Pixelcoordinate
+	CARD8 y;	 low 8 bits from Y-Pixelcoordinate
+};
+*/
+
+struct torp_s_spacket {
+    INT8    type;		/* SP_S_TORP */
+    CARD8   bitset;		/* bit=1 that torp is in packet */
+    CARD8   whichtorps;		/* Torpnumber of first torp / 8 */
+    CARD8   data[21];		/* For every torp 2*9 bit coordinates */
+};
+
+struct mesg_s_spacket {
+    INT8    type;		/* SP_S_MESSAGE */
+    CARD8   m_flags;
+    CARD8   m_recpt;
+    CARD8   m_from;
+    CARD8   length;		/* Length of whole packet */
+    INT8    mesg;
+    INT8    pad2;
+    INT8    pad3;
+    INT8    pad[76];
+};
+
+struct mesg_s_cpacket {
+    INT8    type;		/* CP_S__MESSAGE */
+    INT8    group;
+    INT8    indiv;
+    INT8    length;		/* Size of whole packet   */
+    INT8    mesg[80];
+};
+
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paradise.sndsrv.freebsd.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,295 @@
+/*
+ * paradise.sndsrv.c - USS-Lite Compatible Sound - July 1996
+ *                     This server is FreeBSD Specific.
+ * Sujal M. Patel (smpatel@umiacs.umd.edu)
+ *
+ *
+ * Copyright (c) 1994-1996, Sujal M. Patel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      $Id: paradise.sndsrv.freebsd.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <machine/soundcard.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <string.h>
+
+
+
+char *FILENAME[] = {
+                     "/explode.raw",
+                     "/cloak.raw",
+                     "/firetorp.raw",
+                     "/phaser.raw",
+                     "/plasma.raw",
+                     "/shield.raw",
+                     "/torphit.raw",
+                     "/explode_big.raw",
+                     "/paradise.raw",
+                     "/thermal.raw",
+                     "/redalert.raw"
+                   };
+
+#define NUM_SOUNDS	(sizeof(FILENAME)/sizeof(char*))
+
+signed char *sound_buffer[NUM_SOUNDS];
+int sound_size[NUM_SOUNDS];
+int fragsize;
+
+
+/* Terminate: Signal Handler */
+void quit ()
+{
+  exit (0);
+}
+
+
+
+void init (int argc, char **argv)
+{
+  int i;
+  char s[1024];
+
+  if (argc != 3)
+  {
+    printf ("This program is only executed by netrek.paradise\n");
+    exit (1);
+  }
+
+  for (i=0; i < NUM_SOUNDS; i++)
+  {
+    s[0] = 0;
+    strcat (s, argv[1]);
+    if (s[(int)strlen(s) - 1] == '/') FILENAME[i]++;
+    strcat (s, FILENAME[i]);
+    FILENAME[i] = malloc ((int)strlen (s));
+    strcpy (FILENAME[i],s);
+    sound_buffer[i]=NULL;
+    sound_size[i]=0;
+  }
+
+  signal(SIGTERM, quit);   /* Setup Terminate Signal Handler */
+}
+
+
+/*
+   Setup DSP: Opens /dev/dsp or /dev/pcdsp
+              Sets fragment size on VoxWare
+              Sets speed to 8000hz
+              Should set mono mode
+              Error checking                
+*/
+int setup_dsp (char *dspdev,int *is_pcsp)
+{
+  int dsp, frag, value;
+  int mixer;
+
+  dsp = open(dspdev, O_RDWR);
+  if (dsp < 1)
+  {
+    fprintf (stderr, "paradise.sndsrv: Couldn't open device %s\n",dspdev);
+    return -1;
+  }
+ 
+  *is_pcsp = 0;
+  fragsize = 0;
+
+  frag = 0x00020009;   /* try 512 bytes, for 1/16 second frag size */
+  ioctl(dsp, SNDCTL_DSP_SETFRAGMENT, &frag);
+  value = 8010;
+  if (ioctl(dsp, SNDCTL_DSP_SPEED, &value))
+  {
+      fprintf (stderr, "paradise.sndsrv: Couldn't set DSP rate!\n");
+  };
+  value = 0;
+  ioctl(dsp, SNDCTL_DSP_STEREO, &value);
+  ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &fragsize);
+  /*fprintf(stderr,"paradise.sndsrv: fragment set to %d\n",fragsize);*/
+
+  if (!fragsize)
+  { 
+    /* Don't Assume just because you can't set the fragment, use proper IOCTL */
+    fprintf (stderr, "paradise.sndsrv: Couldn't set Fragment Size.\nAssuming PC Speaker!\n");
+    fragsize = 128;
+    *is_pcsp = 1;
+  } else {
+      mixer = open("/dev/mixer",O_RDWR | O_NONBLOCK);
+      if(mixer==-1)  {
+          fprintf(stderr,"paradise.sndsrv: Couldn't open mixer %s\n","/dev/mixer");
+          return(-1);
+      };
+      value=0x6464;
+      ioctl(mixer,SOUND_MIXER_WRITE_PCM,&value);
+      ioctl(mixer,SOUND_MIXER_WRITE_VOLUME,&value);  /*what does this do?*/
+      close(mixer);
+  }
+  
+  return dsp;
+}
+
+/*
+   This just keeps the pipe from breaking...
+   Eventually I'll look at the paradise signal handlers and
+   just trap this.
+*/
+int do_nothing(void)
+{
+    while(1)  sleep (5);
+}
+
+int read_sound(int k)
+{
+  int i,fd,size;
+
+  /*fprintf(stderr,"loading sound %d, %s\n",k,FILENAME[k]);*/
+
+  fd = open(FILENAME[k], O_RDONLY);
+  if(fd<=0) 
+  {
+    fprintf (stderr, "paradise.sndsrv: The sound %s could not be opened\n", FILENAME[k]);
+    sound_size[k]=-1;
+    return(0);
+  };
+  size=lseek(fd,0,SEEK_END);
+  sound_size[k]=(size/fragsize)+1;   /*size in fragments*/
+  sound_buffer[k]=malloc(sound_size[k]*fragsize);
+  if(sound_buffer[k]==NULL)
+  {
+    fprintf(stderr,"paradise.sndsrv: couldn't malloc memory for sound\n");
+    sound_size[k]=-1;
+    close(fd);
+    return(0);
+  };
+  lseek(fd,0,SEEK_SET);
+  read(fd,sound_buffer[k],size);
+  close(fd);
+  for(i=0;i<size;i++)  sound_buffer[k][i]^=0x80;
+  memset(sound_buffer[k]+size,0,sound_size[k]*fragsize-size);
+  
+  /*fprintf(stderr,"sound has been loaded, %d bytes\n",size);*/ /*DEBUG*/
+  return(1);
+}
+
+
+void do_everything (int dsp, int is_pcsp)
+{
+  char k;
+  int i, j ;
+  int terminate = -1;             /* Which Sound to Terminate                              */
+  int playing[16];                /* Sound numbers that we are playing                     */
+  int position[16];		  /* Current position in each sound file */
+  int playnum = 0;                /* Number of sounds currently being played               */
+  unsigned char final[512];       /* Final Mixing Buffer                                   */
+  int premix[512];
+  char *sample;
+
+  for(;;)  {
+    terminate = -1;
+    /* Try to open a new sound if we get an integer on the 'in' pipe */
+    i=read(STDIN_FILENO,&k,sizeof(k));
+    if(i==0)  {   /* EOF on pipe means parent has closed its end */
+        /*fprintf(stderr,"paradise.sndsrv: shutting down\n"); */
+        kill(getpid(), SIGTERM);
+    };
+    if(i!=-1)  {  /* there was something in the pipe */
+        /*fprintf(stderr,"Just read a %d from pipe\n",(int)k);*/ /*DEBUG*/
+        /* Negative means terminate the FIRST sound in the buffer */
+        if(k<0)  {
+            /*fprintf(stderr,"terminating sound\n");*/ /*DEBUG*/
+            terminate = 0;
+        } else {
+            if(sound_size[k]==0) read_sound(k);
+            if(sound_size[k]>0 && playnum<16)  {
+	        position[playnum]=0;
+                playing[playnum++]=k;
+                /*fprintf(stderr,"sound %d added to play queue\n",playnum-1);*/ /*DEBUG*/
+            };
+        };
+    };
+
+    /* terminate a sound if necessary */
+    for(i=0;i<playnum;i++)
+    {
+      if((position[i]==sound_size[playing[i]]) || (terminate==i))
+      {
+        /*fprintf(stderr,"finished playing sound %d\n",i);*/ /*DEBUG*/
+	/*fprintf(stderr,"is was at position %d\n",position[i]);*/ /*DEBUG*/
+        memmove(playing+i,playing+i+1,(playnum-i)*sizeof(int));
+        memmove(position+i,position+i+1,(playnum-i)*sizeof(int));
+        playnum--;i--;
+      };
+    };
+
+    if(playnum)  {
+        /* Mix each sound into the final buffer */
+        memset(premix,0,sizeof(premix));
+        for(i=0;i<playnum;i++)  {
+            sample=sound_buffer[playing[i]]+position[i]*fragsize;
+            for(j=0;j<fragsize;j++)  {
+                premix[j]+=*(sample+j);
+            };
+            position[i]++;
+        };
+        for(i=0;i<fragsize;i++)
+            final[i]=(premix[i]>255)?255:(premix[i]<-256?0:(premix[i]>>1)+128);
+    } else {
+        /* 
+           We have no sounds to play
+           Just fill the buffer with silence and maybe play it 
+        */
+        memset(final,128,sizeof(final));
+    };
+    write (dsp, final, fragsize);
+    /*
+       The sound server is in a tight loop, EXCEPT for this
+       write which blocks.  Any optimizations in the above
+       code would really be helpful.  Right now the server
+       takes up to 7% cpu on a 486DX/50.
+    */
+  }
+}
+
+
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+  int dsp, is_pcsp, ppid;
+  char filename[512];
+
+  fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
+  init (argc, argv);
+  dsp = setup_dsp (argv[2],&is_pcsp);
+
+  if (dsp < 1) do_nothing();
+
+  do_everything (dsp, is_pcsp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paradise.sndsrv.hp.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,293 @@
+/*
+ * paradise.sndsrv.c - USS-Lite Compatible Sound - July 1996
+ *                     This server is HP/UX Specific.
+ * Sujal M. Patel (smpatel@umiacs.umd.edu)
+ *
+ *
+ * Copyright (c) 1994-1996, Sujal M. Patel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      $Id: paradise.sndsrv.hp.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/audio.h>
+#include <signal.h>
+#include <string.h>
+
+
+char *FILENAME[] = {
+                     "/explode.raw",
+                     "/cloak.raw",
+                     "/firetorp.raw",
+                     "/phaser.raw",
+                     "/plasma.raw",
+                     "/shield.raw",
+                     "/torphit.raw",
+                     "/explode_big.raw",
+                     "/paradise.raw",
+                     "/thermal.raw",
+                     "/redalert.raw"
+                   };
+
+#define NUM_SOUNDS      (sizeof(FILENAME)/sizeof(char*))
+
+signed char *sound_buffer[NUM_SOUNDS];
+int sound_size[NUM_SOUNDS];
+#define fragsize (256)
+
+
+/* Terminate: Signal Handler */
+void quit ()
+{
+  exit (0);
+}
+
+
+
+void init (int argc, char **argv)
+{
+  int i;
+  char s[1024];
+
+  if (argc != 3)
+  {
+    printf ("This program is only executed by Paradise\n");
+    exit (1);
+  }
+
+  for (i=0; i < NUM_SOUNDS; i++)
+  {
+    s[0] = 0;
+    strcat (s, argv[1]);
+    if (s[(int)strlen(s) - 1] == '/') FILENAME[i]++;
+    strcat (s, FILENAME[i]);
+    FILENAME[i] = malloc ((int)strlen (s)+1);
+    strcpy (FILENAME[i],s);
+    sound_buffer[i]=NULL;
+    sound_size[i]=0;
+  }
+
+  signal(SIGTERM, quit);   /* Setup Terminate Signal Handler */
+}
+
+
+/*
+   Setup DSP: Opens /dev/audio
+              Sets fragment size to 512
+              Error checking                
+*/
+int setup_dsp (char *dspdev)
+{
+  int dsp, frag, value;
+  int mixer;
+
+  dsp = open(dspdev, O_RDWR);
+  if (dsp < 1)
+  {
+    fprintf (stderr, "paradise.sndsrv: Couldn't open device %s\n",dspdev);
+    return -1;
+  }
+ 
+	if (-1 == ioctl(dsp, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_LINEAR16BIT)) {
+		fprintf(stderr,"paradise.sndsrv: parameter setting failed");
+		return;
+	}
+
+	if (-1 == ioctl(dsp, AUDIO_SET_CHANNELS, 1)) {
+		fprintf(stderr,"paradise.sndsrv: parameter setting failed");
+		return;
+	}
+
+	if (-1 == ioctl(dsp, AUDIO_SET_SAMPLE_RATE, 16000)) {
+		fprintf(stderr,"paradise.sndsrv: parameter setting failed");
+		return -1;
+	}
+
+	if (-1 == ioctl(dsp, AUDIO_SET_OUTPUT, AUDIO_OUT_INTERNAL)) {
+		fprintf(stderr,"paradise.sndsrv: parameter setting failed");
+		return -1;
+	}
+	
+  
+  return dsp;
+}
+
+/*
+   This just keeps the pipe from breaking...
+   Eventually I'll look at the paradise signal handlers and
+   just trap this.
+*/
+int do_nothing(void)
+{
+    while(1)  sleep (5);
+}
+
+int read_sound(int k)
+{
+  int i,fd,size;
+	unsigned char * b;
+	short * d;
+	
+  /* fprintf(stderr,"loading sound %d, %s\n",k,FILENAME[k]); */
+
+  fd = open(FILENAME[k], O_RDONLY);
+  if(fd<=0) 
+  {
+    fprintf (stderr, "paradise.sndsrv: The sound %s could not be opened\n", FILENAME[k]);
+    sound_size[k]=-1;
+    return(0);
+  };
+  size=lseek(fd,0,SEEK_END);
+  sound_size[k]=((size)/fragsize)+1;   /*size in fragments*/
+  sound_buffer[k]=malloc(sound_size[k]*sizeof(short)*fragsize);
+  if(sound_buffer[k]==NULL)
+  {
+    fprintf(stderr,"paradise.sndsrv: couldn't malloc memory for sound\n");
+    sound_size[k]=-1;
+    close(fd);
+    return(0);
+  };
+  lseek(fd,0,SEEK_SET);
+  read(fd,sound_buffer[k],size);
+  
+  b = ((unsigned char *)sound_buffer[k])+sound_size[k]*fragsize;
+  d = sound_buffer[k] + sound_size[k]*fragsize;
+	/* fprintf(stderr,"size = %d\n",sound_size[k]*fragsize); */
+  for (i=0; i < sound_size[k]*fragsize; i++) {
+    *(--d) = (((short)*(--b))-128) << 8;
+  }
+  
+  close(fd);
+  bzero(((char *)sound_buffer[k])+size, sound_size[k]*sizeof(short)*fragsize-size);
+  
+  /* fprintf(stderr,"buba! sound has been loaded, %d bytes\n",size);*/ /*DEBUG*/
+  return(1);
+}
+
+
+void do_everything (int dsp)
+{
+  char k;
+  int i, j ;
+  int terminate = -1;             /* Which Sound to Terminate                              */
+  int playing[16];                /* Sound numbers that we are playing                     */
+  int position[16];		  /* Current position in each sound file */
+  int playnum = 0;                /* Number of sounds currently being played               */
+  short final[fragsize];       /* Final Mixing Buffer                                   */
+  short *sample;
+
+  for(;;)  {
+    terminate = -1;
+    /* Try to open a new sound if we get an integer on the 'in' pipe */
+    i=read(STDIN_FILENO,&k,sizeof(k));
+    if(i==0)  {   /* EOF on pipe means parent has closed its end */
+        /*fprintf(stderr,"paradise.sndsrv: shutting down\n"); */
+        kill(getpid(), SIGTERM);
+    };
+    if(i!=-1)  {  /* there was something in the pipe */
+        /*fprintf(stderr,"Just read a %d from pipe\n",(int)k);*/ /*DEBUG*/
+        /* Negative means terminate the FIRST sound in the buffer */
+        if(k<0)  {
+            fprintf(stderr,"terminating sound\n"); /*DEBUG*/
+            terminate = 0;
+        } else {
+            if(sound_size[(int)k]==0) read_sound(k);
+            if(sound_size[(int)k]>0 && playnum<16)  {
+	        position[playnum]=0;
+                playing[playnum++]=k;
+               /* fprintf(stderr,"sound %d added to play queue\n",playnum-1);*/ /*DEBUG*/
+            };
+        };
+    };
+
+    /* terminate a sound if necessary */
+    for(i=0;i<playnum;i++)
+    {
+      if((position[i]==sound_size[playing[i]]) || (terminate==i))
+      {
+     /*   fprintf(stderr,"finished playing sound %d\n",i); */ /*DEBUG*/
+	/* fprintf(stderr,"is was at position %d\n",position[i]); */ /*DEBUG*/
+        bcopy(playing+i+1,playing+i,(playnum-i)*sizeof(int));
+        bcopy(position+i+1,position+i,(playnum-i)*sizeof(int));
+        playnum--;i--;
+      };
+    };
+
+    memset(final, 0, sizeof(final));
+    if(playnum)  {
+        /* Mix each sound into the final buffer */
+        for(i=0;i<playnum;i++)  {
+        		short * f = final;
+            sample=sound_buffer[playing[i]]+position[i]*fragsize;
+            for(j=0;j<fragsize;j++)  {
+            	 long s = *f;
+            	 s += *sample++;
+            	 if (s < -32768) {
+            	 	s = -32768;
+            	 }
+            	 if (s > 32767) {
+            	 	s = 32767;
+            	 }
+                *f++ = (short)s;
+            };
+            position[i]++;
+        }
+    } else {
+        /* 
+           We have no sounds to play
+           Just fill the buffer with silence and maybe play it 
+        */
+    };
+    write (dsp, final, fragsize*sizeof(short));
+    /*
+       The sound server is in a tight loop, EXCEPT for this
+       write which blocks.  Any optimizations in the above
+       code would really be helpful.  Right now the server
+       takes up to 7% cpu on a 486DX/50.
+    */
+  }
+}
+
+
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+  int dsp;
+
+  fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
+  init (argc, argv);
+  dsp = setup_dsp (argv[2]);
+
+  if (dsp < 1) do_nothing();
+
+  do_everything (dsp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paradise.sndsrv.linux.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,295 @@
+/*
+ * paradise.sndsrv.c - USS-Lite Compatible Sound - July 1996
+ *                     This server is Linux Specific.
+ * Sujal M. Patel (smpatel@umiacs.umd.edu)
+ *
+ *
+ * Copyright (c) 1994-1996, Sujal M. Patel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      $Id: paradise.sndsrv.linux.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/soundcard.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <string.h>
+
+
+
+char *FILENAME[] = {
+                     "/explode.raw",
+                     "/cloak.raw",
+                     "/firetorp.raw",
+                     "/phaser.raw",
+                     "/plasma.raw",
+                     "/shield.raw",
+                     "/torphit.raw",
+                     "/explode_big.raw",
+                     "/paradise.raw",
+                     "/thermal.raw",
+                     "/redalert.raw"
+                   };
+
+#define NUM_SOUNDS	(sizeof(FILENAME)/sizeof(char*))
+
+signed char *sound_buffer[NUM_SOUNDS];
+int sound_size[NUM_SOUNDS];
+int fragsize;
+
+
+/* Terminate: Signal Handler */
+void quit ()
+{
+  exit (0);
+}
+
+
+
+void init (int argc, char **argv)
+{
+  int i;
+  char s[1024];
+
+  if (argc != 3)
+  {
+    printf ("This program is only executed by netrek.paradise\n");
+    exit (1);
+  }
+
+  for (i=0; i < NUM_SOUNDS; i++)
+  {
+    s[0] = 0;
+    strcat (s, argv[1]);
+    if (s[(int)strlen(s) - 1] == '/') FILENAME[i]++;
+    strcat (s, FILENAME[i]);
+    FILENAME[i] = malloc ((int)strlen (s));
+    strcpy (FILENAME[i],s);
+    sound_buffer[i]=NULL;
+    sound_size[i]=0;
+  }
+
+  signal(SIGTERM, quit);   /* Setup Terminate Signal Handler */
+}
+
+
+/*
+   Setup DSP: 
+              Sets fragment size on VoxWare
+              Sets speed to 8000hz
+              Should set mono mode
+              Error checking                
+*/
+int setup_dsp (char *dspdev,int *is_pcsp)
+{
+  int dsp, frag, value;
+  int mixer;
+
+  dsp = open(dspdev, O_RDWR);
+  if (dsp < 1)
+  {
+    fprintf (stderr, "paradise.sndsrv: Couldn't open device %s\n",dspdev);
+    return -1;
+  }
+ 
+  *is_pcsp = 0;
+  fragsize = 0;
+
+  frag = 0x00020009;   /* try 512 bytes, for 1/16 second frag size */
+  ioctl(dsp, SNDCTL_DSP_SETFRAGMENT, &frag);
+  value = 8010;
+  if (ioctl(dsp, SNDCTL_DSP_SPEED, &value))
+  {
+      fprintf (stderr, "paradise.sndsrv: Couldn't set DSP rate!\n");
+  };
+  value = 0;
+  ioctl(dsp, SNDCTL_DSP_STEREO, &value);
+  ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &fragsize);
+  /*fprintf(stderr,"paradise.sndsrv: fragment set to %d\n",fragsize);*/
+
+  if (!fragsize)
+  { 
+    /* Don't Assume just because you can't set the fragment, use proper IOCTL */
+    fprintf (stderr, "paradise.sndsrv: Couldn't set Fragment Size.\nAssuming PC Speaker!\n");
+    fragsize = 128;
+    *is_pcsp = 1;
+  } else {
+      mixer = open("/dev/mixer",O_RDWR | O_NONBLOCK);
+      if(mixer==-1)  {
+          fprintf(stderr,"paradise.sndsrv: Couldn't open mixer %s\n","/dev/mixer");
+          return(-1);
+      };
+      value=0x6464;
+      ioctl(mixer,SOUND_MIXER_WRITE_PCM,&value);
+      ioctl(mixer,SOUND_MIXER_WRITE_VOLUME,&value);  /*what does this do?*/
+      close(mixer);
+  }
+  
+  return dsp;
+}
+
+/*
+   This just keeps the pipe from breaking...
+   Eventually I'll look at the paradise signal handlers and
+   just trap this.
+*/
+int do_nothing(void)
+{
+    while(1)  sleep (5);
+}
+
+int read_sound(int k)
+{
+  int i,fd,size;
+
+  /*fprintf(stderr,"loading sound %d, %s\n",k,FILENAME[k]);*/
+
+  fd = open(FILENAME[k], O_RDONLY);
+  if(fd<=0) 
+  {
+    fprintf (stderr, "paradise.sndsrv: The sound %s could not be opened\n", FILENAME[k]);
+    sound_size[k]=-1;
+    return(0);
+  };
+  size=lseek(fd,0,SEEK_END);
+  sound_size[k]=(size/fragsize)+1;   /*size in fragments*/
+  sound_buffer[k]=malloc(sound_size[k]*fragsize);
+  if(sound_buffer[k]==NULL)
+  {
+    fprintf(stderr,"paradise.sndsrv: couldn't malloc memory for sound\n");
+    sound_size[k]=-1;
+    close(fd);
+    return(0);
+  };
+  lseek(fd,0,SEEK_SET);
+  read(fd,sound_buffer[k],size);
+  close(fd);
+  for(i=0;i<size;i++)  sound_buffer[k][i]^=0x80;
+  memset(sound_buffer[k]+size,0,sound_size[k]*fragsize-size);
+  
+  /*fprintf(stderr,"sound has been loaded, %d bytes\n",size);*/ /*DEBUG*/
+  return(1);
+}
+
+
+void do_everything (int dsp, int is_pcsp)
+{
+  char k;
+  int i, j ;
+  int terminate = -1;             /* Which Sound to Terminate                              */
+  int playing[16];                /* Sound numbers that we are playing                     */
+  int position[16];		  /* Current position in each sound file */
+  int playnum = 0;                /* Number of sounds currently being played               */
+  unsigned char final[512];       /* Final Mixing Buffer                                   */
+  int premix[512];
+  char *sample;
+
+  for(;;)  {
+    terminate = -1;
+    /* Try to open a new sound if we get an integer on the 'in' pipe */
+    i=read(STDIN_FILENO,&k,sizeof(k));
+    if(i==0)  {   /* EOF on pipe means parent has closed its end */
+        /*fprintf(stderr,"paradise.sndsrv: shutting down\n"); */
+        kill(getpid(), SIGTERM);
+    };
+    if(i!=-1)  {  /* there was something in the pipe */
+        /*fprintf(stderr,"Just read a %d from pipe\n",(int)k);*/ /*DEBUG*/
+        /* Negative means terminate the FIRST sound in the buffer */
+        if(k<0)  {
+            /*fprintf(stderr,"terminating sound\n");*/ /*DEBUG*/
+            terminate = 0;
+        } else {
+            if(sound_size[k]==0) read_sound(k);
+            if(sound_size[k]>0 && playnum<16)  {
+	        position[playnum]=0;
+                playing[playnum++]=k;
+                /*fprintf(stderr,"sound %d added to play queue\n",playnum-1);*/ /*DEBUG*/
+            };
+        };
+    };
+
+    /* terminate a sound if necessary */
+    for(i=0;i<playnum;i++)
+    {
+      if((position[i]==sound_size[playing[i]]) || (terminate==i))
+      {
+        /*fprintf(stderr,"finished playing sound %d\n",i);*/ /*DEBUG*/
+	/*fprintf(stderr,"is was at position %d\n",position[i]);*/ /*DEBUG*/
+        memmove(playing+i,playing+i+1,(playnum-i)*sizeof(int));
+        memmove(position+i,position+i+1,(playnum-i)*sizeof(int));
+        playnum--;i--;
+      };
+    };
+
+    if(playnum)  {
+        /* Mix each sound into the final buffer */
+        memset(premix,0,sizeof(premix));
+        for(i=0;i<playnum;i++)  {
+            sample=sound_buffer[playing[i]]+position[i]*fragsize;
+            for(j=0;j<fragsize;j++)  {
+                premix[j]+=*(sample+j);
+            };
+            position[i]++;
+        };
+        for(i=0;i<fragsize;i++)
+            final[i]=(premix[i]>255)?255:(premix[i]<-256?0:(premix[i]>>1)+128);
+    } else {
+        /* 
+           We have no sounds to play
+           Just fill the buffer with silence and maybe play it 
+        */
+        memset(final,128,sizeof(final));
+    };
+    write (dsp, final, fragsize);
+    /*
+       The sound server is in a tight loop, EXCEPT for this
+       write which blocks.  Any optimizations in the above
+       code would really be helpful.  Right now the server
+       takes up to 7% cpu on a 486DX/50.
+    */
+  }
+}
+
+
+
+void main (argc, argv)
+int argc;
+char **argv;
+{
+  int dsp, is_pcsp, ppid;
+  char filename[512];
+
+  fcntl(STDIN_FILENO,F_SETFL,O_NONBLOCK);
+  init (argc, argv);
+  dsp = setup_dsp (argv[2],&is_pcsp);
+
+  if (dsp < 1) do_nothing();
+
+  do_everything (dsp, is_pcsp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paradise.sndsrv.sun.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,283 @@
+/*
+ * paradise.sndsrv.c - VoxWare(tm) Compatible Sound - July 1996
+ *                   This server is SunOS Specific.
+ * Sujal M. Patel (smpatel@umiacs.umd.edu)
+ *
+ * Copyright (c) 1994-1996, Sujal M. Patel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      $Id: paradise.sndsrv.sun.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <string.h>
+
+char *FILENAME[] = {
+                     "/explode.raw",
+                     "/cloak.raw",
+                     "/firetorp.raw",
+                     "/phaser.raw",
+                     "/plasma.raw",
+                     "/shield.raw",
+                     "/torphit.raw",
+                     "/explode_big.raw",
+                     "/paradise.raw",
+                     "/thermal.raw",
+                     "/redalert.raw"
+                   };
+
+#define NUM_SOUNDS      (sizeof(FILENAME)/sizeof(char*))
+
+signed char *sound_buffer[NUM_SOUNDS];
+int sound_size[NUM_SOUNDS];
+int fragsize;
+
+
+/* Terminate: Signal Handler */
+void
+quit ()
+{
+  exit (0);
+}
+
+
+
+void
+init (int argc, char **argv)
+{
+  int             i;
+  char            s[1024];
+
+  if (argc != 3)
+    {
+      printf ("This program is only executed by Paradise\n");
+      exit (1);
+    }
+
+  for (i = 0; i < NUM_SOUNDS; i++)
+    {
+      s[0] = 0;
+      strcat (s, argv[1]);
+      if (s[(int) strlen (s) - 1] == '/')
+	FILENAME[i]++;
+      strcat (s, FILENAME[i]);
+      FILENAME[i] = malloc ((int) strlen (s) + 1);
+      strcpy (FILENAME[i], s);
+      sound_buffer[i] = NULL;
+      sound_size[i] = 0;
+    }
+
+  signal (SIGTERM, quit);	/* Setup Terminate Signal Handler */
+}
+
+
+/*
+   Setup DSP: Opens /dev/audio
+   Sets fragment size to 512
+   Error checking                
+ */
+int
+setup_dsp (char *dspdev)
+{
+  int             dsp, frag, value;
+  int             mixer;
+
+  dsp = open (dspdev, O_RDWR);
+  if (dsp < 1)
+    {
+      fprintf (stderr, "paradise.sndsrv: Couldn't open device %s\n", dspdev);
+      return -1;
+    }
+
+  fragsize = 512;
+
+  return dsp;
+}
+
+/*
+   This just keeps the pipe from breaking...
+   Eventually I'll look at the paradise signal handlers and
+   just trap this.
+ */
+int
+do_nothing (void)
+{
+  while (1)
+    sleep (5);
+}
+
+int
+read_sound (int k)
+{
+  int             i, fd, size;
+
+  /*fprintf(stderr,"loading sound %d, %s\n",k,FILENAME[k]); */
+
+  fd = open (FILENAME[k], O_RDONLY);
+  if (fd <= 0)
+    {
+      fprintf (stderr, "paradise.sndsrv: The sound %s could not be opened\n", FILENAME[k]);
+      sound_size[k] = -1;
+      return (0);
+    };
+  size = lseek (fd, 0, SEEK_END);
+  sound_size[k] = (size / fragsize) + 1;	/*size in fragments */
+  sound_buffer[k] = malloc (sound_size[k] * fragsize);
+  if (sound_buffer[k] == NULL)
+    {
+      fprintf (stderr, "paradise.sndsrv: couldn't malloc memory for sound\n");
+      sound_size[k] = -1;
+      close (fd);
+      return (0);
+    };
+  lseek (fd, 0, SEEK_SET);
+  read (fd, sound_buffer[k], size);
+  close (fd);
+  for (i = 0; i < size; i++)
+    sound_buffer[k][i] ^= 0x80;
+  bzero (sound_buffer[k] + size, sound_size[k] * fragsize - size);
+
+  /*fprintf(stderr,"sound has been loaded, %d bytes\n",size); *//*DEBUG */
+  return (1);
+}
+
+
+void
+do_everything (int dsp)
+{
+  char            k;
+  int             i, j;
+  int             terminate = -1;	/* Which Sound to Terminate                              */
+  int             playing[16];	/* Sound numbers that we are playing                     */
+  int             position[16];	/* Current position in each sound file */
+  int             playnum = 0;	/* Number of sounds currently being played               */
+  unsigned char   final[512];	/* Final Mixing Buffer                                   */
+  int             premix[512];
+  char           *sample;
+
+  for (;;)
+    {
+      terminate = -1;
+      /* Try to open a new sound if we get an integer on the 'in' pipe */
+      i = read (STDIN_FILENO, &k, sizeof (k));
+      if (i == 0)
+	{			/* EOF on pipe means parent has closed its end */
+	  /*fprintf(stderr,"paradise.sndsrv: shutting down\n"); */
+	  kill (getpid (), SIGTERM);
+	};
+      if (i != -1)
+	{			/* there was something in the pipe */
+	  /*fprintf(stderr,"Just read a %d from pipe\n",(int)k); *//*DEBUG */
+	  /* Negative means terminate the FIRST sound in the buffer */
+	  if (k < 0)
+	    {
+	      /*fprintf(stderr,"terminating sound\n"); *//*DEBUG */
+	      terminate = 0;
+	    }
+	  else
+	    {
+	      if (sound_size[(int) k] == 0)
+		read_sound (k);
+	      if (sound_size[(int) k] > 0 && playnum < 16)
+		{
+		  position[playnum] = 0;
+		  playing[playnum++] = k;
+		  /*fprintf(stderr,"sound %d added to play queue\n",playnum-1); *//*DEBUG */
+		};
+	    };
+	};
+
+      /* terminate a sound if necessary */
+      for (i = 0; i < playnum; i++)
+	{
+	  if ((position[i] == sound_size[playing[i]]) || (terminate == i))
+	    {
+	      /*fprintf(stderr,"finished playing sound %d\n",i); *//*DEBUG */
+	      /*fprintf(stderr,"is was at position %d\n",position[i]); *//*DEBUG */
+	      bcopy (playing + i + 1, playing + i, (playnum - i) * sizeof (int));
+	      bcopy (position + i + 1, position + i, (playnum - i) * sizeof (int));
+	      playnum--;
+	      i--;
+	    };
+	};
+
+      if (playnum)
+	{
+	  /* Mix each sound into the final buffer */
+	  bzero (premix, sizeof (premix));
+	  for (i = 0; i < playnum; i++)
+	    {
+	      sample = sound_buffer[playing[i]] + position[i] * fragsize;
+	      for (j = 0; j < fragsize; j++)
+		{
+		  premix[j] += *(sample + j);
+		};
+	      position[i]++;
+	    };
+	  for (i = 0; i < fragsize; i++)
+	    final[i] = (premix[i] > 255) ? 255 : (premix[i] < -256 ? 0 : (premix[i] >> 1) + 128);
+	}
+      else
+	{
+	  /* 
+	     We have no sounds to play
+	     Just fill the buffer with silence and maybe play it 
+	   */
+	  memset (final, 128, sizeof (final));
+	};
+      write (dsp, final, fragsize);
+      /*
+         The sound server is in a tight loop, EXCEPT for this
+         write which blocks.  Any optimizations in the above
+         code would really be helpful.  Right now the server
+         takes up to 7% cpu on a 486DX/50.
+       */
+    }
+}
+
+
+
+void
+main (argc, argv)
+     int             argc;
+     char          **argv;
+{
+  int             dsp;
+
+  fcntl (STDIN_FILENO, F_SETFL, O_NONBLOCK);
+  init (argc, argv);
+  dsp = setup_dsp (argv[2]);
+
+  if (dsp < 1)
+    do_nothing ();
+
+  do_everything (dsp);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/parsemeta.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,487 @@
+/* $Id: parsemeta.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * meta.c     - Nick Trown    May 1993
+ */
+
+#ifdef METASERVER
+
+#include "copyright.h"
+#include <fcntl.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#ifdef RS6K
+#include <sys/select.h>
+#include <fcntl.h>
+#endif
+
+#ifndef DNET
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include <netdb.h>
+#include <errno.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+#include <string.h>
+#if !defined(SYSV) && !defined(apollo) && !defined(SVR4)
+#include <strings.h>
+#endif
+
+#define BUF	4096
+
+static void metarefresh P((int i));
+static void metadone P((void));
+
+int     pid = 0;
+int     num_servers = 0;
+int	max_servers = 20;
+struct  servers *serverlist = NULL;
+char    *keystrings[] = {"OPEN:", "Wait queue:", "Nobody"};
+
+/*
+   I was planning to use this function a lot but it doesn't look like
+   I need it more than once. It finds the next number after position
+   'start'.
+ */
+
+int
+getnumber(string, start)
+    char   *string;
+    int     start;
+{
+#if 0  /* this is stupid [BDyess] */
+    char    temp[LINE];
+    int     c;
+    int     tc = 0;
+
+    for (c = start; c <= (int) strlen(string); c++) {
+	if ((string[c] >= '0') && (string[c] <= '9')) {
+	    temp[tc++] = string[c];
+	} else if (tc > 0) {
+	    temp[tc] = '\0';
+	    return (atoi(temp));
+	}
+    }
+    return 0;
+#endif /*0*/
+
+  string += start;
+  while(!isdigit(*string) && *string) string++;
+  return atoi(string);
+}
+
+
+/*
+   The connection to the metaserver is by Andy McFadden.
+   This calls the metaserver and parses the output into something
+   useful
+ */
+
+static int
+open_port(host, port, verbose)
+    char   *host;
+    int     port;
+    int     verbose;
+{
+#ifdef DNET
+    return DNetOpenMeta(host, port);
+#else
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    int     s;
+
+
+    /* Connect to the metaserver */
+    /* get numeric form */
+    if ((addr.sin_addr.s_addr = inet_addr(host)) == -1) {
+	if ((hp = gethostbyname(host)) == NULL) {
+	    if (verbose)
+		fprintf(stderr, "unknown host '%s'\n", host);
+	    return (-1);
+	} else {
+	    addr.sin_addr.s_addr = *(long *) hp->h_addr;
+	}
+    }
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(port);
+    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+	if (verbose)
+	    perror("socket");
+	return (-1);
+    }
+    if (connect(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
+	if (verbose)
+	    perror("connect");
+	close(s);
+	return (-1);
+    }
+    return (s);
+#endif				/* DNET */
+}
+
+static int
+readmeta(s)
+    int     s;
+{
+    int     cc, lc = 0, c, tc;
+
+    static char buf[BUF + 1];
+    static char *numstr;
+    static char line[LINE + 1];
+
+#ifndef DEBUG
+    while (1) {
+#ifdef DNET			/* annoying... */
+	if ((cc = sock_read(s, buf, BUF)) < 0) {
+#else	/* } */			/* to balance the {'s for emacs */
+	if ((cc = sock_read(s, buf, BUF)) <= 0) {
+	    if (cc < 0)
+		perror("read");
+#endif				/* DNET */
+	    sock_close(s);
+	    return (cc);
+	}
+#else
+    /*
+       cat the output of the metaserver port 3521 to a file called "output"
+       for testing purposes
+    */
+    s = open("output", O_RDONLY);
+
+    if ((cc = read(s, buf, BUF)) <= 0) {
+	if (cc < 0)
+	    perror("read");
+	close(s);
+	return (cc);
+    }
+    fwrite(buf, cc, 1, stdout);
+    close(s);
+#endif
+
+    for (c = 0; c < cc; c++) {
+	if (buf[c] != '\n')	/* Break up the buffer into lines */
+	    line[lc++] = buf[c];
+	else {
+	    line[lc] = 0;	/* random problems without this.  No terminator
+	                           means invalid strlen().  [BDyess] */
+	    if (sscanf(line, "-h %s -p %d %d",	/* parse line */
+		       serverlist[num_servers].address,
+		       &serverlist[num_servers].port,
+		       &serverlist[num_servers].time) == 3) {
+		/* get what type of server it is */
+		serverlist[num_servers].typeflag = line[strlen(line) - 1];
+		if (serverlist[num_servers].typeflag == 'P') {
+		    serverlist[num_servers].status = 2;
+		    serverlist[num_servers].players = 0;
+		} else
+		    serverlist[num_servers].status = -1;
+
+		/*
+		   I don't have it checking the servers with nobody playing
+		   because the menu window would then be too large to fit on
+		   a 1024 x 768 window. :(  - NBT
+		*/
+
+		for (tc = 0; tc < KEY; tc++)
+		    if ((numstr = strstr(line, keystrings[tc]))) {
+			serverlist[num_servers].status = tc;
+			serverlist[num_servers].players = getnumber(numstr, 0);
+		    }
+		if (strrchr(line, 'R'))
+		    serverlist[num_servers].RSA_client = 1;
+		else
+		    serverlist[num_servers].RSA_client = 0;
+
+		if (serverlist[num_servers].status >= 0 &&
+		    (serverlist[num_servers].status != 2 ||
+		     serverlist[num_servers].typeflag == 'P')) {
+
+#ifdef DEBUG
+		    printf("HOST:%-30s PORT:%-6d %12s %-5d %d\n",
+			   serverlist[num_servers].address,
+			   serverlist[num_servers].port,
+			   keystrings[serverlist[num_servers].status],
+			   serverlist[num_servers].players,
+			   serverlist[num_servers].RSA_client);
+#endif
+
+		    serverlist[num_servers].hilited = 0;
+		    num_servers++;	/* It's valid */
+		    if(num_servers == max_servers) {
+		      /* double the size every time it's exceeded [BDyess] */
+		      serverlist = (struct servers*) realloc(serverlist, 
+		                   sizeof(struct servers) * (max_servers *= 2));
+		    }
+		}
+	    }
+	    lc = 0;
+	    /*line[0] = '\0';  silly [BDyess] */
+	}
+    }
+}
+ /* close(s); */
+}
+
+
+void
+parsemeta()
+{
+    int     s;
+
+    num_servers = 0;
+
+    /* serverlist is now dynamic and grows.  This fixes the random coredump
+       and data corruption problems the previous static method caused. 
+       [BDyess] */
+    if(serverlist) free(serverlist);
+    serverlist = (struct servers*) malloc(sizeof(struct servers) * max_servers);
+
+    if (serverName) {
+	strcpy(serverlist[num_servers].address, serverName);
+	serverlist[num_servers].port = xtrekPort;
+
+#ifdef RSA
+	serverlist[num_servers].RSA_client = RSA_Client;
+#endif
+
+	serverlist[num_servers].status = KEY + 1;
+	serverlist[num_servers].players = 0;
+	num_servers++;
+    }
+    printf("connecting to metaserver...");
+    fflush(stdout);
+
+#ifdef DEBUG
+    readmeta(0);
+#else
+    if ((s = open_port(metaserverAddress, METAPORT, 1)) > 0) {
+	readmeta(s);
+    } else {
+	printf("failed (%s , %d)\n", metaserverAddress, METAPORT);
+    }
+#endif
+    printf("\n");
+}
+
+
+/* Show the meta server menu window */
+
+void
+metawindow()
+{
+    register int i;
+    static int old_num_servers = -1;
+
+    if (old_num_servers != num_servers) {
+	if (metaWin)
+	    W_DestroyWindow(metaWin);
+	metaWin = W_MakeMenu("MetaServer List", WINSIDE + 10, -BORDER + 10, 69,
+			     num_servers + 2, NULL, 2);
+    }
+    for (i = 0; i < num_servers; i++)
+	metarefresh(i);
+
+    /* add refresh option [BDyess] */
+    W_WriteText(metaWin, 0, num_servers, textColor, "Refresh", 7, 0);
+
+    /* Add quit option */
+    W_WriteText(metaWin, 0, num_servers + 1, textColor, "Quit", 4, W_RegularFont);
+
+    /* Map window */
+    if (!W_IsMapped(metaWin))
+	W_MapWindow(metaWin);
+}
+
+/*
+ * Refresh item i
+ */
+static void
+metarefresh(i)
+    int     i;
+{
+    char    buf[BUFSIZ];
+
+    if (serverlist[i].status < KEY) {
+	sprintf(buf, "%-40s %12s ",
+		serverlist[i].address,
+		keystrings[serverlist[i].status]);
+	if (serverlist[i].status != 2)
+	    sprintf(buf + strlen(buf), "%-5d ", serverlist[i].players);
+	else
+	    strcat(buf, "      ");
+	switch (serverlist[i].typeflag) {
+	case 'P':
+	    strcat(buf, "Paradise");
+	    break;
+	case 'B':
+	    strcat(buf, "Bronco");
+	    break;
+	case 'C':
+	    strcat(buf, "Chaos");
+	    break;
+	case 'I':
+	    strcat(buf, "INL");
+	    break;
+	case 'S':
+	    strcat(buf, "Sturgeon");
+	    break;
+	case 'H':
+	    strcat(buf, "Hockey");
+	    break;
+	case 'F':
+	    strcat(buf, "Dogfight");
+	    break;
+	}
+    } else if (serverlist[i].status == KEY) {	/* For when I have checking
+						   code */
+	sprintf(buf, "%-40s CANNOT CONNECT", serverlist[i].address);
+    } else if (serverlist[i].status == KEY + 1) {
+	sprintf(buf, "%-40s   DEFAULT SERVER", serverlist[i].address);
+    }
+    W_WriteText(metaWin, 0, i,
+		serverlist[i].hilited ? W_Yellow : textColor,
+		buf, (int)strlen(buf),
+		serverlist[i].hilited ? W_HighlightFont : W_RegularFont);
+}
+
+
+/*
+   Check selection to see if was valid. If it was then we have a winner!
+ */
+static void
+metaaction(data)
+    W_Event *data;
+{
+    int     s;
+    static time_t lastRefresh = 0;
+    static time_t t;
+
+    if ((data->y >= 0) && (data->y < num_servers)) {
+	xtrekPort = serverlist[data->y].port;
+	serverName = serverlist[data->y].address;
+
+#ifdef RSA
+	RSA_Client = serverlist[data->y].RSA_client;
+#endif
+	serverlist[data->y].hilited = 1;
+	metarefresh(data->y);
+
+	if ((s = open_port(serverName, xtrekPort, 0)) <= 0) {
+	    serverlist[data->y].status = KEY;
+	    serverlist[data->y].hilited = 0;
+	    metarefresh(data->y);
+	} else {
+	    sock_close(s);
+#ifndef AMIGA
+	    /* allow spawning off multiple clients [BDyess] */
+	    if (metaFork) {
+		/* just blink yellow [BDyess] */
+		serverlist[data->y].hilited = 0;
+		metarefresh(data->y);
+		pid = fork();
+	    } else
+#else
+	    /*
+	       OUCH. fork() sucks ;-) Using "run" is equivalent to appending
+	       a & to a command in Unix.  (my shell allows &, but it's not
+	       built in to AmigaDOS.)  This is a stupid kludge.  I
+	       should write a silly shell or rexx script to do all the
+	       metaserver stuff instead, and not compile PARSEMETA at all.
+	    */
+	    if (metaFork) {
+		extern char *command_line; /* main.c, argv */
+		extern int global_argc;
+		int ac;
+		char buf2[256];
+		char    buf[80];
+
+		sprintf(buf,"run %s ",command_line[0]);
+		for(ac=1;ac<global_argc;ac++) {
+		    if(strcmp(command_line[ac], "-m") == 0)
+			ac++;
+		    else {
+			strcat(buf,command_line[ac]);
+			strcat(buf," ");
+		    }
+		}
+		printf(buf2,"-h %s -p %d", command_line[0], serverName, xtrekPort);
+		strcat(buf, buf2);
+		Execute(buf, Input(), Output());
+	    } else
+#endif				/* AMIGA */
+	    {
+		pid = 1;
+		metadone();
+	    }
+	}
+    } else if (data->y == num_servers) {	/* refresh [BDyess] */
+	/*
+	   they can bang on refresh all day, but it won't refresh any faster
+	   than once/minute. [BDyess]
+	*/
+	if ((t = time(NULL)) < lastRefresh + 60)
+	    return;
+	lastRefresh = t;
+	parsemeta();		/* connect and parse info */
+	metawindow();		/* refresh */
+    } else {			/* quit */
+	metadone();
+	exit(0);
+    }
+}
+
+
+/*
+   Unmap the metaWindow
+ */
+
+static void
+metadone()
+{
+    /* Unmap window */
+    W_UnmapWindow(metaWin);
+}
+
+
+/*
+   My own little input() function. I needed this so I don't have
+   to use all the bull in the main input(). Plus to use it I'd have
+   to call mapAll() first and the client would read in the default
+   server and then call it up before I can select a server.
+ */
+
+void
+metainput()
+{
+    W_Event data;
+
+    while (W_IsMapped(metaWin) && pid == 0) {
+	W_GetEvent(&data);
+	switch ((int) data.type) {
+	case W_EV_KEY:
+	    if (data.Window == metaWin)
+		metaaction(&data);
+	    break;
+	case W_EV_BUTTON:
+	    if (data.Window == metaWin)
+		metaaction(&data);
+	    break;
+	case W_EV_EXPOSE:
+	    break;
+	default:
+	    break;
+	}
+    }
+}
+#endif				/* METASERVER */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ping.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,147 @@
+/* $Id: ping.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * ping.c
+ *
+ */
+
+#include "copyright2.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <math.h>
+#include <errno.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+
+/* These are used only in pingstats.c */
+
+int     ping_iloss_sc = 0;	/* inc % loss 0--100, server to client */
+int     ping_iloss_cs = 0;	/* inc % loss 0--100, client to server */
+int     ping_tloss_sc = 0;	/* total % loss 0--100, server to client */
+int     ping_tloss_cs = 0;	/* total % loss 0--100, client to server */
+int     ping_lag = 0;		/* delay in ms of last ping */
+int     ping_av = 0;		/* rt time */
+int     ping_sd = 0;		/* std deviation */
+
+static int sum, n;
+static int M, var;
+static double s2;
+
+void sendServerPingResponse P((int number));
+void calc_lag P((void));
+
+void
+handlePing(packet)		/* SP_PING */
+    struct ping_spacket *packet;
+{
+    ping = 1;			/* we got a ping */
+
+/*
+printf("ping received at %d (lag: %d)\n", msetime(), (int)packet->lag);
+*/
+    sendServerPingResponse((int) packet->number);
+    ping_lag = ntohs(packet->lag);
+    ping_iloss_sc = (int) packet->iloss_sc;
+    ping_iloss_cs = (int) packet->iloss_cs;
+    ping_tloss_sc = (int) packet->tloss_sc;
+    ping_tloss_cs = (int) packet->tloss_cs;
+
+    calc_lag();
+
+    if (W_IsMapped(pStats))	/* pstat window */
+	updatePStats();
+}
+
+void
+startPing()
+{
+    static
+    struct ping_cpacket packet;
+    extern int serverDead;
+
+    packet.type = CP_PING_RESPONSE;
+    packet.pingme = 1;
+
+    if (gwrite(sock, (char *) &packet, sizeof(struct ping_cpacket)) !=
+	sizeof(struct ping_cpacket)) {
+	printf("gwrite failed.\n");
+	serverDead = 1;
+    }
+}
+
+void
+stopPing()
+{
+    static
+    struct ping_cpacket packet;
+    extern int serverDead;
+
+    ping = 0;
+    packet.type = CP_PING_RESPONSE;
+    packet.pingme = 0;
+
+    if (gwrite(sock, (char *) &packet, sizeof(struct ping_cpacket)) !=
+	sizeof(struct ping_cpacket)) {
+	printf("gwrite failed.\n");
+	serverDead = 1;
+    }
+}
+
+void
+sendServerPingResponse(number)	/* CP_PING_RESPONSE */
+    int     number;
+{
+    struct ping_cpacket packet;
+    int     s;
+    extern int serverDead;
+
+    if (udpSock >= 0) {
+	s = udpSock;
+	packets_sent++;
+    } else
+	s = sock;
+
+    packet.type = CP_PING_RESPONSE;
+    packet.pingme = (char) ping;
+    packet.number = (unsigned char) number;
+    /* count this one */
+    packet.cp_sent = htonl(packets_sent);
+    packet.cp_recv = htonl(packets_received);
+
+/*
+printf("ping response sent at %d\n", msetime());
+*/
+
+    if (gwrite(s, (char *) &packet, sizeof(struct ping_cpacket)) !=
+	sizeof(struct ping_cpacket)) {
+	printf("gwrite failed.\n");
+	serverDead = 1;
+    }
+}
+
+void
+calc_lag()
+{
+    /* probably ghostbusted */
+    /* without this things can get really bad */
+    if (ping_lag > 2000 || ping_lag == 0)
+	return;
+
+    n++;
+    sum += ping_lag;
+    s2 += (ping_lag * ping_lag);
+    if (n == 1)
+	return;
+
+    M = sum / n;
+    var = (s2 - M * sum) / (n - 1);
+
+    ping_av = M;
+    ping_sd = (int) sqrt((double) var);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pingstats.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,224 @@
+/* $Id: pingstats.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * pingstats.c	(mostly taken from stats.c)
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+#define	MIN(a,b)	(((a) < (b)) ? (a) : (b))
+
+#define	BX_OFF()	((textWidth + 1) * W_Textwidth + S_IBORDER)
+#define	BY_OFF(line)	((line) * (W_Textheight + S_IBORDER) + S_IBORDER)
+#define	TX_OFF(len)	((textWidth - len) * W_Textwidth + S_IBORDER)
+#define	TY_OFF(line)	BY_OFF(line)
+
+/* right side labels */
+#define TEXT_WIDTH		(5*W_Textwidth + 2*STAT_BORDER)
+#define STAT_WIDTH		(260 + TEXT_WIDTH)
+#define STAT_HEIGHT		BY_OFF(NUM_SLIDERS)
+#define STAT_BORDER		2
+#define S_IBORDER		5
+#define STAT_X			422
+#define STAT_Y			13
+
+#define SL_WID			\
+	(STAT_WIDTH -TEXT_WIDTH - 2 * S_IBORDER - (textWidth + 1) * W_Textwidth)
+#define SL_HEI			(W_Textheight)
+
+#define NUM_ELS(a)		(sizeof (a) / sizeof (*(a)))
+#define NUM_SLIDERS		NUM_ELS(sliders)
+
+typedef struct slider {
+    char   *label;
+    int     min, max;
+    int     green, yellow;
+    int     label_length;
+    int     diff;
+    int    *var;
+    int     lastVal;
+}       SLIDER;
+
+typedef struct record {
+    int    *data;
+    int     last_value;
+}       RECORD;
+
+static SLIDER sliders[] = {
+    {"round trip time", 0, 500, 100, 200},
+    {"average r.t. time", 0, 500, 100, 200},
+    {"lag (st. dev.)", 0, 100, 20, 50},
+    {"%pack in  loss", 0, 50, 10, 20},
+    {"%pack out loss", 0, 50, 10, 20},
+    {"tot %pack loss in", 0, 50, 5, 10},
+    {"tot %pack loss out", 0, 50, 5, 10},
+};
+
+static int textWidth = 0;
+static int initialized = 0;
+
+/* prototypes */
+static void box P((int filled, int x, int y, int wid, int hei, W_Color color));
+static void text P((int value, int y));
+
+/* externals from ping.c (didn't feel like cluttering up data.c with them) */
+extern int ping_iloss_sc;	/* inc % loss 0--100, server to client */
+extern int ping_iloss_cs;	/* inc % loss 0--100, client to server */
+extern int ping_tloss_sc;	/* total % loss 0--100, server to client */
+extern int ping_tloss_cs;	/* total % loss 0--100, client to server */
+extern int ping_lag;		/* delay in ms of last ping */
+extern int ping_av;		/* average rt */
+extern int ping_sd;		/* standard deviation */
+
+int
+pStatsHeight()
+{
+    return STAT_HEIGHT;
+}
+
+int
+pStatsWidth()
+{
+    return STAT_WIDTH;
+}
+
+void
+initPStats()
+{
+    int     i;
+
+    if (initialized)
+	return;
+    initialized = 1;
+    sliders[0].var = (int *) &ping_lag;
+    sliders[1].var = (int *) &ping_av;
+    sliders[2].var = (int *) &ping_sd;
+    sliders[3].var = (int *) &ping_iloss_sc;
+    sliders[4].var = (int *) &ping_iloss_cs;
+    sliders[5].var = (int *) &ping_tloss_sc;
+    sliders[6].var = (int *) &ping_tloss_cs;
+
+    /* adjust */
+    if (ping_av > 0) {
+	sliders[0].max = MAX(ping_av * 2, 200);
+	sliders[1].max = MAX(ping_av * 2, 200);
+    }
+    for (i = 0; i < NUM_SLIDERS; i++) {
+	sliders[i].label_length = strlen(sliders[i].label);
+	textWidth = MAX(textWidth, sliders[i].label_length);
+	sliders[i].diff = sliders[i].max - sliders[i].min;
+	sliders[i].lastVal = 0;
+    }
+}
+
+void
+redrawPStats()
+{
+    int     i;
+
+    W_ClearWindow(pStats);
+    initPStats();
+    for (i = 0; i < NUM_SLIDERS; i++) {
+	sliders[i].lastVal = 0;
+    }
+    for (i = 0; i < NUM_SLIDERS; i++) {
+	W_WriteText(pStats, TX_OFF(sliders[i].label_length), TY_OFF(i),
+		    textColor, sliders[i].label, sliders[i].label_length,
+		    W_RegularFont);
+	box(0, BX_OFF() - 1, BY_OFF(i) - 1, SL_WID + 2, SL_HEI + 2, borderColor);
+	sliders[i].lastVal = 0;
+    }
+}
+
+void
+updatePStats()
+{
+    int     i, value, diff, old_x, new_x;
+    W_Color color;
+    SLIDER *s;
+
+    /* do the average and standard deviation calculations */
+    initPStats();
+
+    for (i = 0; i < NUM_SLIDERS; i++) {
+	s = &sliders[i];
+	value = *(s->var);
+	/* update decimal values at the right */
+	text(*(s->var), BY_OFF(i));
+
+	if (value < s->min)
+	    value = s->min;
+	else if (value > s->max)
+	    value = s->max;
+	if (value == s->lastVal)
+	    continue;
+	diff = value - s->lastVal;
+	if (diff < 0) {		/* bar decreasing */
+	    old_x = s->lastVal * SL_WID / s->diff;
+	    new_x = value * SL_WID / s->diff;
+	    box(1, BX_OFF() + new_x, BY_OFF(i), old_x - new_x, SL_HEI, backColor);
+
+	    if (s->lastVal > s->green && value <= s->green)
+		box(1, BX_OFF(), BY_OFF(i), new_x, SL_HEI, gColor);
+	    else if (s->lastVal > s->yellow && value <= s->yellow)
+		box(1, BX_OFF(), BY_OFF(i), new_x, SL_HEI, yColor);
+	} else {		/* bar increasing */
+	    if (s->lastVal <= s->yellow && value > s->yellow) {
+		color = rColor;
+		s->lastVal = 0;
+	    } else if (s->lastVal <= s->green && value > s->green) {
+		color = yColor;
+		s->lastVal = 0;
+	    } else if (value > s->yellow)
+		color = rColor;
+	    else if (value > s->green)
+		color = yColor;
+	    else
+		color = gColor;
+
+	    old_x = s->lastVal * SL_WID / s->diff;
+	    new_x = value * SL_WID / s->diff;
+	    box(1, BX_OFF() + old_x, BY_OFF(i), new_x - old_x, SL_HEI, color);
+	}
+	s->lastVal = value;
+    }
+}
+
+static
+void
+box(filled, x, y, wid, hei, color)
+    int     filled, x, y, wid, hei;
+    W_Color color;
+{
+    if (wid == 0)
+	return;
+
+    if (filled) {
+	/* XFIX */
+	W_FillArea(pStats, x, y, wid + 1, hei + 1, color);
+	return;
+    }
+    W_MakeLine(pStats, x, y, x + wid, y, color);
+    W_MakeLine(pStats, x + wid, y, x + wid, y + hei, color);
+    W_MakeLine(pStats, x + wid, y + hei, x, y + hei, color);
+    W_MakeLine(pStats, x, y + hei, x, y, color);
+}
+
+static
+void
+text(value, y)
+    int     value, y;
+{
+    char    buf[6];
+    sprintf(buf, "(%3d)", value);	/* fix */
+
+    W_WriteText(pStats, STAT_WIDTH - TEXT_WIDTH, y, textColor,
+		buf, 5, W_RegularFont);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planetbitmaps.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,500 @@
+/* $Id: planetbitmaps.h,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+#define indplanet_width 30
+#define indplanet_height 30
+static unsigned char indplanet_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x80,
+    0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00,
+    0x00, 0x04, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01,
+    0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
+    0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x04, 0x00, 0x00, 0x04, 0x04, 0x00,
+    0x00, 0x04, 0x08, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0,
+0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define indmplanet_width 16
+#define indmplanet_height 16
+static unsigned char indmplanet_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x40, 0x01, 0x40, 0x01,
+    0x40, 0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0x02, 0x20, 0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03,
+0x00, 0x00};
+
+static unsigned char planet_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x80,
+    0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x04, 0x00, 0x00, 0x04, 0x04, 0xf0,
+    0x03, 0x04, 0x02, 0xf8, 0x07, 0x08, 0x02, 0x1c, 0x0e, 0x08, 0x02, 0x0c, 0x0c, 0x08, 0x01,
+    0x00, 0x0c, 0x10, 0x01, 0x00, 0x0e, 0x10, 0x01, 0x00, 0x07, 0x10, 0x01, 0x80, 0x03, 0x10,
+    0x01, 0xc0, 0x01, 0x10, 0x01, 0xc0, 0x00, 0x10, 0x01, 0xc0, 0x00, 0x10, 0x02, 0xc0, 0x00,
+    0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x04, 0xc0, 0x00, 0x04, 0x04, 0xc0,
+    0x00, 0x04, 0x08, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0,
+0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define fedplanet_width 30
+#define fedplanet_height 30
+static unsigned char fedplanet_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x00, 0x80,
+    0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02, 0x04, 0x40, 0x00, 0x04, 0x04, 0xe0,
+    0x00, 0x04, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xf0, 0x01, 0x08, 0x02, 0xf0, 0x01, 0x08, 0x01,
+    0xf8, 0x03, 0x10, 0x01, 0xf8, 0x03, 0x10, 0x01, 0xfc, 0x07, 0x10, 0x01, 0xfc, 0x07, 0x10,
+    0x01, 0xfe, 0x0f, 0x10, 0x01, 0xbe, 0x0f, 0x10, 0x01, 0x1f, 0x1f, 0x10, 0x02, 0x0f, 0x1e,
+    0x08, 0x82, 0x07, 0x3c, 0x08, 0x82, 0x03, 0x38, 0x08, 0x84, 0x01, 0x30, 0x04, 0x04, 0x00,
+    0x00, 0x04, 0x08, 0x00, 0x00, 0x02, 0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0,
+0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define oriplanet_width 30
+#define oriplanet_height 30
+static unsigned char oriplanet_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0xf8, 0x83,
+    0x00, 0x10, 0xfe, 0x0f, 0x01, 0x08, 0x01, 0x10, 0x02, 0x04, 0x00, 0x00, 0x04, 0x44, 0x00,
+    0x40, 0x04, 0x82, 0x01, 0x30, 0x08, 0x12, 0x07, 0x1c, 0x09, 0x12, 0xfe, 0x0f, 0x09, 0x11,
+    0xfc, 0x07, 0x11, 0x19, 0xf8, 0x03, 0x13, 0x19, 0xf8, 0x03, 0x13, 0x19, 0xf0, 0x01, 0x13,
+    0x19, 0xf0, 0x01, 0x13, 0x19, 0xf0, 0x01, 0x13, 0x39, 0xe0, 0x80, 0x13, 0x32, 0xe0, 0x80,
+    0x09, 0x32, 0xe0, 0x80, 0x09, 0x62, 0xe0, 0xc0, 0x08, 0x64, 0xe0, 0xc0, 0x04, 0xc4, 0x40,
+    0x60, 0x04, 0x88, 0x41, 0x30, 0x02, 0x10, 0x46, 0x0c, 0x01, 0x20, 0x48, 0x82, 0x00, 0xc0,
+0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define kliplanet_width 30
+#define kliplanet_height 30
+static unsigned char kliplanet_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x40, 0x60, 0x00, 0x20, 0x40, 0x80,
+    0x00, 0x10, 0x40, 0x00, 0x01, 0x08, 0x40, 0x00, 0x02, 0x04, 0x40, 0x00, 0x04, 0x04, 0x40,
+    0x00, 0x04, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08, 0x01,
+    0xf0, 0x01, 0x10, 0x01, 0xf0, 0x01, 0x10, 0x01, 0xf0, 0x01, 0x10, 0x01, 0xf8, 0x03, 0x10,
+    0x01, 0xf0, 0x01, 0x10, 0x01, 0xe6, 0x0c, 0x10, 0x01, 0x4f, 0x1e, 0x10, 0x02, 0x1f, 0x3f,
+    0x08, 0x82, 0x1f, 0x7f, 0x08, 0x82, 0x0f, 0xfe, 0x08, 0xc4, 0x07, 0xf8, 0x05, 0xc4, 0x01,
+    0x00, 0x04, 0xc8, 0x00, 0x00, 0x02, 0x50, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0,
+0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define romplanet_width 30
+#define romplanet_height 30
+static unsigned char romplanet_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00, 0x20, 0x40, 0x80,
+    0x00, 0x10, 0xe0, 0x00, 0x01, 0x08, 0xf8, 0x03, 0x02, 0x04, 0xa0, 0x00, 0x04, 0x04, 0xa0,
+    0x00, 0x04, 0x02, 0xb0, 0x01, 0x08, 0x02, 0xac, 0x06, 0x08, 0x02, 0xaa, 0x09, 0x08, 0x01,
+    0x4a, 0x09, 0x10, 0x01, 0x11, 0x11, 0x10, 0x01, 0x21, 0x11, 0x10, 0x01, 0x21, 0x11, 0x10,
+    0x01, 0xc1, 0x10, 0x10, 0x01, 0x01, 0x16, 0x10, 0x01, 0x02, 0x09, 0x10, 0x02, 0x02, 0x09,
+    0x08, 0x02, 0x0c, 0x06, 0x08, 0x02, 0xf0, 0x01, 0x08, 0x04, 0xa0, 0x00, 0x04, 0x04, 0xa0,
+    0x00, 0x04, 0x08, 0xa0, 0x00, 0x02, 0x10, 0x40, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0,
+0x00, 0x60, 0x00, 0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static unsigned char mplanet_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0xc2, 0x21, 0x21, 0x42, 0x01, 0x42, 0x01,
+    0x41, 0x81, 0x40, 0x81, 0x40, 0x02, 0x20, 0x82, 0x20, 0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03,
+0x00, 0x00};
+#define klimplanet_width 16
+#define klimplanet_height 16
+static unsigned char klimplanet_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x84, 0x10, 0x82, 0x20, 0x82, 0x20, 0xc1, 0x41,
+    0xc1, 0x41, 0xc1, 0x41, 0xb1, 0x42, 0x71, 0x47, 0x3a, 0x27, 0x0a, 0x2c,
+0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+#define rommplanet_width 16
+#define rommplanet_height 16
+static unsigned char rommplanet_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x84, 0x10, 0x82, 0x20, 0xc2, 0x21, 0xa1, 0x42,
+    0x31, 0x45, 0xd1, 0x44, 0x11, 0x47, 0xa1, 0x42, 0xc2, 0x21, 0x82, 0x20,
+0x84, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+#define orimplanet_width 16
+#define orimplanet_height 16
+static unsigned char orimplanet_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0xc4, 0x11, 0xf2, 0x27, 0x02, 0x20, 0x39, 0x4e, 0xe1, 0x43, 0xc5,
+    0x51, 0xcd, 0x59, 0x89, 0x48, 0x9a, 0x2c, 0x92, 0x24, 0xa4, 0x12, 0x18, 0x0c, 0xe0, 0x03,
+0x00, 0x00};
+#define fedmplanet_width 16
+#define fedmplanet_height 16
+static unsigned char fedmplanet_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x82, 0x20, 0xc1, 0x41,
+    0xc1, 0x41, 0xe1, 0x43, 0xe1, 0x43, 0x71, 0x47, 0x32, 0x26, 0x02, 0x20,
+0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+
+#define mplanet111_width 16
+#define mplanet111_height 16
+static unsigned char mplanet111_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0x5a, 0x21, 0xda, 0x21, 0x81, 0x4c,
+    0x99, 0x54, 0xa5, 0x54, 0xbd, 0x54, 0xa5, 0x5c, 0xda, 0x21, 0x5a, 0x21,
+0x44, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+#define mplanet110_width 16
+#define mplanet110_height 16
+static unsigned char mplanet110_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0x5a, 0x21, 0xda, 0x21, 0x81, 0x40,
+    0x99, 0x40, 0xa5, 0x40, 0xbd, 0x40, 0xa5, 0x40, 0xda, 0x21, 0x5a, 0x21,
+0x44, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+#define mplanet101_width 16
+#define mplanet101_height 16
+static unsigned char mplanet101_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x1a, 0x20, 0x1a, 0x20, 0x01, 0x4c,
+    0x19, 0x54, 0x25, 0x54, 0x3d, 0x54, 0x25, 0x5c, 0x1a, 0x20, 0x1a, 0x20,
+0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+#define mplanet100_width 16
+#define mplanet100_height 16
+static unsigned char mplanet100_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x1a, 0x20, 0x1a, 0x20, 0x01, 0x40,
+    0x19, 0x40, 0x25, 0x40, 0x3d, 0x40, 0x25, 0x40, 0x1a, 0x20, 0x1a, 0x20,
+0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+#define mplanet011_width 16
+#define mplanet011_height 16
+static unsigned char mplanet011_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0x42, 0x21, 0xc2, 0x21, 0x81, 0x4c,
+    0x81, 0x54, 0x81, 0x54, 0x81, 0x54, 0x81, 0x5c, 0xc2, 0x21, 0x42, 0x21,
+0x44, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+#define mplanet010_width 16
+#define mplanet010_height 16
+static unsigned char mplanet010_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0x42, 0x21, 0xc2, 0x21, 0x81, 0x40,
+    0x81, 0x40, 0x81, 0x40, 0x81, 0x40, 0x81, 0x40, 0xc2, 0x21, 0x42, 0x21,
+0x44, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+#define mplanet001_width 16
+#define mplanet001_height 16
+static unsigned char mplanet001_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x4c,
+    0x01, 0x54, 0x01, 0x54, 0x01, 0x54, 0x01, 0x5c, 0x02, 0x20, 0x02, 0x20,
+0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+
+#define mplanet1111_width 16
+#define mplanet1111_height 16
+static unsigned char mplanet1111_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0xda, 0x21, 0x9a, 0x20, 0xc1, 0x4d,
+    0x59, 0x55, 0x25, 0x54, 0x3d, 0x54, 0xa5, 0x5c, 0x9a, 0x23, 0xda, 0x21,
+0x04, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+
+#define mplanet1110_width 16
+#define mplanet1110_height 16
+static unsigned char mplanet1110_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0xda, 0x21, 0x9a, 0x20, 0xc1, 0x41,
+    0x59, 0x41, 0x25, 0x40, 0x3d, 0x40, 0xa5, 0x40, 0x9a, 0x23, 0xda, 0x21,
+0x04, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+
+#define mplanet1010_width 16
+#define mplanet1010_height 16
+static unsigned char mplanet1010_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0xc2, 0x21, 0x82, 0x20, 0xc1, 0x41,
+    0x41, 0x41, 0x01, 0x40, 0x01, 0x40, 0x81, 0x40, 0x82, 0x23, 0xc2, 0x21,
+0x04, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+
+#define mplanet1011_width 16
+#define mplanet1011_height 16
+static unsigned char mplanet1011_bits[] = {
+    0xe0, 0x03, 0x18, 0x0c, 0x44, 0x11, 0xc2, 0x21, 0x82, 0x20, 0xc1, 0x4d,
+    0x41, 0x55, 0x01, 0x54, 0x01, 0x54, 0x81, 0x5c, 0x82, 0x23, 0xc2, 0x21,
+0x04, 0x11, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00};
+
+#define planet111_width 30
+#define planet111_height 30
+static unsigned char planet111_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x10, 0x61, 0x00,
+    0x20, 0x18, 0x83, 0x00, 0x10, 0x18, 0x03, 0x01, 0x08, 0x18, 0x03, 0x02,
+    0x04, 0xf8, 0x03, 0x04, 0xe4, 0xf8, 0x03, 0x04, 0xe2, 0xe0, 0xf8, 0x08,
+    0xe2, 0xe0, 0x08, 0x09, 0x42, 0x40, 0x08, 0x0a, 0xf9, 0xe3, 0xa8, 0x12,
+    0xf5, 0x45, 0x48, 0x12, 0x55, 0xe5, 0xa8, 0x12, 0xf5, 0x45, 0x08, 0x12,
+    0x55, 0xe5, 0x08, 0x12, 0xf5, 0x45, 0x08, 0x12, 0xb1, 0xe1, 0x08, 0x12,
+    0xb2, 0x41, 0xf8, 0x0b, 0xb2, 0xe1, 0x00, 0x08, 0xb2, 0xe1, 0x00, 0x08,
+    0xb4, 0xf9, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x08, 0x18, 0x03, 0x02,
+    0x10, 0x18, 0x03, 0x01, 0x20, 0x18, 0x83, 0x00, 0xc0, 0x10, 0x61, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define planet110_width 30
+#define planet110_height 30
+static unsigned char planet110_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x10, 0x61, 0x00,
+    0x20, 0x18, 0x83, 0x00, 0x10, 0x18, 0x03, 0x01, 0x08, 0x18, 0x03, 0x02,
+    0x04, 0xf8, 0x03, 0x04, 0xe4, 0xf8, 0x03, 0x04, 0xe2, 0xe0, 0x00, 0x08,
+    0xe2, 0xe0, 0x00, 0x08, 0x42, 0x40, 0x00, 0x08, 0xf9, 0xe3, 0x00, 0x10,
+    0xf5, 0x45, 0x00, 0x10, 0x55, 0xe5, 0x00, 0x10, 0xf5, 0x45, 0x00, 0x10,
+    0x55, 0xe5, 0x00, 0x10, 0xf5, 0x45, 0x00, 0x10, 0xb1, 0xe1, 0x00, 0x10,
+    0xb2, 0x41, 0x00, 0x08, 0xb2, 0xe1, 0x00, 0x08, 0xb2, 0xe1, 0x00, 0x08,
+    0xb4, 0xf9, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x08, 0x18, 0x03, 0x02,
+    0x10, 0x18, 0x03, 0x01, 0x20, 0x18, 0x83, 0x00, 0xc0, 0x10, 0x61, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define planet101_width 30
+#define planet101_height 30
+static unsigned char planet101_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00,
+    0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xe2, 0x00, 0xf8, 0x08,
+    0xe2, 0x00, 0x08, 0x09, 0x42, 0x00, 0x08, 0x0a, 0xf9, 0x03, 0xa8, 0x12,
+    0xf5, 0x05, 0x48, 0x12, 0x55, 0x05, 0xa8, 0x12, 0xf5, 0x05, 0x08, 0x12,
+    0x55, 0x05, 0x08, 0x12, 0xf5, 0x05, 0x08, 0x12, 0xb1, 0x01, 0x08, 0x12,
+    0xb2, 0x01, 0xf8, 0x0b, 0xb2, 0x01, 0x00, 0x08, 0xb2, 0x01, 0x00, 0x08,
+    0xb4, 0x01, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define planet100_width 30
+#define planet100_height 30
+static unsigned char planet100_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00,
+    0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x04, 0x00, 0x00, 0x04, 0xe4, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x08,
+    0xe2, 0x00, 0x00, 0x08, 0x42, 0x00, 0x00, 0x08, 0xf9, 0x03, 0x00, 0x10,
+    0xf5, 0x05, 0x00, 0x10, 0x55, 0x05, 0x00, 0x10, 0xf5, 0x05, 0x00, 0x10,
+    0x55, 0x05, 0x00, 0x10, 0xf5, 0x05, 0x00, 0x10, 0xb1, 0x01, 0x00, 0x10,
+    0xb2, 0x01, 0x00, 0x08, 0xb2, 0x01, 0x00, 0x08, 0xb2, 0x01, 0x00, 0x08,
+    0xb4, 0x01, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define planet011_width 30
+#define planet011_height 30
+static unsigned char planet011_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x10, 0x61, 0x00,
+    0x20, 0x18, 0x83, 0x00, 0x10, 0x18, 0x03, 0x01, 0x08, 0x18, 0x03, 0x02,
+    0x04, 0xf8, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x02, 0xe0, 0xf8, 0x08,
+    0x02, 0xe0, 0x08, 0x09, 0x02, 0x40, 0x08, 0x0a, 0x01, 0xe0, 0xa8, 0x12,
+    0x01, 0x40, 0x48, 0x12, 0x01, 0xe0, 0xa8, 0x12, 0x01, 0x40, 0x08, 0x12,
+    0x01, 0xe0, 0x08, 0x12, 0x01, 0x40, 0x08, 0x12, 0x01, 0xe0, 0x08, 0x12,
+    0x02, 0x40, 0xf8, 0x0b, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08,
+    0x04, 0xf8, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x08, 0x18, 0x03, 0x02,
+    0x10, 0x18, 0x03, 0x01, 0x20, 0x18, 0x83, 0x00, 0xc0, 0x10, 0x61, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define planet010_width 30
+#define planet010_height 30
+static unsigned char planet010_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x10, 0x61, 0x00,
+    0x20, 0x18, 0x83, 0x00, 0x10, 0x18, 0x03, 0x01, 0x08, 0x18, 0x03, 0x02,
+    0x04, 0xf8, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x02, 0xe0, 0x00, 0x08,
+    0x02, 0xe0, 0x00, 0x08, 0x02, 0x40, 0x00, 0x08, 0x01, 0xe0, 0x00, 0x10,
+    0x01, 0x40, 0x00, 0x10, 0x01, 0xe0, 0x00, 0x10, 0x01, 0x40, 0x00, 0x10,
+    0x01, 0xe0, 0x00, 0x10, 0x01, 0x40, 0x00, 0x10, 0x01, 0xe0, 0x00, 0x10,
+    0x02, 0x40, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08, 0x02, 0xe0, 0x00, 0x08,
+    0x04, 0xf8, 0x03, 0x04, 0x04, 0xf8, 0x03, 0x04, 0x08, 0x18, 0x03, 0x02,
+    0x10, 0x18, 0x03, 0x01, 0x20, 0x18, 0x83, 0x00, 0xc0, 0x10, 0x61, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define planet001_width 30
+#define planet001_height 30
+static unsigned char planet001_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00,
+    0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0xf8, 0x08,
+    0x02, 0x00, 0x08, 0x09, 0x02, 0x00, 0x08, 0x0a, 0x01, 0x00, 0xa8, 0x12,
+    0x01, 0x00, 0x48, 0x12, 0x01, 0x00, 0xa8, 0x12, 0x01, 0x00, 0x08, 0x12,
+    0x01, 0x00, 0x08, 0x12, 0x01, 0x00, 0x08, 0x12, 0x01, 0x00, 0x08, 0x12,
+    0x02, 0x00, 0xf8, 0x0b, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define planet1111_width 30
+#define planet1111_height 30
+static unsigned char planet1111_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0xa0, 0x60, 0x00,
+    0x20, 0xb0, 0x81, 0x00, 0x10, 0xb0, 0x01, 0x01, 0x08, 0xf0, 0x01, 0x02,
+    0x04, 0x40, 0x00, 0x04, 0xe4, 0xe0, 0x00, 0x04, 0xe2, 0x40, 0xf8, 0x08,
+    0xe2, 0xe0, 0x08, 0x09, 0x42, 0x40, 0x08, 0x0a, 0xf9, 0xe3, 0xa8, 0x12,
+    0xf5, 0x45, 0x48, 0x12, 0x55, 0xf5, 0xa9, 0x12, 0xf5, 0xb5, 0x09, 0x12,
+    0x55, 0xb5, 0x09, 0x12, 0xf5, 0xa5, 0x08, 0x12, 0xb1, 0x01, 0x08, 0x12,
+    0xb2, 0x91, 0xf9, 0x0b, 0xb2, 0xf1, 0x00, 0x08, 0xb2, 0xf5, 0x07, 0x08,
+    0xb4, 0x1d, 0x03, 0x04, 0x04, 0x18, 0x03, 0x04, 0x08, 0x18, 0x07, 0x02,
+    0x10, 0xfc, 0x05, 0x01, 0x20, 0xe0, 0x81, 0x00, 0xc0, 0x30, 0x61, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define planet1110_width 30
+#define planet1110_height 30
+static unsigned char planet1110_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0xa0, 0x60, 0x00,
+    0x20, 0xb0, 0x81, 0x00, 0x10, 0xb0, 0x01, 0x01, 0x08, 0xf0, 0x01, 0x02,
+    0x04, 0x40, 0x00, 0x04, 0xe4, 0xe0, 0x00, 0x04, 0xe2, 0x40, 0x00, 0x08,
+    0xe2, 0xe0, 0x00, 0x08, 0x42, 0x40, 0x00, 0x08, 0xf9, 0xe3, 0x00, 0x10,
+    0xf5, 0x45, 0x00, 0x10, 0x55, 0xf5, 0x01, 0x10, 0xf5, 0xb5, 0x01, 0x10,
+    0x55, 0xb5, 0x01, 0x10, 0xf5, 0xa5, 0x00, 0x10, 0xb1, 0x01, 0x00, 0x10,
+    0xb2, 0x91, 0x01, 0x08, 0xb2, 0xf1, 0x00, 0x08, 0xb2, 0xf5, 0x07, 0x08,
+    0xb4, 0x1d, 0x03, 0x04, 0x04, 0x18, 0x03, 0x04, 0x08, 0x18, 0x07, 0x02,
+    0x10, 0xfc, 0x05, 0x01, 0x20, 0xe0, 0x81, 0x00, 0xc0, 0x30, 0x61, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define planet1010_width 30
+#define planet1010_height 30
+static unsigned char planet1010_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0xa0, 0x60, 0x00,
+    0x20, 0xb0, 0x81, 0x00, 0x10, 0xb0, 0x01, 0x01, 0x08, 0xf0, 0x01, 0x02,
+    0x04, 0x40, 0x00, 0x04, 0x04, 0xe0, 0x00, 0x04, 0x02, 0x40, 0x00, 0x08,
+    0x02, 0xe0, 0x00, 0x08, 0x02, 0x40, 0x00, 0x08, 0x01, 0xe0, 0x00, 0x10,
+    0x01, 0x40, 0x00, 0x10, 0x01, 0xf0, 0x01, 0x10, 0x01, 0xb0, 0x01, 0x10,
+    0x01, 0xb0, 0x01, 0x10, 0x01, 0xa0, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x02, 0x90, 0x01, 0x08, 0x02, 0xf0, 0x00, 0x08, 0x02, 0xf4, 0x07, 0x08,
+    0x04, 0x1c, 0x03, 0x04, 0x04, 0x18, 0x03, 0x04, 0x08, 0x18, 0x07, 0x02,
+    0x10, 0xfc, 0x05, 0x01, 0x20, 0xe0, 0x81, 0x00, 0xc0, 0x30, 0x61, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#define planet1011_width 30
+#define planet1011_height 30
+static unsigned char planet1011_bits[] = {
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0xa0, 0x60, 0x00,
+    0x20, 0xb0, 0x81, 0x00, 0x10, 0xb0, 0x01, 0x01, 0x08, 0xf0, 0x01, 0x02,
+    0x04, 0x40, 0x00, 0x04, 0x04, 0xe0, 0x00, 0x04, 0x02, 0x40, 0xf8, 0x08,
+    0x02, 0xe0, 0x08, 0x09, 0x02, 0x40, 0x08, 0x0a, 0x01, 0xe0, 0xa8, 0x12,
+    0x01, 0x40, 0x48, 0x12, 0x01, 0xf0, 0xa9, 0x12, 0x01, 0xb0, 0x09, 0x12,
+    0x01, 0xb0, 0x09, 0x12, 0x01, 0xa0, 0x08, 0x12, 0x01, 0x00, 0x08, 0x12,
+    0x02, 0x90, 0xf9, 0x0b, 0x02, 0xf0, 0x00, 0x08, 0x02, 0xf4, 0x07, 0x08,
+    0x04, 0x1c, 0x03, 0x04, 0x04, 0x18, 0x03, 0x04, 0x08, 0x18, 0x07, 0x02,
+    0x10, 0xfc, 0x05, 0x01, 0x20, 0xe0, 0x81, 0x00, 0xc0, 0x30, 0x61, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#if 0
+static unsigned char shield_bits[] = {
+    0xc0, 0x3f, 0x00, 0x30, 0xc0, 0x00, 0x08, 0x00, 0x01, 0x04, 0x00, 0x02,
+    0x02, 0x00, 0x04, 0x02, 0x00, 0x04, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08,
+    0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x01, 0x00, 0x08,
+    0x01, 0x00, 0x08, 0x01, 0x00, 0x08, 0x02, 0x00, 0x04, 0x02, 0x00, 0x04,
+0x04, 0x00, 0x02, 0x08, 0x00, 0x01, 0x30, 0xc0, 0x00, 0xc0, 0x3f, 0x00};
+#endif
+
+static unsigned char cloak_bits[] = {
+    0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x00, 0x08, 0x82, 0x00,
+    0x04, 0x00, 0x01, 0x20, 0x20, 0x00, 0x00, 0x02, 0x00, 0x80, 0x08, 0x00,
+    0x01, 0x00, 0x04, 0x49, 0x90, 0x04, 0x01, 0x00, 0x04, 0x80, 0x08, 0x00,
+    0x00, 0x02, 0x00, 0x20, 0x20, 0x00, 0x04, 0x00, 0x01, 0x08, 0x82, 0x00,
+0x10, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00};
+
+#define starm_width 16
+#define starm_height 16
+static unsigned char starm_bits[] = {
+    0x40, 0x00, 0x8c, 0x00, 0xc8, 0x10, 0xf8, 0x1b, 0x18, 0x0c, 0x28, 0x0b,
+    0x6d, 0x28, 0x4e, 0x7c, 0x08, 0x19, 0x28, 0x09, 0x1c, 0x07, 0xe4, 0x0f,
+0x86, 0x18, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00};
+
+#define star_width 30
+#define star_height 30
+static unsigned char star_bits[] = {
+    0x00, 0x20, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0xc0, 0x10, 0xc0, 0x00,
+    0x80, 0x10, 0x42, 0x00, 0x80, 0x30, 0x63, 0x00, 0x80, 0xfb, 0x3b, 0x00,
+    0x00, 0x07, 0x3c, 0x00, 0x00, 0x0f, 0x34, 0x00, 0xfc, 0x09, 0x24, 0x00,
+    0xc4, 0x18, 0x60, 0x1d, 0x46, 0x11, 0xc8, 0x17, 0x60, 0x03, 0x8c, 0x03,
+    0x60, 0x00, 0x86, 0x00, 0x20, 0x84, 0x83, 0x00, 0x20, 0xd0, 0xb8, 0x00,
+    0x3c, 0x1e, 0xa0, 0x14, 0x7e, 0x9c, 0x80, 0x06, 0x72, 0x82, 0xc4, 0x03,
+    0x60, 0x80, 0xc8, 0x01, 0x40, 0xc0, 0x70, 0x00, 0xc0, 0x60, 0xf0, 0x00,
+    0xc0, 0x23, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x03, 0x80, 0xfc, 0x07, 0x06,
+    0xc0, 0x40, 0x06, 0x04, 0xc0, 0x60, 0x0c, 0x00, 0x40, 0x10, 0x18, 0x00,
+0x20, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+#if 0
+#define holem_width 16
+#define holem_height 16
+static unsigned char holem_bits[] = {
+   0xf0, 0x0f, 0x08, 0x10, 0xe4, 0x27, 0x12, 0x48, 0xc9, 0x93, 0x25, 0xa4,
+   0x95, 0xa9, 0x55, 0xaa, 0x55, 0xa9, 0x55, 0xa4, 0x95, 0x93, 0x25, 0x48,
+   0xc9, 0x27, 0x12, 0x10, 0xe4, 0x0f, 0x08, 0x00};
+
+#define holem_width 16
+#define holem_height 16
+static char holem_bits[] = {
+   0x10, 0x11, 0x20, 0x12, 0x40, 0x12, 0x87, 0x0a, 0x98, 0x8a, 0x20, 0x45,
+   0x5e, 0x23, 0xe1, 0x19, 0x98, 0x87, 0xc4, 0x7a, 0xa2, 0x04, 0x51, 0x19,
+   0x50, 0xe1, 0x48, 0x02, 0x48, 0x04, 0x88, 0x08};
+#endif /*0*/
+
+#ifdef VISIBLE_WORMHOLES
+#define holem_width 16
+#define holem_height 16
+static char holem_bits[] = {
+   0x00, 0x01, 0x20, 0x02, 0x40, 0x12, 0x84, 0x0a, 0x98, 0x0a, 0x20, 0x45,
+   0x5e, 0x23, 0xe1, 0x19, 0x98, 0x87, 0xc4, 0x7a, 0xa2, 0x04, 0x50, 0x19,
+   0x50, 0x21, 0x48, 0x02, 0x40, 0x04, 0x80, 0x00};
+#endif /*VISIBLE_WORMHOLES*/
+
+#define asteroid_width 30
+#define asteroid_height 30
+static unsigned char asteroid_bits[] = {
+    0x00, 0xf0, 0x01, 0x00, 0x00, 0x0e, 0x1e, 0x00, 0x80, 0x01, 0x20, 0x00,
+    0x40, 0x00, 0x41, 0x00, 0x30, 0x06, 0x80, 0x01, 0x10, 0x09, 0x00, 0x01,
+    0x88, 0x10, 0x10, 0x02, 0x84, 0x10, 0x28, 0x04, 0x04, 0x09, 0x10, 0x04,
+    0x02, 0x86, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x10,
+    0x11, 0x02, 0x00, 0x11, 0x01, 0x20, 0x80, 0x20, 0x01, 0x50, 0x00, 0x20,
+    0x01, 0x20, 0x00, 0x28, 0x01, 0x00, 0x39, 0x34, 0x82, 0x04, 0x44, 0x34,
+    0x02, 0x00, 0x44, 0x28, 0x02, 0x00, 0x44, 0x20, 0x1c, 0x08, 0x38, 0x10,
+    0xe0, 0x00, 0x00, 0x10, 0x00, 0xc1, 0x01, 0x10, 0x00, 0x22, 0x22, 0x08,
+    0x00, 0xc2, 0x01, 0x06, 0x00, 0x02, 0x80, 0x01, 0x00, 0x02, 0x60, 0x00,
+0x00, 0x0e, 0x10, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x80, 0x07, 0x00};
+
+#define masteroid_width 16
+#define masteroid_height 16
+static unsigned char masteroid_bits[] = {
+    0xe0, 0x07, 0x18, 0x08, 0x34, 0x30, 0x4a, 0x2c, 0x4a, 0x4c, 0x31, 0x40,
+    0x05, 0x80, 0xc1, 0x90, 0xc1, 0xc4, 0x11, 0xca, 0x07, 0x84, 0x1c, 0x81,
+0xb0, 0x4a, 0x30, 0x31, 0x60, 0x0c, 0xc0, 0x07};
+
+#define age_width 16
+#define age_height 16
+static unsigned char age_bits[NSCOUTAGES][32] = {
+    {
+	0xe0, 0x03, 0x18, 0x0c, 0x04, 0x10, 0x02, 0x20, 0x02, 0x20, 0x01, 0x40,
+	0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x01, 0x40, 0x02, 0x20, 0x02, 0x20,
+    0x04, 0x10, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00},
+    {
+	0xe0, 0x03, 0x18, 0x0c, 0xac, 0x12, 0x02, 0x20, 0xaa, 0x2a, 0x01, 0x40,
+	0xab, 0x6a, 0x01, 0x40, 0xab, 0x6a, 0x01, 0x40, 0xaa, 0x2a, 0x02, 0x20,
+    0xac, 0x1a, 0x18, 0x0c, 0xe0, 0x03, 0x00, 0x00},
+    {
+	0xe0, 0x03, 0x58, 0x0d, 0xac, 0x1a, 0x56, 0x35, 0xaa, 0x2a, 0x55, 0x55,
+	0xab, 0x6a, 0x55, 0x55, 0xab, 0x6a, 0x55, 0x55, 0xaa, 0x2a, 0x56, 0x35,
+    0xac, 0x1a, 0x58, 0x0d, 0xe0, 0x03, 0x00, 0x00},
+    {
+	0xe0, 0x03, 0x58, 0x0d, 0xfc, 0x1f, 0x56, 0x35, 0xfe, 0x3f, 0x55, 0x55,
+	0xff, 0x7f, 0x55, 0x55, 0xff, 0x7f, 0x55, 0x55, 0xfe, 0x3f, 0x56, 0x35,
+    0xfc, 0x1f, 0x58, 0x0d, 0xe0, 0x03, 0x00, 0x00},
+    {
+	0xe0, 0x03, 0xf8, 0x0f, 0xfc, 0x1f, 0xfe, 0x3f, 0xfe, 0x3f, 0xff, 0x7f,
+	0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xfe, 0x3f, 0xfe, 0x3f,
+    0xfc, 0x1f, 0xf8, 0x0f, 0xe0, 0x03, 0x00, 0x00}
+};
+
+/* MOO-style bitmaps extended to paradise -RF */
+#define rmyplanet1010_width 30
+#define rmyplanet1010_height 30
+static unsigned char rmyplanet1010_bits[] = {
+    0x01, 0x18, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0xc4, 0x00, 0x60, 0x00,
+    0x18, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet1011_width 30
+#define rmyplanet1011_height 30
+static unsigned char rmyplanet1011_bits[] = {
+    0x01, 0x18, 0x03, 0x07, 0x02, 0x00, 0x00, 0x05, 0xc4, 0x00, 0x60, 0x07,
+    0x18, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet1110_width 30
+#define rmyplanet1110_height 30
+static unsigned char rmyplanet1110_bits[] = {
+    0x01, 0xf8, 0x03, 0x00, 0x02, 0x07, 0x1c, 0x00, 0xc4, 0x00, 0x60, 0x00,
+    0x28, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet1111_width 30
+#define rmyplanet1111_height 30
+static unsigned char rmyplanet1111_bits[] = {
+    0x01, 0xf8, 0x03, 0x07, 0x02, 0x07, 0x1c, 0x05, 0xc4, 0x00, 0x60, 0x07,
+    0x28, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmymplanet1010_width 16
+#define rmymplanet1010_height 16
+static unsigned char rmymplanet1010_bits[] = {
+    0xa0, 0x02, 0x08, 0x08, 0x40, 0x01, 0xc2, 0x21, 0x80, 0x00, 0xc1, 0x41,
+    0x40, 0x01, 0x01, 0x40, 0x00, 0x00, 0x81, 0x40, 0x80, 0x03, 0xc2, 0x21,
+0x00, 0x01, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00};
+#define rmymplanet1011_width 16
+#define rmymplanet1011_height 16
+static unsigned char rmymplanet1011_bits[] = {
+    0xa0, 0x02, 0x08, 0x08, 0x40, 0x01, 0xc2, 0x21, 0x80, 0x00, 0xc1, 0x4d,
+    0x40, 0x15, 0x01, 0x54, 0x00, 0x14, 0x81, 0x5c, 0x80, 0x03, 0xc2, 0x21,
+0x00, 0x01, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planetlist.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,256 @@
+/* $Id: planetlist.c,v 1.1.1.1 1997/12/06 05:41:29 darius Exp $ */
+
+/*
+ * planetlist.c
+ */
+#include "copyright.h"
+#include <stdio.h>
+#include <string.h>
+
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+/* Prototypes */
+static void planet_list_paradise P((void));
+static void planet_list_normal P((void));
+static void print_planet P((W_Window wind, int line, struct planet * j));
+
+static char *teamname[5] = {
+    "IND",
+    "FED",
+    "ROM",
+    "KLI",
+    "ORI"
+};
+
+/*
+** Open a window which contains all the planets and their current
+** statistics.  Players will not know about planets that their team
+** has not orbited.
+*/
+
+void
+planetlist()
+{
+    /*
+       W_ClearWindow(planetw);
+    */
+    if (!paradise) {		/* if not a paradise server then */
+	planet_list_normal();
+    } else {			/* else must be a paradise server */
+	planet_list_paradise();
+    }
+}
+
+
+/*This function provides the planet list for a normal server. */
+
+static void
+planet_list_normal()
+{
+    int     k = 0;		/* for row number */
+    int     i;			/* looping var */
+    struct planet *j;		/* to point to a planet */
+    char    buf[100];		/* to sprintf into */
+    char    buf1[40];
+    W_Window wind;
+
+    wind = planetw;
+
+    for (i = 0, j = &planets[i]; i < nplanets; i++, j++) {
+	if (i == 0 || i == nplanets / 2) {
+	    if (i != 0) {
+		wind = planetw2;
+	    }
+	    sprintf(buf, "Planet name           Own Armies      Resources          Info");
+	    W_WriteText(wind, 2, 1, textColor, buf, strlen(buf), W_RegularFont);
+	    k = 2;
+	}
+	sprintf(buf1, "%-16s ", j->pl_name);
+	if (j->pl_info & idx_to_mask(me->p_teami)) {
+	    sprintf(buf, "%3s %3d       %s%s%s      %s    ",
+		    teamname[mask_to_idx(j->pl_owner) + 1],
+		    j->pl_armies,
+		    (j->pl_flags & PLREPAIR ? "REPR " : "     "),
+		    (j->pl_flags & PLFUEL ? "FUEL " : "     "),
+		    (j->pl_flags & PLAGRI ? "AGRI " : "     "),
+		    team_bit_string(j->pl_info));
+	    W_WriteText(wind, 2, k, planetColor(j), buf1, strlen(buf1),
+			planetFont(j));
+	    W_WriteText(wind, 24, k++, planetColor(j), buf, strlen(buf),
+			planetFont(j));
+	}
+	/* end of have info */
+	else {			/* else no info on planet */
+	    W_WriteText(wind, 2, k++, planetColor(j), buf1, strlen(buf1),
+			planetFont(j));
+	}
+    }				/* end of for loop */
+
+}
+
+
+
+/*This function provides the planet list for a paradise server version 2.0 */
+
+static void
+planet_list_paradise()
+{
+    typedef struct planet *plptr;
+
+    int     k = 0;		/* for row number */
+    int     i, team_pnum;	/* looping var */
+    plptr   j;			/* to point to a planet */
+    char    buf[100];		/* to sprintf into */
+    W_Window wind;
+    extern int number_of_teams;
+    plptr **team_p;
+    int    *team_pcount;
+
+    wind = planetw;
+
+    /* this malloc stuff will handle any number of teams/races */
+
+    /* team's planet counters */
+    team_pcount = (int *) malloc((number_of_teams + 1) * sizeof(int));
+    for (i = 0; i < number_of_teams + 1; i++)
+	team_pcount[i] = 0;
+
+    if (mapSort) {
+	/* make some memory */
+	team_p = (plptr **) malloc((number_of_teams + 1) * sizeof(struct planet *));
+	for (i = 0; i < (number_of_teams + 1); i++)
+	    team_p[i] = (plptr *) malloc(nplanets * sizeof(struct planet *));
+
+	/* loop thru and put proper team planeter point on each planet */
+	for (i = 0, j = &planets[i]; i < nplanets; i++, j++) {
+	    k = mask_to_idx(j->pl_owner) + 1;	/* which team gets planet */
+	    team_p[k][team_pcount[k]] = j;
+	    team_pcount[k]++;
+	}
+
+	/* go thru each teams planet list and display */
+	for (i = 0, k = 0; i < (number_of_teams + 1); i++) {
+	    for (team_pnum = 0; team_pnum < team_pcount[i]; team_pnum++, k++) {
+
+		j = team_p[i][team_pnum];
+		/* (nplanets+13)/2 is the height of window; from newwin.c */
+		if (k == 0 || k >= ((nplanets + 13) / 2)) {
+		    if (k != 0)
+			wind = planetw2;
+		    sprintf(buf, "Planet name      sctr own armies RESOURCES  SURFC  ATMOS    VISIT    TIME");
+		    W_WriteText(wind, 2, 1, textColor, buf, strlen(buf), W_RegularFont);
+		    k = 2;
+		}
+		print_planet(wind, k, j);
+	    }			/* end of 2nd for */
+	    if (team_pcount[i] > 0)
+		k++;
+	}			/* end of 1st for */
+
+	for (i = 0; i < (number_of_teams + 1); i++)
+	    free(team_p[i]);
+	free(team_p);
+    } else {			/* do the original alpa only sort planet list */
+
+	for (i = 0, j = &planets[i]; i < nplanets; i++, j++, k++) {
+	    if (i == 0 || i == nplanets / 2) {
+
+		sprintf(buf, "Planet name      sctr own armies RESOURCES  SURFC  ATMOS    VISIT    TIME");
+
+		if (i != 0) {
+		    wind = planetw2;
+		}
+		W_WriteText(wind, 2, 1, textColor, buf, strlen(buf), W_RegularFont);
+		k = 2;
+	    }
+	    team_pcount[mask_to_idx(j->pl_owner) + 1]++;
+	    print_planet(wind, k, j);
+	}
+    }
+
+    k++;
+    for (i = 0; i < (number_of_teams + 1); i++) {
+	W_Color cur_color;
+
+	cur_color = shipCol[i];
+	sprintf(buf, "%s: ", teamname[i]);
+	W_WriteText(wind, i * 7 + 2, k, cur_color, buf, strlen(buf), W_RegularFont);
+	sprintf(buf, " %.2i", team_pcount[i]);
+	W_WriteText(wind, i * 7 + 2, k + 1, cur_color, buf, strlen(buf), W_RegularFont);
+    }
+
+    free(team_pcount);
+
+}				/* end of planet_list_paradise */
+
+
+/****************************** print_planet() ************************/
+static void
+print_planet(wind, line, j)
+    W_Window wind;
+    int     line;
+    struct planet *j;
+{
+    char    buf[100];		/* to sprintf into */
+
+    sprintf(buf, "%-16s %d-%d", j->pl_name, (j->pl_x / GRIDSIZE) + 1,
+	    (j->pl_y / GRIDSIZE) + 1);
+    W_WriteText(wind, 2, line, textColor, buf, strlen(buf),
+		W_RegularFont);
+
+    if (j->pl_info & idx_to_mask(me->p_teami)) {
+	if (PL_TYPE(*j) == PLSTAR) {	/* if planet actually a star */
+	    W_WriteText(wind, 24, line, textColor, "---S T A R---", 13,
+		       W_RegularFont);
+	} else if (PL_TYPE(*j) == PLWHOLE) { /* if wormhole... */
+	   W_WriteText(wind, 24, line, textColor, "---W O R M H O L E---", 21,
+			W_RegularFont);
+	} else {		/* else planet not a star */
+	    char   *s = NULL;
+
+	    switch (j->pl_flags & PLATMASK) {
+	    case PLPOISON:
+		s = "TOXC";
+		break;
+	    case PLATYPE3:
+		s = "TNTD";
+		break;
+	    case PLATYPE2:
+		s = "THIN";
+		break;
+	    case PLATYPE1:
+		s = "STND";
+		break;
+	    };
+	    sprintf(buf, "%3s %3d       %c%c%c%c     %c%c%c    %4s",
+		    teamname[mask_to_idx(j->pl_owner) + 1],
+		    j->pl_armies,
+		    (j->pl_flags & PLREPAIR ? 'R' : ' '),
+		    (j->pl_flags & PLFUEL ? 'F' : ' '),
+		    (j->pl_flags & PLAGRI ? 'A' : ' '),
+		    (j->pl_flags & PLSHIPYARD ? 'S' : ' '),
+		    (j->pl_flags & PLDILYTH ? 'D' : ' '),
+		    (j->pl_flags & PLMETAL ? 'M' : ' '),
+		    (j->pl_flags & PLARABLE ? 'A' : ' '),
+		    s);
+
+	    W_WriteText(wind, 24, line, planetColor(j), buf, strlen(buf),
+			planetFont(j));
+
+	    sprintf(buf, "%4s   %3ld",
+		    team_bit_string(j->pl_info),
+		    ((idx_to_mask(me->p_teami) == j->pl_owner) ? 0 : (status2->clock - j->pl_timestamp)));
+
+	    W_WriteText(wind, 64, line, planetColor(j), buf, strlen(buf),
+			planetFont(j));
+	}
+    } else {
+	sprintf(buf, "--- No info; Scout me ---");
+	W_WriteText(wind, 24, line, textColor, buf, strlen(buf),
+		    W_RegularFont);
+    }
+}				/* end of print_planet */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/planets.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,481 @@
+/* $Id: planets.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/*
+ * planets.c
+ *
+ * Kevin P. Smith  2/21/89
+ *
+ * This file contains the galaxy definition as well as some support for
+ *  determining when parts of the galactic map need to be redrawn.
+ */
+#include "copyright2.h"
+
+#include <stdio.h>
+#include <math.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+/* define to get profiling info, to better set DEPTH and DETAIL [BDyess] */
+/*#define PROFILE1		/* maxdepth printed */
+/*#define PROFILE2		/* every PLREDRAW setting printed (VERBOSE) */
+
+/* Note:  DETAIL * MUST * be a factor of GWIDTH. */
+#define DETAIL 80		/* Size of redraw array */
+#define RADIUS 2		/* number of adjacent cells to register in */
+#define SIZE 2500
+#define DEPTH 8
+#ifdef PROFILE1
+#define ADDPLANET(i,j,k) { \
+    for(z=0;z<DEPTH;z++) { \
+	if(redraws[i][j][z] == (char)-1) { \
+	    redraws[i][j][z] = k; \
+	    break; \
+	} \
+    }  z++; \
+    if(z > maxdepth) maxdepth = z; \
+}
+#else				/* not PROFILEing */
+#define ADDPLANET(i,j,k) { \
+    for(z=0;z<DEPTH;z++) { \
+	if(redraws[i][j][z] == (char)-1) { \
+	    redraws[i][j][z]=k; \
+	    break; \
+	} \
+    } \
+}
+#endif				/* PROFILE1 */
+
+#define LEFT 	1		/* position flags for corner guessing */
+#define RIGHT 	2
+#define TOP 	4
+#define BOTTOM	8
+
+struct _star {
+    int     s_x, s_y;
+    int     s_color;
+};
+
+static void redrawStarSector P((struct _star star_sector[16]));
+
+/*
+   planets may be on top of each other or very close, so more than one planet
+   can exist in a given block.  The 3rd dimension is for a list of planets.
+   [BDyess]
+*/
+char    redraws[DETAIL][DETAIL][DEPTH];
+static int initialized = 0;
+
+/*
+   since planets may be moved, the redraw matrix must be updated.  This
+   function is for updating just one planet.  This should help the moving
+   planet efficiency problems quite a bit.  [BDyess]
+*/
+void
+initOnePlanet(pl)
+    struct planet *pl;
+{
+}
+
+/*
+   rewritten to repair UNBELIEVABLE inefficiencies in the original [BDyess]
+*/
+void
+initPlanets()
+{
+    register int i, j, k, x, y, z, r, s;
+    struct planet *pl;
+#ifdef PROFILE1
+    int     maxdepth = 0;
+#endif				/* PROFILE1 */
+
+    /* initialize lookup array */
+    for (i = 0; i < DETAIL; i++) {
+	for (j = 0; j < DETAIL; j++) {
+	    for (k = 0; k < DEPTH; k++) {
+		redraws[i][j][k] = -1;
+	    }
+	}
+    }
+
+    /*
+       check all the planets.  If part of the planet falls inside a box in
+       the lookup array, add it to the refresh list for that box.  [BDyess]
+    */
+    for (k = 0, pl = planets; k < nplanets; k++, pl++) {
+	x = pl->pl_x;
+	y = pl->pl_y;
+	i = x / SIZE - 3;
+	j = y / SIZE - 2;
+	/*
+	   fill cells around the target cell with the planetnum like so: ****
+	
+	**
+	
+	x** ****
+	
+	**
+	
+	**	taller than wide because of text ****
+	
+	[BDyess]
+	*/
+	for (r = 0; r < 5; r++) {
+	    i++;
+	    if (i <= 0)
+		continue;
+	    if (i >= DETAIL)
+		break;
+	    for (s = 0; s < 7; s++) {
+		j += s;
+		if (j <= 0)
+		    continue;
+		if (j >= DETAIL)
+		    break;
+		ADDPLANET(i, j, k)
+		    j -= s;
+	    }
+	}
+#if 0				/* this works, and allows the radius around
+				   the hot spot to be changed. It's disabled
+				   because a less-flexible piece of code
+				   (above) is a bit faster.  Plus, it's hard
+				   to generalize about that extra added
+				   lines.  [BDyess] */
+	ADDPLANET(i, j, k)
+	    for (r = 1; r <= RADIUS; r++) {
+	    /* draw box sides in all four directions */
+	    /* bottom */
+	    i += r;
+	    ADDPLANET(i, j, k)
+		for (s = 1; s <= r; s++) {
+		j += s;
+		ADDPLANET(i, j, k)
+		    j -= 2 * s;
+		ADDPLANET(i, j, k)
+		    j += s;
+	    }
+	    /* top */
+	    i -= 2 * r;
+	    ADDPLANET(i, j, k)
+		for (s = 1; s <= r; s++) {
+		j += s;
+		ADDPLANET(i, j, k)
+		    j -= 2 * s;
+		ADDPLANET(i, j, k)
+		    j += s;
+	    }
+	    /* left */
+	    i += r;
+	    j += r;
+	    ADDPLANET(i, j, k)
+		for (s = 1; s < r; s++) {
+		i += s;
+		ADDPLANET(i, j, k)
+		    i -= 2 * s;
+		ADDPLANET(i, j, k)
+		    i += s;
+	    }
+	    /* right */
+	    j -= 2 * r;
+	    ADDPLANET(i, j, k)
+		for (s = 1; s < r; s++) {
+		i += s;
+		ADDPLANET(i, j, k)
+		    i -= 2 * s;
+		ADDPLANET(i, j, k)
+		    i += s;
+	    }
+	}
+#endif				/* 0 */
+    }
+    initialized = 1;
+#ifdef PROFILE1
+    printf("max depth = %d\n", maxdepth);
+#endif				/* PROFILE1 */
+}
+
+void
+checkRedraw(x, y)
+    int     x, y;
+{
+    int     j;
+    char    i;
+
+    if (!initialized || x < 0 || y < 0 || x >= blk_gwidth || y >= blk_gwidth)
+	return;
+    x /= SIZE;
+    y /= SIZE;
+    for (j = 0; j < DEPTH; j++) {
+	i = redraws[x][y][j];
+	if (i == (char) -1)
+	    return;
+	planets[i].pl_flags |= PLREDRAW;
+#ifdef PROFILE2
+	printf("setting PLREDRAW flag for %s\n", planets[i].pl_name);
+#endif				/* PROFILE2 */
+    }
+}
+
+
+/* NOTE: this has been rewritten -- see below */
+
+#define NUMSTARS 1600
+
+static int starsX[NUMSTARS];
+static int starsY[NUMSTARS];
+
+void
+_initStars()
+{
+    register int i;
+
+    for (i = 0; i < NUMSTARS; i++) {
+	starsX[i] = (i % 40) * 5000 + random() % 5000;
+	starsY[i] = (i / 40) * 5000 + random() % 5000;
+    }
+}
+
+void
+_drawStars()
+{
+    int     i;
+    int     x, y;
+
+    for (i = 0; i < NUMSTARS; i++) {
+	x = starsX[i] - me->p_x;
+	y = starsY[i] - me->p_y;
+	if (ABS(x) < 10000 && ABS(y) < 10000) {
+	    x = x / SCALE + WINSIDE / 2;
+	    y = y / SCALE + WINSIDE / 2;
+	    W_DrawPoint(w, x, y, W_White);
+	    W_CacheClearArea(w, x, y, 1, 1);
+	}
+    }
+}
+
+/*
+ *  This rewrite improves drawStars() by a factor of about 30 (according to
+ *  gprof)
+ */
+
+/* blk_gwidth/(WINSIDE * SCALE) == 10 for blk_gwidth == 200000 */
+static struct _star stars[10][10][16];
+
+void
+initStars()
+{
+    register int i, j, k;
+
+    for (i = 0; i < 10; i++) {
+	for (j = 0; j < 10; j++) {
+	    for (k = 0; k < 16; k++) {
+		stars[i][j][k].s_x = i * (WINSIDE * SCALE) + random() % (WINSIDE * SCALE);
+		stars[i][j][k].s_y = j * (WINSIDE * SCALE) + random() % (WINSIDE * SCALE);
+		stars[i][j][k].s_color = randcolor();
+	    }
+	}
+    }
+}
+
+int
+randcolor()
+{
+    switch (random() % 10) {
+	case 0:return W_Yellow;
+    case 1:
+	return W_Red;
+    case 2:
+	return W_Green;
+    case 3:
+	return W_Cyan;
+    default:
+	return W_White;
+    }
+}
+
+void
+drawStars()
+{
+    /*
+       note: cpp symbols in expressions (WINSIDE*SCALE) will be precalculated
+       by any C optimizer
+    */
+    int     sectorx = me->p_x / (WINSIDE * SCALE), sectory = me->p_y / (WINSIDE * SCALE);
+    int     sector_offx = me->p_x - sectorx * (WINSIDE * SCALE), sector_offy = me->p_y - sectory * (WINSIDE * SCALE);
+    int     l = 0, r = 0, t = 0, b = 0;
+
+    if (sector_offx < 0) {	/* goddamn rounding towards 0 */
+	sectorx--;
+	sector_offx += WINSIDE * SCALE;
+    }
+    if (sector_offy < 0) {	/* goddamn rounding towards 0 */
+	sectory--;
+	sector_offy += WINSIDE * SCALE;
+    }
+#define	MAXSECTOR	(blk_gwidth/(WINSIDE*SCALE))
+
+    /* at worst we have to redraw 4 star sectors */
+
+    /* draw the one we're in */
+    /*
+       check first to make sure it's valid.  This is mainly important for if
+       it tries to redraw and we're already dead
+    */
+    if (sectorx < 0 || sectory < 0)
+	return;
+
+    l = sector_offx < (WINSIDE * SCALE) / 2 && sectorx > 0;
+    r = sector_offx > (WINSIDE * SCALE) / 2 && sectorx + 1 < MAXSECTOR;
+    t = sector_offy < (WINSIDE * SCALE) / 2 && sectory > 0;
+    b = sector_offy > (WINSIDE * SCALE) / 2 && sectory + 1 < MAXSECTOR;
+
+    if (t) {
+	if (l)			/* redraw upper-left sector */
+	    redrawStarSector(stars[sectorx - 1][sectory - 1]);
+
+	/* redraw upper sector */
+	redrawStarSector(stars[sectorx][sectory - 1]);
+
+	if (r)			/* redraw upper-right sector */
+	    redrawStarSector(stars[sectorx + 1][sectory - 1]);
+    }
+    if (l)			/* redraw left sector */
+	redrawStarSector(stars[sectorx - 1][sectory]);
+
+    /* redraw center sector */
+    redrawStarSector(stars[sectorx][sectory]);
+
+    if (r)			/* redraw right sector */
+	redrawStarSector(stars[sectorx + 1][sectory]);
+
+    if (b) {
+	if (l)			/* redraw bottom-left sector */
+	    redrawStarSector(stars[sectorx - 1][sectory + 1]);
+
+	/* redraw bottom sector */
+	redrawStarSector(stars[sectorx][sectory + 1]);
+
+	if (r)			/* redraw bottom-right sector */
+	    redrawStarSector(stars[sectorx + 1][sectory + 1]);
+    }
+    W_FlushPointCaches(w);
+}
+
+static void
+redrawStarSector(star_sector)
+    struct _star star_sector[16];
+{
+    register i, dx, dy, dxx, dyy;
+    register struct _star *s;
+    static int warpflag = 0;	/* assume starting out not in warp */
+    static int streaksOn = 0, lastspeed = 0, lastsubspeed = 0, updates = 0;
+    static int streaklength = 1;
+
+    if (warpStreaks) {
+	if (warpflag != (me->p_flags & PFWARP)) {	/* change in warp state */
+	    streaksOn = 1;
+	    warpflag = (me->p_flags & PFWARP);
+	}
+	if (streaksOn) {
+	    if (warpflag && (me->p_speed < lastspeed ||
+	    (me->p_speed == lastspeed && me->p_subspeed <= lastsubspeed))) {
+		/* finished accelerating */
+		updates++;
+		if (updates > 5) {
+		    lastspeed = me->p_speed;
+		    lastsubspeed = me->p_subspeed;
+		    updates = 0;
+		    streaksOn = 0;
+		    redrawStarSector(star_sector);
+		    return;
+		}
+	    } else if (streaklength == 1 || (!warpflag && ((me->p_speed > lastspeed) ||
+	    (me->p_speed == lastspeed && me->p_subspeed >= lastsubspeed)))) {
+		/* finished decelerating */
+		updates++;
+		if (updates > 5) {
+		    lastspeed = me->p_speed;
+		    lastsubspeed = me->p_subspeed;
+		    updates = 0;
+		    streaksOn = 0;
+		    streaklength = 1;
+		    redrawStarSector(star_sector);
+		    return;
+		}
+	    } else
+		updates = 0;
+	    lastspeed = me->p_speed;
+	    lastsubspeed = me->p_subspeed;
+	    /* draw the streaks */
+	    if (warpflag)
+		streaklength += 3;
+	    else
+		streaklength--;
+	    dxx = (int) (Cos[me->p_dir] * streaklength);
+	    dyy = (int) (Sin[me->p_dir] * streaklength);
+	    for (i = 0, s = star_sector; i < 16; i++, s++) {
+		dx = s->s_x - me->p_x;
+		dy = s->s_y - me->p_y;
+		if (ABS(dx) > (SCALE * WINSIDE / 2) || ABS(dy) > (SCALE * WINSIDE / 2))
+		    continue;
+
+		dx = dx / SCALE + WINSIDE / 2;
+		dy = dy / SCALE + WINSIDE / 2;
+		W_CacheLine(w, dx, dy, dx - dxx, dy - dyy, s->s_color);
+
+		clearline[0][clearlcount] = dx;
+		clearline[1][clearlcount] = dy;
+		clearline[2][clearlcount] = dx - dxx;
+		clearline[3][clearlcount] = dy - dyy;
+		clearlcount++;
+	    }
+	    return;
+	}
+    }
+    for (i = 0, s = star_sector; i < 16; i++, s++) {
+	dx = s->s_x - me->p_x;
+	dy = s->s_y - me->p_y;
+	if (ABS(dx) > (SCALE * WINSIDE / 2) || ABS(dy) > (SCALE * WINSIDE / 2))
+	    continue;
+
+	dx = dx / SCALE + WINSIDE / 2;
+	dy = dy / SCALE + WINSIDE / 2;
+	W_CachePoint(w, dx, dy, s->s_color);
+#ifndef AMIGA
+	/*
+	   this is a minor kludge: as long as there are less then 128 stars
+	   in a sector these cached requests will not actually be written to
+	   the X server until the next redraw cycle begins.
+	*/
+	W_CacheClearArea(w, dx, dy, 1, 1);
+#else
+	clearline[0][clearlcount] = dx;
+	clearline[1][clearlcount] = dy;
+	clearline[2][clearlcount] = dx;
+	clearline[3][clearlcount] = dy;
+	clearlcount++;
+#endif
+    }
+}
+
+#if 0
+void
+clearStars()
+{
+    int     i;
+    int     x, y;
+
+    for (i = 0; i < NUMSTARS; i++) {
+	x = starsX[i] - me->p_x;
+	y = starsY[i] - me->p_y;
+	if (ABS(x) < 10000 && ABS(y) < 10000) {
+	    x = x / SCALE + WINSIDE / 2;
+	    y = y / SCALE + WINSIDE / 2;
+	    W_CacheClearArea(w, x, y, 1, 1);
+	}
+    }
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/playerlist.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,518 @@
+/* $Id: playerlist.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/*
+ * playerlist.c
+ * modified to sort by teams by Bill Dyess on 9/23/93
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "gameconf.h"
+#include "packets.h"
+
+/* Prototypes */
+static void dofulllist P((struct player * pptr, int vpos));
+/* static char *get_players_rank_name P((struct player *j));*/
+void getdesig P((struct player * j, char *desig));
+
+struct teamstruct {
+    short   teamnum;
+    short   totalnum;
+    short   outfitnum;
+    short   row;
+    short   outfitrow;
+};
+
+int     lastsortPlayers, lasthnk, lastspl, lastshowDead;
+
+void
+playerlist()
+{
+    int     i;
+    char    buf[100];
+
+    if (slot == NULL) {
+	if ((slot = (short *) malloc(sizeof(short) * 33)) == NULL) {
+	    perror("out of memory?!?\n");
+	    exit(-1);
+	}
+    }
+    if (*playerList != 0 && *playerList != ',') {	/* do the wide thing
+							   [BDyess] */
+	wideplayerlist();
+	return;
+    }
+    for (i = 0; i < 33; i++)
+	slot[i] = -2;
+    lastsortPlayers = sortPlayers;
+    lasthnk = hideNoKills;
+    lastspl = showPreLogins;
+    lastshowDead = showDead;
+
+    W_ClearWindow(playerw);
+
+    (void) strcpy(buf, "  Type Rank      Name            Kills        Type Rank      Name            Kills");
+    W_WriteText(playerw, 0, 1, textColor, buf, strlen(buf), W_RegularFont);
+
+    if (!paradise)
+	(void) strcpy(buf, "  Type Rank      Name            Kills   Win  Loss  Ratio Offense Defense     DI");
+    else
+	(void) strcpy(buf, "  Type Rank      Name            Kills   Win  Loss  Ratio  Battle Strategy     DI");
+
+    W_WriteText(playerw, 0, 20, textColor, buf, strlen(buf), W_RegularFont);
+
+    for (i = 0; i < nplayers; i++)
+	updatePlayer[i] |= ALL_UPDATE;
+
+    playerlist2();
+}
+
+
+void
+playerlist2()
+{
+    register int i, k, z;
+    char    buf[100];
+    short   extra = 0, outfitextra = 0;
+    struct teamstruct teams[4];
+    struct teamstruct *quadrant[4], *tempquad;	/* topleft, topright,
+						   bottomleft, bottomright */
+    register struct player *j;
+    static short sequentialSort = 0;
+    char   *rname;
+    char    desig[3];
+    short   currentSlot;
+    static int usingWide = 0;
+
+    if (*playerList != 0 && *playerList != ',') {	/* do the wide thing
+							   [BDyess] */
+	if (slot == NULL) {
+	    playerlist();
+	    return;
+	}
+	wideplayerlist2();
+	usingWide = 1;
+	return;
+    }
+    /* keeps the playerlist from being drawn when not allowed [BDyess] */
+    if (!allowPlayerlist)
+	return;
+
+    if (slot == NULL || lastsortPlayers != sortPlayers ||
+	lasthnk != hideNoKills ||
+	lastspl != showPreLogins ||
+	lastshowDead != showDead ||
+	usingWide) {
+	usingWide = 0;
+        if(resizePlayerList)
+            W_ResizeText(playerw,83,W_WindowHeight(playerw));
+	playerlist();
+	return;
+    }
+    if (!W_IsMapped(playerw))
+	return;
+    if (updatePlayer[me->p_no] & LARGE_UPDATE)
+	dofulllist(me, 21);
+    if (blk_bozolist >= 0)
+	if (updatePlayer[blk_bozolist] & LARGE_UPDATE)
+	    dofulllist(&players[blk_bozolist], 22);
+    /*
+       if sortPlayers is on: the players team goes in the top left (top right
+       if robSort: on), the next-largest team in the top right, the third
+       largest in the bottom left, and everything else in the bottom right
+    */
+    if (sortPlayers) {
+	bzero(teams, sizeof(teams));
+	for (i = 0; i < 4; i++)
+	    teams[i].teamnum = i;
+	/* figure out how many players on each team */
+	for (i = 0, j = &players[i]; i < nplayers; i++, j++) {
+	    if (j->p_status != PFREE && !(j->p_status == POUTFIT && j->p_teami < 0)) {
+		if (j->p_teami < 0 || j->p_teami == number_of_teams) {
+		    if (!showDead)
+			continue;
+		    extra++;
+		    if (j->p_status == POUTFIT && sortOutfitting)
+			outfitextra++;
+		} else if (j->p_teami == number_of_teams) {
+		    if (!showPreLogins)
+			continue;
+		    extra++;
+		    if (j->p_status == POUTFIT && sortOutfitting)
+			outfitextra++;
+		} else {
+		    teams[j->p_teami].totalnum++;
+		    if (j->p_status == POUTFIT && showDead && sortOutfitting)
+			teams[j->p_teami].outfitnum++;
+		}
+	    }
+	    /*
+	       printf("player %d is on team %d with status %d\n",
+	       i,j->p_teami,j->p_status);
+	    */
+	}
+
+	for (i = 0; i < 4; i++)
+	    quadrant[i] = &teams[i];
+	if (me->p_teami >= 0 && me->p_teami < number_of_teams)
+	    teams[me->p_teami].totalnum += 10000;
+	for (i = 3; i > 0; i--) {
+	    for (k = 0; k < i; k++) {
+		if (quadrant[k]->totalnum < quadrant[k + 1]->totalnum) {
+		    tempquad = quadrant[k];
+		    quadrant[k] = quadrant[k + 1];
+		    quadrant[k + 1] = tempquad;
+		}
+	    }
+	}
+	if (me->p_teami >= 0 && me->p_teami < number_of_teams) {
+	    teams[me->p_teami].totalnum -= 10000;
+	    if (robsort) {
+		quadrant[0] = quadrant[1];
+		quadrant[1] = &teams[me->p_teami];
+	    }
+	}
+	quadrant[3]->totalnum += extra;
+	quadrant[3]->outfitnum += outfitextra;
+
+	if (quadrant[0]->totalnum > 16 || quadrant[1]->totalnum > 16) {
+	    /*
+	       if one team is so huge as to not fit on just one side, then
+	       just list all the players sequentially, but still team sorted.
+	       For now, set a flag and clear any freshly empty space.
+	    */
+	    if (sequentialSort == 0) {
+		sequentialSort = 1;
+		playerlist();
+		return;
+	    }
+	    quadrant[0]->row = 0;
+	    quadrant[1]->row = quadrant[0]->totalnum;
+	    quadrant[2]->row = quadrant[1]->row + quadrant[1]->totalnum;
+	    quadrant[3]->row = quadrant[2]->row + quadrant[2]->totalnum;
+	    /* wipe out the blank sections */
+	    for (i = quadrant[3]->row + quadrant[3]->totalnum; i < 32; i++) {
+		if (slot[i] != -1) {
+		    /*
+		       if we get here, it's not possible to have players
+		       blank on the left side
+		    */
+		    W_ClearArea(playerw, 44, i - 16 + 1, 41, 1);
+		    slot[i] = -1;
+		}
+	    }
+	} else {
+	    if (sequentialSort == 1) {
+		sequentialSort = 0;
+		playerlist();
+		return;
+	    }
+	    quadrant[0]->row = quadrant[1]->row = 2;
+	    if (quadrant[0]->totalnum + quadrant[2]->totalnum <= 16) {
+		quadrant[2]->row = 18 - quadrant[2]->totalnum;
+	    } else {
+		quadrant[2]->row = 2 + quadrant[0]->totalnum;
+		quadrant[3]->totalnum += quadrant[0]->totalnum + quadrant[2]->totalnum - 16;
+	    }
+	    if (quadrant[1]->totalnum + quadrant[3]->totalnum <= 16) {
+		quadrant[3]->row = 18 - quadrant[3]->totalnum;
+	    } else {
+		quadrant[3]->row = 2 + quadrant[1]->totalnum;
+		quadrant[2]->row -= quadrant[1]->totalnum + quadrant[3]->totalnum - 16;
+	    }
+
+	    for (i = 0; i < 4; i++)
+		quadrant[i]->outfitrow = quadrant[i]->row + quadrant[i]->totalnum -
+		    quadrant[i]->outfitnum;
+	    /* wipe out the blank sections */
+	    for (i = 2 + quadrant[0]->totalnum; i < quadrant[2]->row; i++) {
+		if (slot[i - 2] != -1 || players[slot[i - 2]].p_status != POUTFIT) {
+		    W_ClearArea(playerw, 0, i, 41, 1);
+		    slot[i - 2] = -1;
+		}
+	    }
+	    for (i = 2 + quadrant[1]->totalnum; i < quadrant[3]->row; i++) {
+		if (slot[16 + i - 2] != -1) {
+		    W_ClearArea(playerw, 44, i, 41, 1);
+		    slot[16 + i - 2] = -1;
+		}
+	    }
+	}
+    }
+    /* update the display for each player */
+    for (i = 0, j = &players[i]; i < nplayers; i++, j++) {
+
+	if (!updatePlayer[i] && !sortPlayers && slot[i] == j->p_no)
+	    continue;
+
+	getdesig(j, desig);
+	if (!desig[0]) {
+	    if (!sortPlayers)
+		W_ClearArea(playerw, (i > 15) ? 44 : 0, (i > 15) ? i - 16 + 2 : i + 2, 41, 1);
+	    continue;		/* don't display this guy, he's toast */
+	}
+	rname = get_players_rank_name(j);
+	(void) sprintf(buf, "%c%c %2.2s  %-9.9s %-15.15s",
+		       teaminfo[j->p_teami].letter,
+		       shipnos[j->p_no],
+		       desig,
+		       rname,
+		       j->p_name);
+	/*
+	   replace 0.00 kills with spaces if not alive and paradise or not
+	   RSA
+	*/
+	/* this is optional with the hideNoKills option 	                     */
+	if ((j->p_kills <= 0 &&
+	     (paradise || RSA_Client <= 0) && hideNoKills)
+	    || (j->p_status & ~PALIVE))
+	    strcat(buf, "      ");
+	else
+	    sprintf(buf + strlen(buf), "%6.2f", j->p_kills);
+	if (!sortPlayers) {
+#ifdef PLPROF
+	    printf("Updating player %d\n", j->p_no);
+#endif				/* PLPROF */
+	    W_WriteText(playerw, (i > 15) ? 44 : 0,
+			(i > 15) ? i - 16 + 2 : i + 2, playerColor(j), buf,
+			strlen(buf), shipFont(j));
+	    slot[i] = j->p_no;
+	} else if (!sequentialSort) {
+	    /* find out which quadrant he should be in */
+	    for (z = 0; j->p_teami != quadrant[z]->teamnum && z < 3; z++);
+	    if (j->p_status == POUTFIT && sortOutfitting)
+		k = quadrant[z]->outfitrow++ - quadrant[z]->row;
+	    else
+		k = 0;
+	    if (quadrant[z]->row + k > 18) {
+		z += 1;
+		if (z > 3)
+		    z -= 2;
+	    }
+	    currentSlot = (z % 2) * 16 + quadrant[z]->row - 2 + k;
+	    if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) {
+		slot[currentSlot] = j->p_no;
+#ifdef PLPROF
+		printf("Updating %d, currentslot = %d, updatePlayer = %d\n",
+		       j->p_no, currentSlot, updatePlayer[j->p_no]);
+#endif				/* PLPROF */
+		W_WriteText(playerw, 44 * (z % 2), k + quadrant[z]->row,
+			    playerColor(j), buf, strlen(buf), shipFont(j));
+	    }
+	    if (!k)
+		quadrant[z]->row++;
+	} else {		/* do sequential sort placement */
+	    /* find out which quadrant he should be in */
+	    for (z = 0; j->p_teami != quadrant[z]->teamnum && z < 3; z++);
+	    currentSlot = quadrant[z]->row++;
+	    if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) {
+		if (currentSlot >= 16) {
+		    W_WriteText(playerw, 44, currentSlot - 16 + 2, playerColor(j),
+				buf, strlen(buf), shipFont(j));
+		} else {
+		    W_WriteText(playerw, 0, currentSlot + 2, playerColor(j), buf,
+				strlen(buf), shipFont(j));
+		}
+	    }
+	}
+
+#if 0
+	if (slot[currentSlot] != j->p_no || updatePlayer[j->p_no] & SMALL_UPDATE) {
+	    slot[currentSlot] = j->p_no;
+#ifdef PLPROF
+	    printf("Updating %d\n", j->p_no);
+#endif				/* PLPROF */
+	    W_WriteText(playerw, currentSlot >= 16 ? 44 : 0,
+		 currentSlot >= 16 ? currentSlot + 2 - 16 : currentSlot + 2,
+			playerColor(j), buf, strlen(buf), shipFont(j));
+	}
+    }
+#endif				/* 0 */
+    updatePlayer[j->p_no] = NO_UPDATE;
+}
+}
+
+void
+getdesig(j, desig)
+    struct player *j;
+    char   *desig;
+{
+    switch (j->p_status) {
+    case PALIVE:
+        strncpy(desig, j->p_ship->s_desig, 2);
+        j->p_ship->s_desig[2] = 0;
+	break;
+    case PTQUEUE:
+	strcpy(desig, "tq");
+	break;
+    case POUTFIT:
+	if ((j->p_teami < 0) || !showDead)
+	    desig[0] = 0;
+	else
+	    strcpy(desig, "--");
+	break;
+    case PEXPLODE:
+    case PDEAD:
+	if (showDead)
+	    strcpy(desig, "**");
+	else
+	    desig[0] = 0;
+	break;
+    case POBSERVE:
+	strcpy(desig, "ob");
+	break;
+    default:
+	desig[0] = 0;
+	break;
+    }
+    /*
+       if (!*desig) j->p_teami = -1;
+    */
+    if (j->p_teami == number_of_teams && !showPreLogins)
+	desig[0] = 0;
+}
+
+static void
+dofulllist(pptr, vpos)
+    struct player *pptr;
+    int     vpos;
+{
+    char    buf[100];
+    char   *rname;
+    char    desig[3];
+    struct ratings r;
+
+    if (!W_IsMapped(playerw))
+	return;
+
+    getdesig(pptr, desig);
+    if (!desig[0]) {
+	if (pptr->p_no == blk_bozolist)
+	    blk_bozolist = -1;
+	W_ClearArea(playerw, 0, vpos, 83, 1);
+	return;
+    }
+    get_ratings(pptr, &r);
+
+    rname = get_players_rank_name(pptr);
+    if (!paradise)
+	sprintf(buf, "%c%c %2.2s  %-9.9s %-16.16s%5.2f %5d %5d %6.2f   %5.2f   %5.2f %8.2f  ",
+		teaminfo[pptr->p_teami].letter,
+		shipnos[pptr->p_no],
+		desig /* pptr->p_ship->s_desig */ ,
+		rname,
+		pptr->p_name,
+		pptr->p_kills,
+		r.r_kills,
+		r.r_losses,
+		r.r_ratio,
+		r.r_offrat,
+		r.r_defrat,
+		r.r_di);
+    else
+	sprintf(buf, "%c%c %2.2s  %-9.9s %-16.16s%5.2f %5d %5d %6.2f   %5.2f   %5.2f %8.2f  ",
+		teaminfo[pptr->p_teami].letter,
+		shipnos[pptr->p_no],
+		desig /* pptr->p_ship->s_desig */ ,
+		rname,
+		pptr->p_name,
+		pptr->p_kills,
+		r.r_kills,
+		r.r_losses,
+		r.r_ratio,
+		r.r_batrat,
+		r.r_stratrat,
+		r.r_di);
+
+#ifdef PLPROF
+    printf("Updating %d\n", pptr->p_no);
+#endif				/* PLPROF */
+    W_WriteText(playerw, 0, vpos, playerColor(pptr), buf, strlen(buf),
+		shipFont(pptr));
+}
+
+char   *
+get_players_rank_name(j)
+    struct player *j;
+{
+    char   *r;
+    if (j->p_stats.st_rank < 0)
+	j->p_stats.st_rank = 0;
+    if (!paradise) {
+	r = ranks[j->p_stats.st_rank].name;
+    } else {
+	if (j->p_stats2.st_royal == 0)
+	    r = ranks2[j->p_stats2.st_rank].name;
+	else
+	    r = royal[j->p_stats2.st_royal].name;
+    }
+    return (r);
+}
+
+void
+playerwEvent(data)
+    W_Event *data;
+{
+    int     key;
+    struct obtype *target;
+
+    key = doKeymap(data);
+    if (key == -1)
+	return;
+    switch (key) {
+    case 'l':			/* lock on [BDyess] */
+	target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
+	sendPlaylockReq(target->o_num);
+	me->p_playerl = target->o_num;
+	break;
+    case 'i':
+    case 'I':
+	if (!infomapped)
+	    inform(data->Window, data->x, data->y, key);
+	else
+	    destroyInfo();
+	break;
+    case 'X':
+	macroState = 1;
+	warning("Macro mode");
+	break;
+    default:
+	warning("Invalid key");
+    }
+}
+
+void
+selectblkbozo(data)
+    W_Event *data;
+{
+    int     width, slotnum;
+
+    if (*playerList
+	&& *playerList != ',')
+	return;
+    width = W_WindowWidth(data->Window);
+    if (data->key == W_RBUTTON || data->key == W_LBUTTON || data->key == W_MBUTTON)
+	if (data->y > W_Textheight * 2 + 1 && data->y < W_Textheight * 19) {
+	    W_TranslatePoints(data->Window, &data->x, &data->y);
+	    slotnum = 0;
+	    if (data->x > width / 2)
+		slotnum += 16;
+	    /* only look for players in the slotspace */
+	    if (data->y <= (16 + 1)) {
+		slotnum += data->y - 2;
+		if (slot[slotnum] != me->p_no)
+		    blk_bozolist = slot[slotnum];
+		if (blk_bozolist >= 0) {
+		    updatePlayer[blk_bozolist] |= LARGE_UPDATE;
+		} else {
+		    blk_bozolist = -1;
+		    W_ClearArea(playerw, 0, 22, 83, 1);
+		}
+	    }
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/proto.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,312 @@
+/* $Id: proto.h,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+#ifndef proto_h_
+#define proto_h_
+
+#ifndef P
+#ifdef __STDC__
+#define P(s) s
+#else
+#define P(s) ()
+#endif
+#endif
+
+#include <stdio.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include "Wlib.h"
+#include "struct.h"
+
+/* autokey.c */
+int setAutoKeyOn P((void));
+int setAutoKeyOff P((void));
+void autoKeyDefaults P((void));
+int doAutoKey P((void));
+int autoKeyAllOff P((void));
+int autoKeyOff P((W_Event * data));
+int autoKeyTorpOn P((void));
+int autoKeyTorpReqOn P((void));
+int autoKeyPhaserOn P((void));
+int autoKeyPhaserReqOn P((void));
+int autoKeyDetOn P((void));
+int autoKeyDetReqOn P((void));
+int autoKeyPlasmaReqOn P((void));
+int autoKeyBombReqOn P((void));
+int autoKeyBeamUpReqOn P((void));
+int autoKeyBeamDownReqOn P((void));
+int autoKeyOrbitReqOn P((void));
+
+/* beeplite.c */
+void litedefaults P((void));
+void rcdlite P((struct distress *));
+
+/* blk_parsemotd.c */
+void blk_parsemotd P((char *line));
+
+/* colors.c */
+void getColorDefs P((void));
+
+/* data.c */
+
+/* dashboard.c */
+void stline P((int flag));
+void redrawTstats P((void));
+void light_send P((void));
+void light_receive P((void));
+
+/* death.c */
+void death P((void));
+
+/* defaults.c */
+char   *initDefaults P((char *deffile));
+char   *getdefault P((char *str));
+char   *stringDefault P((char *str, char *preferred));
+int booleanDefault P((char *def, int preferred));
+int intDefault P((char *def, int preferred));
+int defaultShip P((int preferred));
+void resetDefaults P((void));
+char   *expandFilename P((char *));
+
+/* detonate.c */
+void detmine P((void));
+
+/* distress.c */
+int testmacro P((char *, char *, int *, int *));
+int condmacro P((char *, char *, int *, int *, int));
+int solvetest P((char *, int *));
+int skipmacro P((char [], int));
+int makedistress P((struct distress *, char *, char *));
+
+/* dmessage.c */
+void dmessage P((char *message, unsigned int flags, unsigned int from, unsigned int to));
+void logit P((char *message));
+void sendVersion P((void));
+
+/* enter.c */
+void enter P((void));
+void openmem P((void));
+
+/* findslot.c */
+int findslot P((void));
+
+/* getname.c */
+void getname P((char *defname, char *defpasswd));
+
+/* getship.c */
+void init_shiptypes P((void));
+struct ship *getship P((int s_type));
+void init_galaxy_class P((void));
+
+/* helpwin.c */
+void fillhelp P((void));
+
+/* inform.c */
+void inform P((W_Window ww, int x, int y, int key));
+void destroyInfo P((void));
+
+/* input.c */
+void initinput P((void));
+void input P((void));
+int getcourse P((W_Window ww, int x, int y));
+
+/* interface.c */
+void set_speed P((int speed));
+void set_course P((unsigned int dir));
+void shield_up P((void));
+void shield_down P((void));
+void shield_tog P((void));
+void bomb_planet P((void));
+void beam_up P((void));
+void beam_down P((void));
+void repair P((void));
+void repair_off P((void));
+void repeat_message P((void));
+void cloak P((void));
+void cloak_on P((void));
+void cloak_off P((void));
+int mtime P((void));
+
+/* keymap.c */
+void buildShipKeymap P((struct ship * shipp));
+void initkeymap P((int type));
+void keymapAdd P((char *str, char *map));
+void ckeymapAdd P((char *cstr, char *map));
+void buttonmapAdd P((char *str, char *map));
+void cbuttonmapAdd P((char *cstr, char *map));
+void dumpKeymap P((void));
+
+/* main.c */
+/* doy, this prototype is wholly unecessary */
+/* int main P((int argc, char **argv)); */
+void reaper P((void));
+unsigned long dotAddrToNetAddr P((char *str));
+
+#ifdef MACROS
+/* macros.c */
+void doMacro P((W_Event * data));
+void initMacros P((void));
+
+/* macrowin.c */
+void showMacroWin P((void));
+#endif				/* MACROS */
+
+/* newwin.c */
+void newwin P((char *hostmon, char *progname));
+void mapAll P((void));
+void entrywindow P((int *team, int *s_type));
+int deadTeam P((int owner));
+void erase_motd P((void));
+void newMotdPic P((int x, int y, int width, int height, char *bits, int page));
+void newMotdLine P((char *line));
+void fillhelp P((void));
+void drawIcon P((void));
+void do_refit P((int type));
+void showMotd P((W_Window win));
+
+/* motdwin.c */
+void motdWinEvent P((int));
+void showMotdWin P((void));
+
+/* option.c */
+void optionwindow P((void));
+void optionredrawtarget P((W_Window win));
+void optionredrawoption P((int *ip));
+int optionaction P((W_Event * data));
+void optiondone P((void));
+
+#ifdef METASERVER
+/* parsemeta.c */
+void parsemeta P((void));
+void metawindow P((void));
+void metainput P((void));
+/* void metaaction P((W_Event * data)); */
+#endif				/* METASERVER */
+
+/* planetlist.c */
+void planetlist P((void));
+
+/* planets.c */
+void initPlanets P((void));
+void checkRedraw P((int x, int y));
+void initStars P((void));
+void drawStars P((void));
+void clearStars P((void));
+
+/* playerlist.c */
+void playerlist P((void));
+void playerlist2 P((void));
+struct player;
+char   *get_players_rank_name P((struct player * j));
+void selectblkbozo P((W_Event * data));
+void playerwEvent P((W_Event * data));
+
+/* ranklist.c */
+void ranklist P((void));
+
+/* ratings.c */
+struct ratings *get_ratings P((struct player * s, struct ratings * r));
+
+/* redraw.c */
+struct _clearzone *new_czone P((void));
+
+/* reserved.c */
+int makeReservedPacket P((void *packet));
+int encryptReservedPacket P((void *spacket, void *cpacket, char *server, int pno));
+
+/* shipbitmaps.c */
+void slurp_ship_bitmaps P((void));
+void replace_shipshape P((int, int, int, int, int));
+void replace_ship_bitmaps P((int, int, int, char *));
+
+/* sintab.c */
+void inittrigtables P((void));
+
+/* smessage.c */
+void message_expose P((void));
+void smessage P((int ichar));
+void smessage_ahead P((int head, int ichar));
+void pmessage P((char *str, int recip, int group));
+void emergency P((void));
+void carry_report P((void));
+void message_on P((void));
+void message_off P((void));
+void sendCharMessage P((char *buf, int ch));
+
+/* socket.c */
+void print_totals P((void));
+void connectToServer P((int port));
+void callServer P((int port, char *server));
+int isServerDead P((void));
+void socketPause P((int sec, int usec));
+int readFromServer P((void));
+int readFromServer P((void));
+void sendShortPacket P((int type, int state));
+void sendTeamReq P((int team, int ship));
+void sendLoginReq P((char *name, char *pass, char *login, int query));
+void sendTractorReq P((int state, int pnum));
+void sendRepressReq P((int state, int pnum));
+void sendDetMineReq P((int torp));
+void sendMessage P((char *mes, int group, int indiv));
+void sendOptionsPacket P((void));
+void sendUpdatePacket P((long speed));
+void sendUdpReq P((int req));
+int closeUdpConn P((void));
+short swaps P((int in));
+int mask_to_idx P((int));
+
+/* stats.c */
+void redrawStats P((void));
+void updateStats P((void));
+void calibrate_stats P((void));
+
+/* udpopt.c */
+void udpwindow P((void));
+void udprefresh P((int i));
+void udpaction P((W_Event * data));
+void udpdone P((void));
+
+/* util.c */
+int angdist P((unsigned int x, unsigned int y));
+struct obtype *gettarget P((W_Window ww, int x, int y, int targtype));
+struct id *getTargetID P((W_Window ww, int x, int y, int targtype));
+char   *team_bit_string P((int mask));
+
+/* varydamage.c */
+struct ship_shape;
+void doShields P((int dx, int dy, struct ship_shape * ship_bits, struct player * j));
+void doHull P((int dx, int dy, struct ship_shape * ship_bits, struct player * j));
+
+/* war.c */
+void warwindow P((void));
+void waraction P((W_Event * data));
+
+/* warning.c */
+void warning P((char *text));
+char   *timeString P((time_t time));
+
+/* wide_plist.c */
+void wideplayerlist P((void));
+void wideplayerlist2 P((void));
+
+/* x11window.c */
+int checkMapped P((char *window));
+void W_RenameWindow P((W_Window window, char *str));
+void W_GetEvent P((W_Event * wevent));
+
+#ifdef RECORDER
+/* recorder.c */
+void startRecorder P((void));
+void stopRecorder P((void));
+void recordPacket P((char *data, int len));
+void writeUpdateMarker P((void));
+int startPlayback P((void));
+int readRecorded P((int fp, char *data, int len));
+#endif
+
+#ifdef XTREKRC_HELP
+/* defwin.c */
+void showdef P((void));
+void def_action P((W_Event *ev));
+#endif
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/puck.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,10 @@
+/* $Id: puck.h,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+#define puck_width 20
+#define puck_height 20
+static unsigned char puck_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x07, 0x00, 0xc0, 0x1f, 0x00, 0xe0, 0x3f, 0x00, 0xe0, 0x3f, 0x00,
+   0xf0, 0x7f, 0x00, 0xf0, 0x7f, 0x00, 0xf0, 0x7f, 0x00, 0xe0, 0x3f, 0x00,
+   0xe0, 0x3f, 0x00, 0xc0, 0x1f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rabbitbitmaps.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,142 @@
+/* $Id: rabbitbitmaps.h,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+#define rmyplanet000_width 30
+#define rmyplanet000_height 30
+static unsigned char rmyplanet000_bits[] =
+{
+    0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet001_width 30
+#define rmyplanet001_height 30
+static unsigned char rmyplanet001_bits[] =
+{
+    0x00, 0x18, 0x03, 0x07, 0x00, 0x00, 0x00, 0x05, 0xc0, 0x00, 0x60, 0x07,
+    0x00, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet010_width 30
+#define rmyplanet010_height 30
+static unsigned char rmyplanet010_bits[] =
+{
+    0x1c, 0x18, 0x03, 0x00, 0x14, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x60, 0x00,
+    0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet011_width 30
+#define rmyplanet011_height 30
+static unsigned char rmyplanet011_bits[] =
+{
+    0x1c, 0x18, 0x03, 0x07, 0x14, 0x00, 0x00, 0x05, 0xdc, 0x00, 0x60, 0x07,
+    0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet100_width 30
+#define rmyplanet100_height 30
+static unsigned char rmyplanet100_bits[] =
+{
+    0x00, 0xf8, 0x03, 0x00, 0x00, 0x07, 0x1c, 0x00, 0xc0, 0x00, 0x60, 0x00,
+    0x20, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x02,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet101_width 30
+#define rmyplanet101_height 30
+static unsigned char rmyplanet101_bits[] =
+{
+    0x00, 0xf8, 0x03, 0x07, 0x00, 0x07, 0x1c, 0x05, 0xc0, 0x00, 0x60, 0x07,
+    0x20, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet110_width 30
+#define rmyplanet110_height 30
+static unsigned char rmyplanet110_bits[] =
+{
+    0x1c, 0xf8, 0x03, 0x00, 0x14, 0x07, 0x1c, 0x00, 0xdc, 0x00, 0x60, 0x00,
+    0x10, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmyplanet111_width 30
+#define rmyplanet111_height 30
+static unsigned char rmyplanet111_bits[] =
+{
+    0x1c, 0xf8, 0x03, 0x07, 0x14, 0x07, 0x1c, 0x05, 0xdc, 0x00, 0x60, 0x07,
+    0x10, 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x02, 0x00, 0x00, 0x08,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x10,
+    0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x08,
+    0x04, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0x02,
+    0x10, 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x60, 0x00,
+0x00, 0x07, 0x1c, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00};
+#define rmymplanet011_width 16
+#define rmymplanet011_height 16
+static unsigned char rmymplanet011_bits[] =
+{
+    0xa0, 0x02, 0x08, 0x08, 0x40, 0x01, 0x42, 0x21, 0xc0, 0x01, 0x81, 0x4c,
+    0x80, 0x14, 0x81, 0x54, 0x80, 0x14, 0x81, 0x5c, 0xc0, 0x01, 0x42, 0x21,
+0x40, 0x01, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00};
+#define rmymplanet010_width 16
+#define rmymplanet010_height 16
+static unsigned char rmymplanet010_bits[] =
+{
+    0xa0, 0x02, 0x08, 0x08, 0x40, 0x01, 0x42, 0x21, 0xc0, 0x01, 0x81, 0x40,
+    0x80, 0x00, 0x81, 0x40, 0x80, 0x00, 0x81, 0x40, 0xc0, 0x01, 0x42, 0x21,
+0x40, 0x01, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00};
+#define rmymplanet001_width 16
+#define rmymplanet001_height 16
+static unsigned char rmymplanet001_bits[] =
+{
+    0xa0, 0x02, 0x08, 0x08, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x01, 0x4c,
+    0x00, 0x14, 0x01, 0x54, 0x00, 0x14, 0x01, 0x5c, 0x00, 0x00, 0x02, 0x20,
+0x00, 0x00, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00};
+#define rmymplanet000_width 16
+#define rmymplanet000_height 16
+static unsigned char rmymplanet000_bits[] =
+{
+    0xa0, 0x02, 0x08, 0x08, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x01, 0x40,
+    0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x02, 0x20,
+0x00, 0x00, 0x08, 0x08, 0xa0, 0x02, 0x00, 0x00};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ranklist.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,95 @@
+/* $Id: ranklist.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/*
+ * ranklist.c
+ *
+ * Kevin P. Smith 12/5/88
+ *
+ */
+#include "copyright2.h"
+
+#include <stdio.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+/* Prototypes */
+static void print_ranks_paradise P((void));
+
+
+void
+ranklist()
+{
+    register int i;
+    char    buf[80];
+
+    /*
+       W_ClearWindow(rankw);
+    */
+    if (!paradise) {
+	(void) strcpy(buf, "  Rank       Hours  Defense  Ratings      DI");
+	W_WriteText(rankw, 1, 1, textColor, buf, strlen(buf), W_BoldFont);
+	for (i = 0; i < NUMRANKS; i++) {
+	    sprintf(buf, "%-11.11s %5.0f %8.2f %8.2f   %7.2f",
+		    ranks[i].name,
+		    ranks[i].hours,
+		    ranks[i].defense,
+		    ranks[i].ratings,
+		    ranks[i].ratings * ranks[i].hours);
+	    if (mystats->st_rank == i) {
+		W_WriteText(rankw, 1, i + 2, W_Cyan, buf, strlen(buf), W_BoldFont);
+	    } else {
+		W_WriteText(rankw, 1, i + 2, textColor, buf, strlen(buf),
+			    W_RegularFont);
+	    }
+	}
+	strcpy(buf, "To achieve a rank, you need a high enough defense, and");
+	W_WriteText(rankw, 1, i + 3, textColor, buf, strlen(buf), W_RegularFont);
+	strcpy(buf, "either enough hours, and bombing + planet + offense ratings");
+	W_WriteText(rankw, 1, i + 4, textColor, buf, strlen(buf), W_RegularFont);
+	strcpy(buf, "above shown ratings, or too few hours, and a DI rating above");
+	W_WriteText(rankw, 1, i + 5, textColor, buf, strlen(buf), W_RegularFont);
+	strcpy(buf, "the shown DI rating.");
+	W_WriteText(rankw, 1, i + 6, textColor, buf, strlen(buf), W_RegularFont);
+    } else {			/* else we are in a paradise server */
+	print_ranks_paradise();
+    }
+}
+
+
+
+static void
+print_ranks_paradise()
+{
+    register int i;
+    char    buf[80];
+
+    W_ResizeText(rankw, 65, nranks2 + 8);
+
+    (void) strcpy(buf, "  Rank       genocides  DI    battle strategy  special ships");
+    W_WriteText(rankw, 1, 1, textColor, buf, strlen(buf), W_BoldFont);
+    for (i = 0; i < nranks2; i++) {
+	sprintf(buf, "%-11.11s %5d %8.2f %8.2f %8.2f   %7.2f",
+		ranks2[i].name,
+		ranks2[i].genocides,
+		ranks2[i].di,
+		ranks2[i].battle,
+		ranks2[i].strategy,
+		ranks2[i].specship);
+	if (mystats->st_rank == i) {
+	    W_WriteText(rankw, 1, i + 2, W_Cyan, buf, strlen(buf), W_BoldFont);
+	} else {
+	    W_WriteText(rankw, 1, i + 2, textColor, buf, strlen(buf), W_RegularFont);
+	}
+    }
+    strcpy(buf, "To achieve a rank, you need a high enough number of");
+    W_WriteText(rankw, 1, i + 3, textColor, buf, strlen(buf), W_RegularFont);
+    strcpy(buf, "genocides, a high enough DI, a high enough battle");
+    W_WriteText(rankw, 1, i + 4, textColor, buf, strlen(buf), W_RegularFont);
+    strcpy(buf, "rating, a high enough strategy rating, and a high");
+    W_WriteText(rankw, 1, i + 5, textColor, buf, strlen(buf), W_RegularFont);
+    strcpy(buf, "enough special ship rating");
+    W_WriteText(rankw, 1, i + 6, textColor, buf, strlen(buf), W_RegularFont);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ratings.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,163 @@
+/* $Id: ratings.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/*
+ * ratings.c,  2/13/94 Bill Dyess
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "gameconf.h"
+
+/*
+   fills the ratings struct pointed to by r with the stats for the player
+   pointed to by j [BDyess]
+*/
+struct ratings *
+get_ratings(j, r)
+    struct player *j;
+    struct ratings *r;
+{
+    if (paradise) {
+	struct stats2 *s;	/* point to player's paradise stats */
+	float   t, t2;		/* temps */
+
+	s = &(j->p_stats2);
+	/* fill in kills, losses, and maxkills based on ship type */
+	if (j->p_ship->s_type == STARBASE) {
+	    r->r_kills = s->st_sbkills;
+	    r->r_losses = s->st_sblosses;
+	    r->r_maxkills = s->st_sbmaxkills;
+	} else if (j->p_ship->s_type == WARBASE) {
+	    r->r_kills = s->st_wbkills;
+	    r->r_losses = s->st_wblosses;
+	    r->r_maxkills = s->st_wbmaxkills;
+	} else {
+	    r->r_kills = s->st_tkills;
+	    r->r_losses = s->st_tlosses;
+	    r->r_maxkills = s->st_tmaxkills;
+	}
+	/* calculate ratio */
+	r->r_ratio = (r->r_losses != 0) ? r->r_kills / (float) r->r_losses
+	    : r->r_kills;
+	/*
+	   r->r_ratio = (s->st_tlosses != 0) ? (float) s->st_tkills / (float)
+	   s->st_tlosses : s->st_tkills;
+	*/
+        if(!status2->timeprod)
+          t = s->st_tticks;
+        else
+    	  t = (float) s->st_tticks / (float) status2->timeprod;	/* hour ratio */
+	if (t == 0.0)
+	    t = 1.0;
+	t2 = t * (float) status2->losses;	/* get expected losses */
+	if(t2 == 0) t2=1;
+	r->r_defrat = s->st_tlosses / t2;	/* calc defense rating */
+
+	t2 = t * (float) status2->kills;	/* get expected kills */
+	if(t2 == 0) t2=1;
+	r->r_offrat = s->st_tkills / t2;	/* calc offense rating */
+
+	t2 = t * (float) status2->armsbomb;	/* expected armies bombed */
+	if(t2 == 0) t2=1;
+	r->r_bombrat = (float) s->st_tarmsbomb / t2;	/* bomb rating */
+
+	t2 = t * (float) status2->resbomb;	/* expected resources bmbd */
+	if(t2 == 0) t2=1;
+	r->r_resrat = (float) s->st_tresbomb / t2;	/* resrce bmbd rating */
+
+	t2 = t * (float) status2->dooshes;	/* expected armies dooshed */
+	if(t2 == 0) t2=1;
+	r->r_dooshrat = (float) s->st_tdooshes / t2;	/* doosh rating */
+
+	r->r_batrat = r->r_dooshrat + r->r_offrat;	/* get battle rating */
+
+	t2 = t * (float) status2->planets;	/* expected planets */
+	if(t2 == 0) t2=1;
+	r->r_planetrat = (float) s->st_tplanets / t2;	/* get planet rating */
+	/* strategy rating */
+	r->r_stratrat = r->r_bombrat + r->r_resrat + r->r_planetrat;
+	/* calculate sb rating */
+	t2 = (float) status2->sbkills / (float)( (status2->sblosses > 0) ? status2->sblosses : 1);
+	if (s->st_sblosses == 0)
+	    r->r_sbrat = 0.0;
+	else
+	    r->r_sbrat = ((float) s->st_sbkills / (float) s->st_sblosses) / t2;
+	/* calculate wb rating */
+	t2 = (float) status2->wbkills / (float)( (status2->wblosses > 0) ? status2->wblosses : 1);
+	if (s->st_wblosses == 0)
+	    r->r_wbrat = 0.0;
+	else
+	    r->r_wbrat = ((float) s->st_wbkills / (float) s->st_wblosses) / t2;
+	/* calculate js rating */
+	t = (float) s->st_jsticks / (float)( (status2->jstime > 0) ? status2->jstime : 1);
+	t2 = t * (float) status2->jsplanets;	/* get expected js planets */
+	if (t2 == 0.0)
+	    r->r_jsrat = 0.0;
+	else
+	    r->r_jsrat = (float) s->st_jsplanets / t2;	/* js rating */
+	r->r_jsplanets = s->st_jsplanets;	/* store js planets */
+
+	r->r_specrat = r->r_sbrat + r->r_wbrat + r->r_jsrat;	/* get special ship
+								   rating */
+	/* put the sum of the three major ratings in the 'ratings' slot */
+	r->r_ratings = r->r_specrat + r->r_batrat + r->r_stratrat;
+	r->r_genocides = s->st_genocides;	/* get # genocides */
+	r->r_di = s->st_di;	/* get player's DI */
+	t = (s->st_tticks) ? s->st_tticks : 1.0;
+	r->r_killsPerHour = r->r_kills * 36000.0 / t;
+	r->r_lossesPerHour = r->r_losses * 36000.0 / t;
+	r->r_planets = s->st_tplanets;
+	r->r_armies = s->st_tarmsbomb;
+	r->r_resources = s->st_tresbomb;
+	r->r_dooshes = s->st_tdooshes;
+	/* r->r_jsplanets = s->st_jsplanets; */
+    } else {			/* bronco stats */
+	struct stats *s = &j->p_stats;
+
+	r->r_offrat = offenseRating(j);	/* offense */
+	r->r_planetrat = planetRating(j);	/* planet */
+	r->r_bombrat = bombingRating(j);	/* bombing */
+	r->r_offrat = offenseRating(j);	/* offense */
+	r->r_defrat = defenseRating(j);	/* defense */
+	r->r_resrat = 0;	/* these don't apply */
+	r->r_dooshrat = 0;
+	r->r_stratrat = 0;
+	r->r_batrat = 0;
+	r->r_sbrat = 0;
+	r->r_wbrat = 0;
+	r->r_jsrat = 0;
+	r->r_jsplanets = 0;
+	r->r_specrat = 0;
+	r->r_ratings = r->r_offrat + r->r_planetrat + r->r_bombrat;	/* ratings */
+	r->r_di = r->r_ratings * s->st_tticks / 36000.0;	/* di */
+	/* fill in kills, losses, and ratio based on ship type */
+	if (j->p_ship->s_type == STARBASE) {
+	    r->r_kills = s->st_sbkills;
+	    r->r_losses = s->st_sblosses;
+	    r->r_ratio = (s->st_sblosses != 0)
+		? (float) r->r_kills / (float) r->r_losses
+		: (float) j->p_stats.st_sbkills;
+	    r->r_maxkills = j->p_stats.st_sbmaxkills;
+	} else {
+	    r->r_kills = s->st_kills + s->st_tkills;
+	    r->r_losses = s->st_losses + s->st_tlosses;
+	    r->r_ratio = (r->r_losses != 0)
+		? (float) r->r_kills / (float) r->r_losses
+		: r->r_kills;
+	    r->r_maxkills = s->st_maxkills;
+	}
+	r->r_planets = s->st_tplanets + s->st_planets;
+	r->r_armies = s->st_armsbomb + s->st_tarmsbomb;
+	/* not recorded in bronco */
+	r->r_resources = 0;
+	/* r->r_jsplanets = 0; */
+	r->r_dooshes = 0;
+	r->r_genocides = 0;
+    }
+    return r;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/recorder.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,347 @@
+/* $Id: recorder.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+#ifdef RECORDER
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/select.h>
+#include <fcntl.h>
+
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "packets.h"
+
+int     record_total;
+int     lastTeamReq = -1;
+int     recfp = -1, playfp = -1;
+
+void pb_skip P((int frames));
+
+void
+startRecorder()
+{
+    if (recordGame = booleanDefault("recordGame", recordGame)) {
+	recordFile = stringDefault("recordFile", "/tmp/netrek.record");
+	recordFile = expandFilename(recordFile);
+	maxRecord = intDefault("maxRecord", maxRecord);
+	recfp = open(recordFile, O_WRONLY | O_TRUNC | O_APPEND | O_CREAT, S_IRWXU);
+	if (recfp >= 0)
+	    printf("Game being recorded to %s.  Max size is %d\n", recordFile, maxRecord);
+	else {
+	    perror("startRecorder");
+	    printf("Can't open file %s for recording\n", recordFile);
+	    recordGame = 0;
+	}
+    }
+}
+
+void
+stopRecorder()
+{
+    char    buf[80];
+
+    close(recfp);
+    recfp = -1;
+    recordGame = 0;
+    sprintf(buf, "Recording stopped, %d bytes (%d updates) written to %s\n",
+	   record_total, udcounter, (recordFile==NULL) ? "Nothing" : recordFile);
+    warning(buf);
+}
+
+void
+recordPacket(data, len)
+    char   *data;
+    int     len;
+{
+    int     res;
+
+    if (recfp >= 0 && len > 0) {
+	switch (*data) {
+	case SP_PICKOK:	/* playback needs to know what team! */
+	    data[2] = (char) lastTeamReq;
+	    break;
+	case SP_RSA_KEY:
+	case SP_MOTD:
+	case SP_MOTD_PIC:
+	case SP_NEW_MOTD:
+	    return;
+	default:
+	    break;
+	}
+	res = write(recfp, data, len);
+	record_total += res;
+	if ((maxRecord && (record_total > maxRecord)) || (res <= 0))
+	    stopRecorder();
+    }
+}
+
+void
+writeUpdateMarker()
+{
+    unsigned char update_buf[4];
+
+    update_buf[0] = REC_UPDATE;
+    /*
+       record stuff not normally sent by server.  Otherwise tractors and lock
+       markers don't work during playback
+    */
+    update_buf[1] = (unsigned char) me->p_tractor;
+    update_buf[2] = (unsigned char) ((me->p_flags & PFPLOCK) ? me->p_playerl : me->p_planet);
+    /* one more byte here, any ideas? */
+    record_total += write(recfp, update_buf, 4);
+}
+
+int
+startPlayback()
+{
+    if (playback || (playback = booleanDefault("playback", 0))) {
+	if (!playFile)
+	    playFile = stringDefault("playFile", "/tmp/netrek.record");
+	playFile = expandFilename(playFile);
+
+	playfp = open(playFile, O_RDONLY, 0);
+	if (playfp < 0) {
+	    perror("startPlayback");
+	    printf("Couldn't open playback file %s\n", playFile);
+	    exit(0);
+	}
+	printf("Replaying %s\n", playFile);
+	return 1;
+    }
+    return 0;
+}
+
+int
+readRecorded(fp, data, len)
+    int     fp, len;
+    char   *data;
+{
+    int     ret;
+
+    if (!playback || len < 0 || playfp < 0)
+	return -1;
+    if (len > 4)		/* make sure we don't skip updates */
+	len = 4;
+    ret = read(playfp, data, len);
+    if (ret <= 0)
+	EXIT(0);
+    return ret;
+}
+
+void
+pb_dokey(event)
+W_Event *event;
+{
+    switch (event->key&0xff) {
+    case 'p':
+    case 'P':
+	paused = !paused;
+	pb_scan=0;
+	if (paused)
+	    pb_advance = 0;
+	break;
+    case 'r':
+    case 'R':
+	pb_advance = PB_REDALERT;
+	paused = 0;
+	break;
+    case 'y':
+    case 'Y':
+	pb_advance = PB_YELLOWALERT;
+	paused = 0;
+	break;
+    case 'd':
+    case 'D':
+	pb_advance = PB_DEATH;
+	paused = 0;
+	break;
+    case ' ':
+	if(paused) {
+	    if(pb_scan)
+		pb_skip(pb_advance);
+	    else {
+		pb_advance=1;
+		paused=0;
+	    }
+	} else {
+	    paused = 1;
+	    pb_advance=0;
+	}
+	break;
+    case 'f':
+    case 'F': /* fast forward */
+	pb_scan=!pb_scan;
+	if(pb_scan) {
+	    pb_advance=10;
+	    pb_slow=0;
+	    paused=0;
+	    warning("1-9: set speed. P-Pause, F-Fast Fwd off");
+	} else {
+	    pb_advance=0;
+	    pb_slow=0;
+	    paused=0;
+	    warning("Playback mode, keys: P)ause R)ed Y)ellow D)eath F)ast Q)uit");
+	}
+	break;
+    case 's': /* Slow mode */
+    case 'S':
+	if(pb_scan || paused || !pb_slow)
+	    pb_slow=1;
+	else
+	    pb_slow=0;
+	pb_scan=0;
+	paused=0;
+	pb_advance=0;
+	break;
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+	if(!pb_scan)
+	    pb_advance += (event->key - '0') * 10;
+	else
+	    pb_advance = (event->key - '0') * 10;
+	paused = 0;
+	break;
+    case 'q':
+    case 'Q':
+	exit(0);
+    default:
+	warning("Playback mode, keys: P)ause R)ed Y)ellow D)eath F)ast Q)uit");
+    }
+}
+
+void
+pb_skip(frames)
+     int frames;
+{
+    while(frames) {
+	pb_update=0;
+	readFromServer();
+	frames-=pb_update;
+	udcounter+=pb_update;
+    }
+}
+
+void
+pb_framectr(xloc, yloc)
+     int xloc, yloc;
+{
+    char buf[20];
+
+    if(paused) 
+	strcpy(buf,"PAU");
+    else if(pb_scan)
+	strcpy(buf,"FFW");
+    else if(pb_advance) {
+	switch(pb_advance) {
+	case PB_REDALERT:
+	    strcpy(buf,"RED");
+	    break;
+	case PB_YELLOWALERT:
+	    strcpy(buf,"YLW");
+	    break;
+	case PB_DEATH:
+	    strcpy(buf,"DTH");
+	    break;
+	default:
+	    buf[0]='+';
+	    buf[1]=(pb_advance / 10) + '0';
+	    buf[2]=(pb_advance % 10) + '0';
+	    break;
+	}
+    } else if(pb_slow)
+	strcpy(buf,"SLW");
+    else
+	strcpy(buf,"NRM");
+
+    sprintf((buf+3),":%8d",udcounter);
+
+    W_WriteText(tstatw, xloc, yloc, textColor, buf, 12, W_RegularFont);
+}
+
+void
+pb_input()
+{
+    W_Event data;
+    fd_set  readfds;
+    int     wsock = W_Socket();
+
+    struct timeval timeout;
+
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 200000;
+
+    intrupt(); /* draws the first frame */
+
+    while (me->p_status == PALIVE ||
+	   me->p_status == PEXPLODE ||
+	   me->p_status == PDEAD ||
+	   me->p_status == POBSERVE) {
+
+	if (keepInfo > 0) {
+	    if (infowin_up >= 0 &&
+		--infowin_up == -1 &&
+		infomapped) {
+		destroyInfo();
+		infowin_up = -2;
+	    }
+	}
+	exitInputLoop = 0;
+	while (W_EventsPending() && !exitInputLoop) {
+	    fastQuit = 0;	/* any event cancel fastquit */
+	    W_NextEvent(&data);
+	    dispatch_W_event(&data);
+	}
+	if (!paradise)  /* stars are ok, it's just a recording.
+			   zoom doesn't make sense. */
+	    blk_zoom = 0;
+
+#ifndef AMIGA
+	FD_ZERO(&readfds);
+	FD_SET(wsock, &readfds);
+	if (paused) {
+	    select(32, &readfds, (fd_set *) 0, (fd_set *) 0, 0);
+	    continue;
+	} else if(pb_slow && !pb_scan)
+	    select(32, &readfds, (fd_set *) 0, (fd_set *) 0,&timeout);
+
+	/* otherwise, in full blast mode, don't wait on anything. */
+
+#else				/* AMIGA */
+	if (paused) {
+	    sigsPending = Wait(wsock | SIGBREAKF_CTRL_C);
+	    continue;
+	} else if(pb_slow && !pb_scan) {
+	    StartTimer(0,200000);
+	    while(1) {
+		sigsPending = Wait(wsock | portmask | SIGBREAKF_CTRL_C);
+		if((sigsPending & (wsock | SIGBREAKF_CTRL_C)) ||
+		   CheckIO(&(ior->tr_node)))
+		    break;
+	    }
+		
+	    StopTimer();
+	}
+		
+	if (sigsPending & SIGBREAKF_CTRL_C) {
+	    printf("User break, Ctrl-C, exiting!\n");
+	    exit(0);
+	}
+#endif				/* AMIGA */
+	/* at this point, we're sure it's time for at least one frame. */
+	intrupt();
+    }
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/redraw.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,2564 @@
+/*
+ * redraw.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <math.h>
+#include <ctype.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+#include "gameconf.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif
+#include "sound.h"
+
+typedef struct tractor Tractor;
+struct tractor {
+    int     sx, sy, d1x, d1y, d2x, d2y;	/* source (x,y) dest (x1,y1) (x2,y2) */
+    Tractor *next;
+}      *tracthead = NULL, *tractcurrent = NULL, *tractrunner;
+
+struct _clearzone *
+new_czone()
+{
+    if (clearzone == 0) {
+	czsize = 10;
+	clearzone = (struct _clearzone *) malloc(sizeof(*clearzone) * czsize);
+	clearcount = 0;
+    } else if (clearcount >= czsize) {
+	clearzone = (struct _clearzone *) realloc(clearzone,
+					sizeof(*clearzone) * (czsize *= 2));
+    }
+    return &clearzone[clearcount++];
+}
+
+/* Prototypes */
+static void local P((void));
+#ifndef COW_HAS_IT_WHY_SHOULDNT_WE
+static
+#endif
+void map P((void));
+static void redraw P((void));
+/* static void stline P((int flag));*/
+static W_Icon planetBitmap P((struct planet * p));
+static W_Icon planetmBitmap P((struct planet * p));
+
+void
+intrupt()
+{
+    static long lastread;
+    static struct timeval lastredraw = {0, 0};
+    struct timeval t;
+    static int needredraw=0;
+
+#ifndef __osf__
+    long    time();
+#endif
+
+    udcounter++;
+    
+    needredraw += readFromServer();
+
+    gettimeofday(&t, NULL);
+    if (needredraw && ((unsigned int) redrawDelay * 100000 <
+                       (unsigned int) ((t.tv_sec - lastredraw.tv_sec) * 1000000
+                                       + (t.tv_usec - lastredraw.tv_usec)))) {
+	needredraw = 0;
+        lastredraw=t;
+#if 0
+	lastread = time(NULL);
+#endif
+#ifdef RECORDER
+	if (!playback || (pb_update && 
+			  ((!pb_scan) || !(udcounter % pb_advance))))
+#endif
+	{
+	    redraw();
+	    playerlist2();
+	}
+#ifdef RECORDER
+	if (playback) {
+	    if(!pb_scan) {
+		if (pb_advance > 0) {
+		    if ((pb_advance -= pb_update) <= 0) {
+			pb_advance = 0;
+			paused = 1;
+		    }
+		} else if (pb_advance < 0) {
+		    switch (pb_advance) {
+		    case PB_REDALERT:
+			if (me->p_flags & PFRED) {
+			    pb_advance = 0;
+			    paused = 1;
+			}
+			break;
+		    case PB_YELLOWALERT:
+			if (me->p_flags & PFYELLOW) {
+			    pb_advance = 0;
+			    paused = 1;
+			}
+			break;
+		    case PB_DEATH:
+		    default:
+			if (me->p_status != PALIVE) {
+			    pb_advance = 0;
+			paused = 1;
+			}
+			break;
+		    }
+		}
+	    }
+	    pb_update = 0;
+	}
+	if (recordGame)
+	    writeUpdateMarker();
+#endif
+    }
+#if 0
+    if (lastread + 3 < time(NULL)) {
+	/*
+	   We haven't heard from server for awhile... Strategy:  send a
+	   useless packet to "ping" server.
+	*/
+	sendWarReq(me->p_hostile);
+    }
+#endif
+    if (me->p_status == POUTFIT) {
+	death();
+    }
+}
+
+static void
+redraw()
+{
+
+    /* erase warning line if necessary */
+    if ((warntimer <= udcounter) && (warncount > 0)) {
+#ifndef AMIGA
+	/* XFIX */
+	W_ClearArea(warnw, 5, 5, W_Textwidth * warncount, W_Textheight);
+#else
+	W_ClearWindow(warnw);
+#endif
+	warncount = 0;
+    }
+    if (W_FastClear) {
+	W_ClearWindow(w);
+	clearcount = 0;
+	clearlcount = 0;
+	tractcurrent = tracthead;
+    } else {
+#if 0
+	/* just to save a little time on all the function calls */
+	/* all the normal clear functions are implemented as well. */
+	W_FlushClearZones(w, clearzone, clearcount);
+	clearcount = 0;
+#else
+	while (clearcount) {
+	    clearcount--;
+	    /* XFIX */
+	    W_CacheClearArea(w, clearzone[clearcount].x,
+		       clearzone[clearcount].y, clearzone[clearcount].width,
+			     clearzone[clearcount].height);
+
+	    /*
+	       W_ClearArea(w, clearzone[clearcount].x,
+	       clearzone[clearcount].y, clearzone[clearcount].width,
+	       clearzone[clearcount].height);
+	    */
+	}
+#endif
+	while (clearlcount) {
+	    clearlcount--;
+	    /* XFIX */
+	    W_CacheLine(w, clearline[0][clearlcount],
+			clearline[1][clearlcount], clearline[2][clearlcount],
+			clearline[3][clearlcount], backColor);
+	    /*
+	       W_MakeLine(w, clearline[0][clearlcount],
+	       clearline[1][clearlcount], clearline[2][clearlcount],
+	       clearline[3][clearlcount], backColor);
+	    */
+	}
+	/* XFIX */
+#ifndef AMIGA
+	W_FlushClearAreaCache(w);
+	W_FlushLineCaches(w);
+#endif
+	/* erase the tractor lines [BDyess] */
+	for (tractrunner = tracthead; tractrunner != tractcurrent;
+	     tractrunner = tractrunner->next) {
+	    W_MakeTractLine(w, tractrunner->sx, tractrunner->sy,
+			    tractrunner->d1x, tractrunner->d1y,
+			    backColor);
+	    W_MakeTractLine(w, tractrunner->sx, tractrunner->sy,
+			    tractrunner->d2x, tractrunner->d2y,
+			    backColor);
+	}
+	tractcurrent = tracthead;
+    }
+
+    local();			/* redraw local window */
+
+#ifdef AMIGA			/* would do it in W_EventsPending, just have
+				   it here so the display is updated sooner. */
+    W_Flush();
+#endif
+
+    /* XFIX */
+    W_FlushLineCaches(w);
+
+    stline(0);
+
+    if (W_IsMapped(statwin))
+	updateStats();
+
+    updateInform();		/* check and update info window [BDyess] */
+
+    /* XFIX: last since its least accurate information */
+    if (mapmode)
+	map();
+
+}
+
+static W_Icon terrainBitmap(int x, int y)
+{
+   int aster_bm = 0;
+   int aster_fluff = 0;
+   
+   /* is no asteroids, then return fluff if adjacent 'roids */
+   if (!(terrainInfo[x*250 + y].types & T_ASTEROIDS)) aster_fluff = 1;
+
+   /* check surrounding terrain */
+   if (x > 0)
+      if (terrainInfo[(x-1)*250 + y].types & T_ASTEROIDS)
+	 aster_bm |= (1<<0);
+   if (x < 249)
+      if (terrainInfo[(x+1)*250 + y].types & T_ASTEROIDS) 
+	 aster_bm |= (1<<2);
+   if (y > 0)
+      if (terrainInfo[x*250 + y-1].types & T_ASTEROIDS) 
+	 aster_bm |= (1<<3);
+   if (y < 249)
+      if (terrainInfo[x*250 + y+1].types & T_ASTEROIDS) 
+	 aster_bm |= (1<<1);
+   
+   if (aster_fluff && aster_bm) return asteroidfluff[(x*250 + y)%3];
+   else return asteroidBM[aster_bm];
+}
+
+static  W_Icon
+planetBitmap(p)
+    register struct planet *p;
+{
+    int     i;
+    if (paradise) {
+	switch (PL_TYPE(*p)) {
+	case PLWHOLE:
+	    return wormBM[udcounter % WORMFRAMES];
+	    break;
+	case PLSTAR:
+	    return starBM[udcounter % STARFRAMES];
+	    break;
+	case PLAST:
+	    return basteroid[0];
+	}
+    }
+    if (showlocal == 2) {
+	return (bplanets[0]);
+    } else if (p->pl_info & idx_to_mask(me->p_teami)) {
+	if (showlocal == 1 || showlocal == 4) {
+	    i = 0;
+	    if ((paradise) && (p->pl_flags & PLSHIPYARD))
+		i += 8;
+	    if (p->pl_armies > 4)
+		i += 4;
+	    if (p->pl_flags & PLREPAIR)
+		i += 2;
+	    if (p->pl_flags & PLFUEL)
+		i += 1;
+	    return ((showlocal == 1 ? bplanets2 : bplanetsMOO)[i]);
+	} else if (showlocal == 0) {
+	    int     team = mask_to_idx(p->pl_owner);
+	    if (team < -1)
+		team = -1;
+	    else if (team >= number_of_teams)
+		team = number_of_teams - 1;
+	    return (bplanets[1 + team]);
+	} else {
+	    int     mask;
+	    if (paradise)
+		mask = (p->pl_flags & PLSURMASK) >> PLSURSHIFT;
+	    else {
+		mask = ((p->pl_flags & PLFUEL) ? 1 : 0)
+		    | ((p->pl_flags & PLREPAIR) ? 2 : 0)
+		    | ((p->pl_flags & PLAGRI) ? 4 : 0);
+	    }
+	    return bplanetsr[mask];
+	}
+    } else {
+	return (bplanets[5]);
+    }
+}
+
+
+static  W_Icon
+planetmBitmap(p)
+    register struct planet *p;
+{
+    int     i;
+    if (paradise) {
+	switch (p->pl_flags & PLTYPEMASK) {
+	case PLSTAR:
+	    return mstarBM;
+	case PLAST:
+	    return mbasteroid[0];
+#ifdef VISIBLE_WORMHOLES
+	case PLWHOLE:
+	    return mholeBM;
+#endif /*VISIBLE_WORMHOLES*/
+	}
+    }
+    if (showgalactic == 2) {
+	return (mbplanets[0]);
+    } else if (showgalactic == 4) {
+	int     infoage = 4;
+	if (!(p->pl_info & idx_to_mask(me->p_teami)))
+	    return mbplanetsA[NSCOUTAGES - 1];
+	if (p->pl_owner == idx_to_mask(me->p_teami))
+	    return mbplanetsA[0];
+
+	for (i = 0;
+	   i < NSCOUTAGES - 1 && infoage < status2->clock - p->pl_timestamp;
+	     i++, infoage = infoage * 5 / 3) {
+	}
+	return mbplanetsA[i];
+    } else if (p->pl_info & idx_to_mask(me->p_teami)) {
+	if (showgalactic == 1 || showgalactic == 5) {
+	    i = 0;
+	    if ((paradise) && (p->pl_flags & PLSHIPYARD))
+		i += 8;
+	    if (p->pl_armies > 4)
+		i += 4;
+	    if (p->pl_flags & PLREPAIR)
+		i += 2;
+	    if (p->pl_flags & PLFUEL)
+		i += 1;
+	    return ((showgalactic == 1 ? mbplanets2 : mbplanetsMOO)[i]);
+	} else if (showgalactic == 0) {
+	    int     team = mask_to_idx(p->pl_owner);
+	    if (team < -1)
+		team = -1;
+	    else if (team >= number_of_teams)
+		team = number_of_teams - 1;
+	    return (mbplanets[1 + team]);
+	} else {
+	    int     mask;
+	    if (paradise)
+		mask = (p->pl_flags & PLSURMASK) >> PLSURSHIFT;
+	    else {
+		mask = ((p->pl_flags & PLFUEL) ? 1 : 0)
+		    | ((p->pl_flags & PLREPAIR) ? 2 : 0)
+		    | ((p->pl_flags & PLAGRI) ? 4 : 0);
+	    }
+	    return mbplanetsr[mask];
+	}
+    } else {
+	return (mbplanets[5]);
+    }
+}
+
+/* call this from local for each player, instead of having an extra loop! */
+static void
+redraw_photon_torps(j)
+    struct player *j;
+{
+    int     i, h;
+    struct torp *k;
+    int     dx, dy;
+    int     view;
+    struct _clearzone *cz;
+
+    view = SCALE * WINSIDE / 2;
+    i = j->p_no;
+    if (!j->p_ntorp)
+	return;
+    for (h = 0, k = &torps[ntorps * i + h]; h < ntorps; h++, k++) {
+	if (!k->t_status)
+	    continue;
+	dx = k->t_x - me->p_x;
+	dy = k->t_y - me->p_y;
+	if (ABS(dx) > view || ABS(dy) > view) {
+	    /* Call any torps off screen "free" (if owned by other) */
+	    if (k->t_status == TEXPLODE && j != me) {
+		k->t_status = TFREE;
+		j->p_ntorp--;
+	    }
+	    continue;
+	}
+	dx = dx / SCALE + WINSIDE / 2;
+	dy = dy / SCALE + WINSIDE / 2;
+#ifdef UNIX_SOUND
+        if ((k->t_status == TEXPLODE) && (k->t_fuse == 5)) play_sound (SND_TORPHIT);
+#endif
+	if (k->t_status == TEXPLODE) {
+
+	    k->t_fuse--;
+	    if (k->t_fuse <= 0) {
+		k->t_status = TFREE;
+		j->p_ntorp--;
+		continue;
+	    }
+	    if (k->t_fuse >= NUMDETFRAMES) {
+		k->t_fuse = NUMDETFRAMES - 1;
+	    }
+	    W_WriteBitmap(dx - (cloud_width / 2), dy - (cloud_height / 2),
+			  cloud[k->t_fuse], torpColor(k));
+	    cz = new_czone();
+	    cz->x = dx - (cloud_width / 2);
+	    cz->y = dy - (cloud_height / 2);
+	    cz->width = cloud_width;
+	    cz->height = cloud_height;
+	} else if (k->t_owner != me->p_no && ((k->t_war & idx_to_mask(me->p_teami)) ||
+					      (idx_to_mask(players[k->t_owner].p_teami) & (me->p_hostile | me->p_swar)))) {
+	    /*
+	       solid.  Looks strange. W_FillArea(w, dx - (etorp_width/2), dy
+	       - (etorp_height/2), etorp_width, etorp_height, torpColor(k));
+	    */
+
+#ifdef BORGTEST
+	    W_CacheLine(w, dx - (etorp_width / 2), dy - (etorp_height / 2),
+			dx + (etorp_width / 2), dy + (etorp_height / 2),
+			(k->t_turns == 32767) ? notColor(k) : torpColor(k));
+	    W_CacheLine(w, dx + (etorp_width / 2), dy - (etorp_height / 2),
+			dx - (etorp_width / 2), dy + (etorp_height / 2),
+			(k->t_turns == 32767) ? notColor(k) : torpColor(k));
+#else
+#ifdef TORPBITS
+	    /*
+	       went back to this for Amiga, one bitmap is faster than 2
+	       lines.
+	     */
+	    W_WriteBitmap(dx - (etorp_width / 2), dy - (etorp_height / 2),
+			  etorp, torpColor(k));
+#else
+	    /* XFIX */
+	    if (0 && k->frame) {
+		W_CacheLine(w, dx - 2, dy,
+			    dx + 2, dy, torpColor(k));
+		W_CacheLine(w, dx, dy - 2,
+			    dx, dy + 2, torpColor(k));
+	    } else {
+		W_CacheLine(w, dx - 1, dy - 1,
+			    dx + 1, dy + 1, torpColor(k));
+		W_CacheLine(w, dx + 1, dy - 1,
+			    dx - 1, dy + 1, torpColor(k));
+	    }
+	    k->frame = !k->frame;
+#endif				/* TORPBITS */
+#endif
+
+	    cz = new_czone();
+	    cz->x = dx - (etorp_width / 2);
+	    cz->y = dy - (etorp_height / 2);
+	    cz->width = etorp_width;
+	    cz->height = etorp_height;
+	} else {
+	    /* XFIX */
+
+	    if (0 /* animateTorps */ ) {
+		switch (k->frame) {
+		case 0:
+		    W_CacheLine(w, dx - (mtorp_width / 2), dy, dx,
+				dy, torpColor(k));
+		    break;
+		case 1:
+		    W_CacheLine(w, dx - (mtorp_width / 2), dy - (mtorp_width / 2),
+				dx, dy, torpColor(k));
+		    break;
+		case 2:
+		    W_CacheLine(w, dx, dy, dx,
+				dy + (mtorp_width / 2), torpColor(k));
+		    break;
+		case 3:
+		    W_CacheLine(w, dx, dy,
+				dx + (mtorp_width / 2), dy - (mtorp_width / 2), torpColor(k));
+		    break;
+		case 4:
+		    W_CacheLine(w, dx, dy, dx + (mtorp_width / 2),
+				dy, torpColor(k));
+		    break;
+		case 5:
+		    W_CacheLine(w, dx - (mtorp_width / 2), dy - (mtorp_width / 2),
+				dx, dy, torpColor(k));
+		    break;
+		case 6:
+		    W_CacheLine(w, dx, dy - (mtorp_width / 2), dx,
+				dy, torpColor(k));
+		    break;
+		case 7:
+		    W_CacheLine(w, dx - (mtorp_width / 2), dy - (mtorp_width / 2),
+				dx, dy, torpColor(k));
+		    break;
+		}
+		k->frame++;
+		if (k->frame > 7)
+		    k->frame = 0;
+	    } else {
+#ifdef TORPBITS
+		W_WriteBitmap(dx - (mtorp_width / 2), dy - (mtorp_height / 2),
+			      mtorp, torpColor(k));
+#else
+		W_CacheLine(w, dx - (mtorp_width / 2), dy,
+			    dx + (mtorp_width / 2), dy, torpColor(k));
+		W_CacheLine(w, dx, dy - (mtorp_width / 2),
+			    dx, dy + (mtorp_width / 2), torpColor(k));
+#endif
+	    }
+
+	    cz = new_czone();
+	    cz->x = dx - (mtorp_width / 2);
+	    cz->y = dy - (mtorp_height / 2);
+	    cz->width = mtorp_width;
+	    cz->height = mtorp_height;
+	}
+    }
+}
+
+static void
+draw_one_thingy(k)
+    struct thingy *k;
+{
+    int     dx, dy;
+    int     view;
+    struct _clearzone *cz;
+    view = SCALE * WINSIDE / 2;
+
+    if (k->t_shape == SHP_BLANK)
+	return;
+    /* printf("%d,%d - %d,%d\n", me->p_x, me->p_y, k->t_x, k->t_y); */
+    dx = k->t_x - me->p_x;
+    dy = k->t_y - me->p_y;
+    if (ABS(dx) > view || ABS(dy) > view) {
+	return;
+    }
+    dx = dx / SCALE + WINSIDE / 2;
+    dy = dy / SCALE + WINSIDE / 2;
+    switch (k->t_shape) {
+    case SHP_BOOM:
+	k->t_fuse--;
+	if (k->t_fuse <= 0) {
+	    k->t_shape = SHP_BLANK;
+	    return;
+	}
+	if (k->t_fuse >= NUMDETFRAMES) {
+	    k->t_fuse = NUMDETFRAMES - 1;
+	}
+	W_WriteBitmap(dx - (cloud_width / 2), dy - (cloud_height / 2),
+		      cloud[k->t_fuse], droneColor(k));
+	cz = new_czone();
+	cz->x = dx - (cloud_width / 2);
+	cz->y = dy - (cloud_height / 2);
+	cz->width = cloud_width;
+	cz->height = cloud_height;
+	break;
+    case SHP_MISSILE:
+	{
+	    int     dview = (int) (k->t_dir * NDRONEVIEWS + 128) / 256;
+	    if (dview >= NDRONEVIEWS)
+		dview -= NDRONEVIEWS;
+	    W_WriteBitmap
+		(dx - (drone_width / 2), dy - (drone_height / 2),
+		 drone_bm[dview],
+		 droneColor(k));
+	}
+	cz = new_czone();
+	cz->x = dx - (drone_width / 2);
+	cz->y = dy - (drone_height / 2);
+	cz->width = drone_width;
+	cz->height = drone_height;
+	break;
+    case SHP_TORP:
+	if (k->t_owner != me->p_no &&
+	    ((k->t_war & idx_to_mask(me->p_teami)) ||
+	     (idx_to_mask(players[k->t_owner].p_teami) & (me->p_hostile | me->p_swar)))) {
+	    W_CacheLine(w, dx - (etorp_width / 2), dy - (etorp_height / 2),
+	     dx + (etorp_width / 2), dy + (etorp_height / 2), torpColor(k));
+	    W_CacheLine(w, dx + (etorp_width / 2), dy - (etorp_height / 2),
+	     dx - (etorp_width / 2), dy + (etorp_height / 2), torpColor(k));
+	    cz = new_czone();
+	    cz->x = dx - (etorp_width / 2);
+	    cz->y = dy - (etorp_height / 2);
+	    cz->width = etorp_width;
+	    cz->height = etorp_height;
+	} else {
+	    W_CacheLine(w, dx - (mtorp_width / 2), dy, dx + (mtorp_width / 2), dy,
+			torpColor(k));
+	    W_CacheLine(w, dx, dy - (mtorp_width / 2), dx, dy + (mtorp_width / 2),
+			torpColor(k));
+	    cz = new_czone();
+	    cz->x = dx - (mtorp_width / 2);
+	    cz->y = dy - (mtorp_height / 2);
+	    cz->width = mtorp_width;
+	    cz->height = mtorp_height;
+	}
+	break;
+    case SHP_PLASMA:
+    case SHP_MINE:		/* use plasma until I get a nifty bitmap */
+	if (k->t_owner != me->p_no &&
+	    ((k->t_war & idx_to_mask(me->p_teami)) ||
+	     (idx_to_mask(players[k->t_owner].p_teami) & (me->p_hostile | me->p_swar)))) {
+	    W_WriteBitmap(dx - (eplasmatorp_width / 2),
+			  dy - (eplasmatorp_height / 2),
+			  eplasmatorp, torpColor(k));
+	    cz = new_czone();
+	    cz->x = dx - (eplasmatorp_width / 2);
+	    cz->y = dy - (eplasmatorp_height / 2);
+	    cz->width = eplasmatorp_width;
+	    cz->height = eplasmatorp_height;
+	} else {
+	    W_WriteBitmap(dx - (mplasmatorp_width / 2),
+			  dy - (mplasmatorp_height / 2),
+			  mplasmatorp, torpColor(k));
+	    cz = new_czone();
+	    cz->x = dx - (mplasmatorp_width / 2);
+	    cz->y = dy - (mplasmatorp_height / 2);
+	    cz->width = mplasmatorp_width;
+	    cz->height = mplasmatorp_height;
+	}
+	break;
+    case SHP_PBOOM:
+	k->t_fuse--;
+	if (k->t_fuse <= 0) {
+	    k->t_shape = SHP_BLANK;
+	    return;
+	}
+	if (k->t_fuse >= NUMDETFRAMES) {
+	    k->t_fuse = NUMDETFRAMES - 1;
+	}
+	W_WriteBitmap(dx - (plasmacloud_width / 2),
+		      dy - (plasmacloud_height / 2),
+		      plasmacloud[k->t_fuse], torpColor(k));
+	cz = new_czone();
+	cz->x = dx - (plasmacloud_width / 2);
+	cz->y = dy - (plasmacloud_height / 2);
+	cz->width = plasmacloud_width;
+	cz->height = plasmacloud_height;
+	break;
+    case SHP_FIGHTER:
+	{
+	    int     fview = (int) (k->t_dir * VIEWS + 128) / 256;
+	    if (fview >= VIEWS)
+		fview -= VIEWS;
+	    W_WriteBitmap(dx - (fighter_width / 2),
+			  dy - (fighter_height / 2),
+			  fighter[fview], torpColor(k));
+	    cz = new_czone();
+	    cz->x = dx - (fighter_width / 2);
+	    cz->y = dy - (fighter_height / 2);
+	    cz->width = fighter_width;
+	    cz->height = fighter_height;
+	}
+	break;
+    case SHP_WARP_BEACON:
+	{
+	    cz = new_czone();
+	    cz->x = dx - (warpbeacon_width / 2);
+	    cz->y = dy - (warpbeacon_height / 2);
+	    cz->width = warpbeacon_width;
+	    cz->height = warpbeacon_height;
+	    W_WriteBitmap(cz->x, cz->y,
+			  warpbeacon, W_White);
+	    if (k->t_fuse > 4) {
+		W_WriteBitmap(cz->x, cz->y,
+			      wbflash, shipCol[1 + mask_to_idx(k->t_owner)]);
+	    }
+	    if (++(k->t_fuse) > 6)
+		k->t_fuse = 0;
+	}
+    }
+}
+
+static void
+redraw_drones(j)
+    struct player *j;
+{
+    int     i, h;
+    int     count;
+
+    i = j->p_no;
+
+    if (!j->p_ndrone)
+	return;
+    count = 0;
+
+    for (h = i * npthingies; h < npthingies * (i + 1); h++) {
+	draw_one_thingy(&thingies[h]);
+	if (thingies[h].t_shape != SHP_BLANK)
+	    count++;
+    }
+    j->p_ndrone = count;
+}
+
+static void
+redraw_other_drones()
+{
+    int     h;
+
+    for (h = 0; h < ngthingies; h++)
+	draw_one_thingy(&thingies[nplayers * npthingies + h]);
+}
+
+static void
+redraw_plasma_torps(j)
+    struct player *j;
+{
+    int     h, i;
+    register struct plasmatorp *pt;
+    struct _clearzone *cz;
+
+    int     dx, dy;
+    int     view;
+
+    view = SCALE * WINSIDE / 2;
+    i = j->p_no;
+
+    if (!j->p_nplasmatorp)
+	return;
+    for (h = 0, pt = &plasmatorps[nplasmas * i + h]; h < nplasmas; h++, pt++) {
+	if (!pt->pt_status)
+	    continue;
+	dx = pt->pt_x - me->p_x;
+	dy = pt->pt_y - me->p_y;
+	if (ABS(dx) > view || ABS(dy) > view)
+	    continue;
+	dx = dx / SCALE + WINSIDE / 2;
+	dy = dy / SCALE + WINSIDE / 2;
+#ifdef UNIX_SOUND
+        if ((pt->pt_status == TEXPLODE) && (pt->pt_fuse == 5))
+                play_sound (SND_TORPHIT); /* Torp Hit used for Plasma Hit */
+#endif
+	if (pt->pt_status == PTEXPLODE) {
+	    pt->pt_fuse--;
+	    if (pt->pt_fuse <= 0) {
+		pt->pt_status = PTFREE;
+		j->p_nplasmatorp--;
+		continue;
+	    }
+	    if (pt->pt_fuse >= NUMDETFRAMES) {
+		pt->pt_fuse = NUMDETFRAMES - 1;
+	    }
+	    W_WriteBitmap(dx - (plasmacloud_width / 2),
+			  dy - (plasmacloud_height / 2),
+			  plasmacloud[pt->pt_fuse], plasmatorpColor(pt));
+	    cz = new_czone();
+	    cz->x = dx - (plasmacloud_width / 2);
+	    cz->y = dy - (plasmacloud_height / 2);
+	    cz->width = plasmacloud_width;
+	    cz->height = plasmacloud_height;
+	}
+	/* needmore: if(pt->pt_war & idx_to_mask(me->p_teami)) */
+	else if (pt->pt_owner != me->p_no && ((pt->pt_war & idx_to_mask(me->p_teami)) ||
+					      (idx_to_mask(players[pt->pt_owner].p_teami) & (me->p_hostile | me->p_swar)))) {
+	    W_WriteBitmap(dx - (eplasmatorp_width / 2),
+			  dy - (eplasmatorp_height / 2),
+			  eplasmatorp, plasmatorpColor(pt));
+	    cz = new_czone();
+	    cz->x = dx - (eplasmatorp_width / 2);
+	    cz->y = dy - (eplasmatorp_height / 2);
+	    cz->width = eplasmatorp_width;
+	    cz->height = eplasmatorp_height;
+	} else {
+	    W_WriteBitmap(dx - (mplasmatorp_width / 2),
+			  dy - (mplasmatorp_height / 2),
+			  mplasmatorp, plasmatorpColor(pt));
+	    cz = new_czone();
+	    cz->x = dx - (mplasmatorp_width / 2);
+	    cz->y = dy - (mplasmatorp_height / 2);
+	    cz->width = mplasmatorp_width;
+	    cz->height = mplasmatorp_height;
+	}
+    }
+}
+
+#ifdef HOCKEY
+void tactical_hockey P((void));
+#endif
+
+void
+redraw_terrain()
+{
+   int i,j;
+   int view;
+   int nx, ny; /* for adjusted coords, based on ship position */
+   int tx, ty, x; /* terrain grid x and y for 0,0 on the local */
+   struct _clearzone *cz;
+   
+   view = SCALE * WINSIDE / 2;
+   
+   nx = (int) ((me->p_x - view) / SCALE)%terrain_width;
+   ny = (int) ((me->p_y - view) / SCALE)%terrain_height;
+
+   ty = (int) ((me->p_y - view)/(GWIDTH/250));
+   x = tx = (int) ((me->p_x - view)/(GWIDTH/250));
+   if (ty < 0) ty = 0;
+   if (tx < 0) {
+      tx = 0;
+      x = 0;
+   }
+
+   if(received_terrain_info) {
+      for (i=0; i < WINSIDE; i += terrain_height) {
+	 for (j=0; j < WINSIDE; j += terrain_width) {
+	    if ((terrainInfo[tx*250+ty].types & T_ASTEROIDS) ||
+		((tx > 0) && (terrainInfo[(tx-1)*250+ty].types & T_ASTEROIDS)) ||
+		((tx < 249) && (terrainInfo[(tx+1)*250+ty].types & T_ASTEROIDS)) ||
+		((ty > 0) && (terrainInfo[tx*250+(ty-1)].types & T_ASTEROIDS)) ||
+		((tx < 249) && (terrainInfo[tx*250+(ty+1)].types & T_ASTEROIDS))) {
+	       W_WriteBitmap(j-nx, i-ny, terrainBitmap(tx,ty), W_Grey);
+	       cz = new_czone();
+	       cz->x = j-nx;
+	       cz->y = i-ny;
+	       cz->width = terrain_width;
+	       cz->height = terrain_height;
+	    } 
+	    tx++;
+	    if (tx >= 250) {
+	       tx = x;
+	       break;
+	    }
+	 }
+	 ty++;
+	 if (ty >= 250) break;
+	 tx = x;
+      }
+   }
+}
+
+void
+redraw_all_planets()
+{
+    int     view;
+    int     i;
+    int     dx, dy;
+    struct _clearzone *cz;
+    struct planet *l;
+    int     nplan;
+
+    view = SCALE * WINSIDE / 2;
+    nplan = paradise ? nplanets : 40;
+
+#ifdef HOCKEY
+    if(hockey) {
+      tactical_hockey();
+    }
+#endif /*HOCKEY*/
+    for (i = 0, l = &planets[i]; i < nplan; i++, l++) {
+	dx = l->pl_x - me->p_x;
+	dy = l->pl_y - me->p_y;
+	if (ABS(dx) > view || ABS(dy) > view)
+	    continue;
+	dx = dx / SCALE + WINSIDE / 2;
+	dy = dy / SCALE + WINSIDE / 2;
+	if (PL_TYPE(*l) == PLWHOLE)
+	   W_WriteBitmap(dx - (wormhole_width / 2), dy - (wormhole_height / 2),
+		      planetBitmap(l),
+		      ((paradise) && (PL_TYPE(*l) == PLWHOLE))
+		       ? textColor
+		       : planetColor(l));
+	else
+	W_WriteBitmap(dx - (planet_width / 2), dy - (planet_height / 2),
+		      planetBitmap(l),
+			 ((paradise) && (PL_TYPE(*l) == PLSTAR))
+		      ? textColor
+		      : planetColor(l));
+#ifdef SHOW_IND
+	if (showIND && (l->pl_info & idx_to_mask(me->p_teami)) && (l->pl_owner == NOBODY) && l->pl_flags & PLPLANET)
+	{
+	    W_CacheLine (w, dx - (planet_width / 2), dy - (planet_height / 2),
+			 dx + (planet_width / 2 - 1), dy + (planet_height / 2 - 1),
+			 W_White);
+	    W_CacheLine (w, dx + (planet_width / 2 - 1), dy - (planet_height / 2),
+			 dx - (planet_width / 2), dy + (planet_height / 2 - 1),
+			 W_White);
+	}
+#endif
+	if (namemode) {
+	   if (PL_TYPE(*l) != PLWHOLE) {
+	    W_MaskText(w, dx - l->pl_namelen * W_Textwidth / 2, dy + (planet_height / 2),
+			 ((paradise) && (PL_TYPE(*l) == PLSTAR))
+		       ? textColor
+		       : planetColor(l),
+		       l->pl_name, l->pl_namelen, planetFont(l));
+	    cz = new_czone();
+	    cz->x = dx - l->pl_namelen * W_Textwidth / 2;
+	    cz->y = dy + (planet_height / 2);
+	    cz->width = W_Textwidth * l->pl_namelen;
+	    cz->height = W_Textheight;
+	}
+	}
+				/* put letters and number next to */
+				/* planet bitmaps for resources and */
+				/* armies */
+	 if (paradise && tacPlanetInfo) {
+	      if (PL_TYPE(*l) == PLPLANET) {
+		   char dspstr[8];
+		   if (tacPlanetInfo & 1) 
+			sprintf(dspstr, "%d", l->pl_armies);
+		   if ((tacPlanetInfo & 2) && (l->pl_flags & PLREPAIR)) 
+			strcat(dspstr, "R");
+		   if ((tacPlanetInfo & 4) && (l->pl_flags & PLFUEL)) 
+			strcat(dspstr, "F");
+		   if ((tacPlanetInfo & 8) && (l->pl_flags & PLAGRI)) 
+			strcat(dspstr, "A");
+		   if ((tacPlanetInfo & 16) && (l->pl_flags & PLSHIPYARD)) 
+			strcat(dspstr, "S");
+		   cz = new_czone();
+		   cz->x = dx + planet_width/2 + 2;
+		   cz->y = dy;
+		   cz->width = W_Textwidth * strlen(dspstr);
+		   cz->height = W_Textheight;
+		   W_MaskText(w, cz->x, cz->y,
+			      planetColor(l), dspstr, strlen(dspstr),
+				   planetFont(l));
+	      }
+	 }
+
+	/*--------draw tactical lock*/
+	if ((showLock & 2) && (me->p_flags & PFPLLOCK) && (me->p_planet == l->pl_no)) {
+	    W_WriteTriangle(w, dx, dy - (planet_height) / 2 - 6, 5, 0, foreColor);
+	    cz=new_czone();
+	    cz->x=dx-5;
+	    cz->y=dy - (planet_height) / 2 - 12;
+	    cz->width=11;
+	    cz->height=7;
+	}
+	cz = new_czone();
+	if (PL_TYPE(*l) == PLWHOLE) {
+	   cz->x = dx - (wormhole_width / 2);
+	   cz->y = dy - (wormhole_height / 2);
+	   cz->width = wormhole_width;
+	   cz->height = wormhole_height;
+	} else {
+	cz->x = dx - (planet_width / 2);
+	/*cz->y = dy - (planet_height / 2) - 13;*/
+	cz->y = dy - (planet_height / 2);
+	cz->width = planet_width;
+	/*cz->height = planet_height + 26;*/
+	cz->height = planet_height;
+	}
+    }
+}
+
+void 
+doShowMySpeed(dx, dy, ship_bits, j)
+    int     dx, dy;
+    struct ship_shape *ship_bits;
+    struct player *j;
+{
+    struct _clearzone *cz;
+    char    idbuf[5];
+    int     len;
+    int     color;
+
+    sprintf(idbuf, "%c,%d", *(shipnos + j->p_no), me->p_speed);
+    len = strlen(idbuf);
+    /*
+       color the playernum,speed based on warp/afterburn/warpprep state
+       [BDyess]
+    */
+    switch (me->p_flags & (PFWARP | PFAFTER | PFWARPPREP)) {
+    case PFWARP:
+	color = W_Cyan;
+	me->p_flags &= ~PFWARPPREP;
+	break;
+    case PFAFTER:
+	color = rColor;
+	break;
+    case PFWARPPREP:
+	color = yColor;
+	break;
+    default:			/* impulse */
+	if (me->p_speed > 0) {
+	    color = gColor;
+	} else {		/* stopped */
+	    color = textColor;
+	}
+	break;
+    }
+    dx += ship_bits->width / 2;
+    dy -= ship_bits->height / 2;
+    /* underline number,speed if warp is suspended [BDyess] */
+    W_MaskText(w, dx, dy, color, idbuf, len, (me->p_flags & PFWPSUSPENDED) ?
+	       W_UnderlineFont : shipFont(j));
+
+    cz = new_czone();
+    cz->x = dx;
+    cz->y = dy;
+    cz->width = len * W_Textwidth;
+    cz->height = W_Textheight;
+}
+
+#ifdef LOCAL_SHIPSTATS
+/* show just about anything next to ship on local display
+   DSFAPWE - for each letter in statString, show a line for:
+   Damage, Shields, Fuel, Armies, sPeed, Wtemp, Etemp 
+
+   lower case = reverse length
+ */
+static void
+doLocalShipstats()
+{
+    char *sptr;
+    int num=0, len, x=localStatsX, i;
+    struct _clearzone *cz;
+    W_Color color;
+
+    for(sptr=statString;*sptr;sptr++) {
+	switch(toupper(*sptr)) {
+	case 'W':
+	    len=(statHeight*me->p_wtemp) / me->p_ship->s_maxwpntemp;
+	    break;
+	case 'E':
+	    len=(statHeight*me->p_etemp) / me->p_ship->s_maxegntemp;
+	    break;
+	case 'P':
+	    len=(statHeight*me->p_speed)/me->p_ship->s_maxspeed;
+	    break;
+	case 'D':
+	    len=(statHeight*me->p_damage)/me->p_ship->s_maxdamage;
+	    break;
+	case 'S':
+	    len=statHeight - ((statHeight*me->p_shield)/me->p_ship->s_maxshield);
+	    break;
+	case 'F':
+	    len=statHeight - ((statHeight*me->p_fuel)/me->p_ship->s_maxfuel);
+	    break;
+	case 'A':
+	    len= me->p_ship->s_maxarmies ?
+		(statHeight*me->p_armies)/me->p_ship->s_maxarmies : 0;
+	    break;
+	default:
+	    continue;
+	}
+	if(islower(*sptr))
+	    len=statHeight - len;
+	if(len>statHeight)
+	    len=statHeight;
+
+	if(len>2*(statHeight/3) || toupper(*sptr) == 'A')
+	    color=W_Red;
+	else if(len<(statHeight/3))
+	    color=W_Green;
+	else
+	    color=W_Yellow;
+	if(len>0)
+	    W_CacheLine(w,x+W_Textwidth/2,localStatsY-len,x+W_Textwidth/2,localStatsY,color);
+	W_MaskText(w,x,localStatsY+1,W_White,sptr,1,W_RegularFont);
+	x+=W_Textwidth;
+    }
+    if(x>localStatsX) {
+	W_CacheLine(w,localStatsX,localStatsY-statHeight,x,localStatsY-statHeight,W_White);
+	W_CacheLine(w,localStatsX,localStatsY,x,localStatsY,W_White);
+	cz=new_czone();
+	cz->x=localStatsX;
+	cz->y=localStatsY-statHeight+1;
+	cz->width=x-localStatsX;
+	cz->height=statHeight-2;
+    }
+}
+#endif
+
+static void
+local()
+{
+    register int i;
+    register struct player *j;
+    register struct phaser *php;
+    struct _clearzone *cz;
+
+    int     dx, dy;
+    int     view;
+    char    idbuf[10];
+    struct ship_shape *ship_bits;
+    if (showKitchenSink) {
+	cz = new_czone();
+	cz->width = 76;
+	cz->height = 60;
+	cz->x = 500 - cz->width;
+	cz->y = 0;
+	W_WriteBitmap(cz->x, cz->y, kitchenSink, W_Grey);
+    }
+    /*
+       Kludge to try to fix missing ID chars on tactical (short range)
+       display.
+    */
+    idbuf[0] = '0';
+    idbuf[1] = '\0';
+    /* Draw Terrain */
+    redraw_terrain();
+    /* Draw Planets */
+    redraw_all_planets();
+    /* Draw ships */
+    view = SCALE * WINSIDE / 2;
+    for (i = 0, j = &players[i]; i < nplayers; i++, j++) {
+	int     tx, ty;
+	if (me->p_x < 0)
+	    continue;
+
+	/* more efficient than using a separate loop for this */
+	redraw_photon_torps(j);
+	redraw_drones(j);
+	redraw_plasma_torps(j);
+
+	if ((j->p_status != PALIVE) && (j->p_status != PEXPLODE))
+	    continue;
+
+#ifdef UNIX_SOUND
+        if (myPlayer(j) && (j->p_flags & PFCLOAK) &&
+           (j->p_cloakphase == 0)) play_sound (SND_CLOAK);
+        if (myPlayer(j) && (!(j->p_flags & PFCLOAK)) && 
+           (j->p_cloakphase == 6)) play_sound (SND_CLOAK);
+#endif
+
+	if (j->p_flags & PFCLOAK) {
+	    if (j->p_cloakphase < (CLOAK_PHASES - 1)) {
+		j->p_cloakphase++;
+	    }
+	} else {
+	    if (j->p_cloakphase) {
+		j->p_cloakphase--;
+	    }
+	}
+	dx = j->p_x - me->p_x;
+	dy = j->p_y - me->p_y;
+	if (ABS(dx) > view || ABS(dy) > view) {
+	    if(j->p_status == PEXPLODE)
+		j->p_explode++;
+	    continue;
+	}
+	dx = dx / SCALE + WINSIDE / 2;
+	dy = dy / SCALE + WINSIDE / 2;
+	if (j->p_status == PALIVE) {
+
+	    ship_bits = shape_of_ship(j->p_teami, j->p_ship->s_bitmap);
+
+	    if (j->p_flags & PFCLOAK && (j->p_cloakphase == (CLOAK_PHASES - 1))) {
+		if (myPlayer(j)) {
+		    W_WriteBitmap(dx - (cloak_width / 2), dy - (cloak_height / 2),
+				  cloakicon, myColor);
+		    cz = new_czone();
+		    cz->x = dx - (ship_bits->width / 2 + 1);
+		    cz->y = dy - (ship_bits->height / 2 + 1);
+		    cz->width = ship_bits->width + 2;
+		    cz->height = ship_bits->height + 2;
+		    doShields(dx, dy, ship_bits, j);
+#ifdef VARY_HULL
+		    doHull(dx, dy, ship_bits, j);
+#endif				/* VARY_HULL */
+		    if (showMySpeed)
+			doShowMySpeed(dx, dy, ship_bits, j);
+		}
+		continue;
+	    }
+	    cz = new_czone();
+#ifdef BEEPLITE
+	    if (emph_player_seq_n[j->p_no] > 0 &&
+		((F_beeplite_flags & LITE_PLAYERS_LOCAL) ||
+		 ((j == me) && (F_beeplite_flags & LITE_SELF)))) {
+		int     seq_n = emph_player_seq_n[j->p_no] % emph_player_seql_frames;
+
+		cz->x = dx - (emph_player_seql_width / 2);
+		cz->y = dy - (emph_player_seql_height / 2);
+		cz->width = emph_player_seql_width;
+		cz->height = emph_player_seql_height;
+
+		W_WriteBitmap(dx - (emph_player_seql_width / 2),
+			      dy - (emph_player_seql_height / 2),
+			      emph_player_seql[seq_n],
+			      emph_player_color[j->p_no]);
+	    } else
+#endif
+	    {
+		cz->x = dx - (ship_bits->width / 2);
+		cz->y = dy - (ship_bits->height / 2);
+		cz->width = ship_bits->width;
+		cz->height = ship_bits->height;
+	    }
+	    W_WriteBitmap(dx - (ship_bits->width / 2),
+			  dy - (ship_bits->height / 2),
+			  ship_bits->bmap[rosette((int) j->p_dir,
+				 (int) ship_bits->nviews)], playerColor(j));
+	    if (j->p_cloakphase > 0) {
+		W_WriteBitmap(dx - (cloak_width / 2),
+			dy - (cloak_height / 2), cloakicon, playerColor(j));
+		doShields(dx, dy, ship_bits, j);
+		if (j == me) {
+#ifdef VARY_HULL
+		    doHull(dx, dy, ship_bits, j);
+#endif				/* VARY_HULL */
+		    if (showMySpeed)
+			doShowMySpeed(dx, dy, ship_bits, j);
+		}
+		continue;
+	    }
+	    if (showLock & 2) {
+		if ((me->p_flags & PFPLOCK) && (me->p_playerl == j->p_no)) {
+		    W_WriteTriangle(w, dx, dy + (ship_bits->width / 2),
+				    4, 1, foreColor);
+		    cz = new_czone();
+		    cz->x = dx - 4;
+		    cz->y = dy + (ship_bits->height / 2);
+		    cz->width = 9;
+		    cz->height = 5;
+		}
+	    }
+	    doShields(dx, dy, ship_bits, j);
+#ifdef VARY_HULL
+	    doHull(dx, dy, ship_bits, j);
+#endif				/* VARY_HULL */
+	    if (showMySpeed && j == me)
+		doShowMySpeed(dx, dy, ship_bits, j);
+	    else {
+		int     color = playerColor(j);
+		idbuf[0] = *(shipnos + j->p_no);
+
+		W_MaskText(w, dx + (ship_bits->width / 2),
+			   dy - (ship_bits->height / 2), color,
+			   idbuf, 1, shipFont(j));
+
+		cz = new_czone();
+		cz->x = dx + (ship_bits->width / 2);
+		cz->y = dy - (ship_bits->height / 2);
+		cz->width = W_Textwidth;
+		cz->height = W_Textheight;
+	    }
+	} else if (j->p_status == PEXPLODE) {
+	    int     i;
+	    i = j->p_explode;
+	    if (i < EX_FRAMES || (i < SBEXPVIEWS && j->p_ship->s_type == STARBASE)) {
+
+#ifdef SOUND
+		if(i==0)
+		    S_PlaySound(S_EXPLOSION);
+#endif
+#ifdef UNIX_SOUND
+                if (i==0)
+                {
+                    if (j->p_ship->s_type == STARBASE)
+                    play_sound(SND_EXP_SB);         /* Starbase Explode */
+                    else play_sound(SND_EXPLOSION); /* Ship Explosion */
+                }
+#endif 
+    
+		cz = new_czone();
+		if (j->p_ship->s_type == STARBASE) {
+		    W_WriteBitmap(dx - (sbexp_width / 2),
+				  dy - (sbexp_height / 2), sbexpview[i],
+				  playerColor(j));
+		    cz->x = dx - (sbexp_width / 2);
+		    cz->y = dy - (sbexp_height / 2);
+		    cz->width = sbexp_width;
+		    cz->height = sbexp_height;
+		} else {
+		    W_WriteBitmap(dx - (ex_width / 2), dy - (ex_height / 2),
+				  expview[i], playerColor(j));
+		    cz->x = dx - (ex_width / 2);
+		    cz->y = dy - (ex_height / 2);
+		    cz->width = ex_width;
+		    cz->height = ex_height;
+		}
+		j->p_explode++;
+	    }
+	}
+	/* Now draw his phaser (if it exists) */
+	php = &phasers[j->p_no];
+	if (php->ph_status != PHFREE) {
+	    if (php->ph_status == PHMISS) {
+		/* Here I will have to compute end coordinate */
+		tx = j->p_x + j->p_ship->s_phaserrange * Cos[php->ph_dir];
+		ty = j->p_y + j->p_ship->s_phaserrange * Sin[php->ph_dir];
+		tx = (tx - me->p_x) / SCALE + WINSIDE / 2;
+		ty = (ty - me->p_y) / SCALE + WINSIDE / 2;
+	    } else if (php->ph_status == PHHIT2) {
+		tx = (php->ph_x - me->p_x) / SCALE + WINSIDE / 2;
+		ty = (php->ph_y - me->p_y) / SCALE + WINSIDE / 2;
+	    } else {		/* Start point is dx, dy */
+		tx = (players[php->ph_target].p_x - me->p_x) /
+		    SCALE + WINSIDE / 2;
+		ty = (players[php->ph_target].p_y - me->p_y) /
+		    SCALE + WINSIDE / 2;
+	    }
+
+
+	    php->ph_fuse++;
+
+#ifdef CHECK_DROPPED
+	    if (php->ph_fuse > longest_ph_fuse + 1 && php->ph_status != PHGHOST) {
+		if (reportDroppedPackets)
+		    printf("Dropped phaser free, player %d (fuse)\n", j->p_no);
+		php->ph_status = PHGHOST;
+	    }
+	    if (php->ph_status != PHGHOST) {
+#endif
+#ifdef W_PHASERLINE
+/*
+ * an old redraw.c I used for the Amiga port(not this port) had this.
+ * Draws a dashed line instead of solid..different pattern from tractor
+ * lines.   At least that's what I guessed for amigawindow.c :-) -JR
+ */
+
+		if (j->p_teami != me->p_teami)
+		    W_MakePhaserLine(w, dx, dy, tx, ty,
+			    (php->ph_fuse % 2 && php->ph_status != PHMISS) ?
+				     foreColor :
+				     shipCol[1 + j->p_teami],
+				     php->ph_fuse);
+		else
+#endif
+		{
+		    W_Color ph_col;
+		    if (jubileePhasers) {
+
+			switch (php->ph_fuse % 4) {
+			case 0:
+			    ph_col = W_Red;
+			    break;
+			case 1:
+			    ph_col = W_Yellow;
+			    break;
+			case 2:
+			    ph_col = W_Green;
+			    break;
+			case 3:
+			    ph_col = W_Cyan;
+			    break;
+			}
+			if (php->ph_status == PHMISS)
+			    ph_col = W_White;
+		    } else {
+			ph_col = (php->ph_fuse % 2 && php->ph_status != PHMISS) ?
+			    foreColor :
+			    shipCol[1 + j->p_teami];
+		    }
+		    W_CacheLine(w, dx, dy, tx, ty, ph_col);
+		}
+		clearline[0][clearlcount] = dx;
+		clearline[1][clearlcount] = dy;
+		clearline[2][clearlcount] = tx;
+		clearline[3][clearlcount] = ty;
+		clearlcount++;
+#ifdef CHECK_DROPPED
+	    }			/* PHGHOST */
+#endif
+	}
+    }
+
+    /* ATM - show tractor/pressor beams (modified by James Collins) */
+    /* showTractorPressor is a variable set by xtrekrc. */
+    /* modified to show all T/P's 1/28/94 [BDyess] */
+    /* fixed display bug 1/29/94 [BDyess] */
+    dx = WINSIDE / 2;
+    dy = WINSIDE / 2;
+    if (showTractorPressor) {
+	double  theta;
+	unsigned char dir;
+	int     lx[2], ly[2], px, py, target_width;
+	struct player *victim = &players[me->p_tractor];
+	int     last;
+	if (paradise && showAllTractorPressor && allowShowAllTractorPressor) {
+	    /* check everybody */
+	    last = nplayers;
+	    j = &players[0];
+	    i = 0;
+	} else {
+	    /* only check self */
+	    last = me->p_no + 1;
+	    j = me;
+	    i = me->p_no;
+	}
+	for (; i < last; i++, j++) {
+	    if (!(j->p_flags & (PFTRACT | PFPRESS) && isAlive(j)))
+		continue;
+	    if (!paradise && RSA_Client > 0 && j != me)
+		continue;
+	    victim = &players[j->p_tractor];
+	    if (victim->p_flags & PFCLOAK)
+		break;		/* can't see tractors on cloaked opponents */
+	    if (j == me) {
+		dx = dy = WINSIDE / 2;
+	    } else {
+		dx = (j->p_x - me->p_x) / SCALE + WINSIDE / 2;
+		dy = (j->p_y - me->p_y) / SCALE + WINSIDE / 2;
+	    }
+	    if (PtOutsideWin(dx, dy))
+		continue;	/* he's off the screen */
+	    px = (victim->p_x - me->p_x) / SCALE + WINSIDE / 2;
+	    py = (victim->p_y - me->p_y) / SCALE + WINSIDE / 2;
+	    if (px == dx && py == dy)
+		break;
+#define XPI     3.1415926
+	    theta = atan2((double) (px - dx), (double) (dy - py)) + XPI / 2.0;
+	    dir = (unsigned char) (theta / XPI * 128.0);
+	    target_width = shape_of_ship(victim->p_teami,
+					 victim->p_ship->s_bitmap)->width;
+	    if (!(victim->p_flags & PFSHIELD))
+		target_width /= 2;
+	    lx[0] = px + (Cos[dir] * (target_width / 2));
+	    ly[0] = py + (Sin[dir] * (target_width / 2));
+	    lx[1] = px - (Cos[dir] * (target_width / 2));
+	    ly[1] = py - (Sin[dir] * (target_width / 2));
+#undef XPI
+	    if (j->p_flags & PFPRESS) {
+		W_MakeTractLine(w, dx, dy, lx[0], ly[0], W_Yellow);
+		W_MakeTractLine(w, dx, dy, lx[1], ly[1], W_Yellow);
+	    } else {
+		W_MakeTractLine(w, dx, dy, lx[0], ly[0], W_Green);
+		W_MakeTractLine(w, dx, dy, lx[1], ly[1], W_Green);
+	    }
+	    /*
+	       keeping track of tractors seperately from other lines allows
+	       clearing them diffently.  Clearing them the same as other
+	       solid lines caused occasional bits to be left on the screen.
+	       This is the fix.  [BDyess]
+	    */
+	    if (tractcurrent == NULL) {	/* just starting */
+		tractcurrent = tracthead = (Tractor *) malloc(sizeof(Tractor));
+		tracthead->next = NULL;
+	    }
+	    tractcurrent->sx = dx;
+	    tractcurrent->sy = dy;
+	    tractcurrent->d1x = lx[0];
+	    tractcurrent->d1y = ly[0];
+	    tractcurrent->d2x = lx[1];
+	    tractcurrent->d2y = ly[1];
+	    /* get ready for the next run through */
+	    if (tractcurrent->next) {	/* already malloc'd before */
+		tractcurrent = tractcurrent->next;
+	    } else {		/* new maximum, create a new struct */
+		tractcurrent->next = (Tractor *) malloc(sizeof(Tractor));
+		tractcurrent = tractcurrent->next;
+		tractcurrent->next = NULL;
+	    }
+	}
+    }
+    /* changed torps/drones/plasmas to one call per player, in the above loop */
+    /* still have leftover drones to draw: */
+    redraw_other_drones();
+
+    /* Draw Edges */
+    if (me->p_x < (WINSIDE / 2) * SCALE) {
+	int     sy, ey;
+	dx = (WINSIDE / 2) - (me->p_x) / SCALE;
+	sy = (WINSIDE / 2) + (0 - me->p_y) / SCALE;
+	ey = (WINSIDE / 2) + (blk_gwidth - me->p_y) / SCALE;
+	if (sy < 0)
+	    sy = 0;
+	if (ey > WINSIDE - 1)
+	    ey = WINSIDE - 1;
+	/* XFIX */
+	W_CacheLine(w, dx, sy, dx, ey, warningColor);
+	/*
+	   W_MakeLine(w, dx, sy, dx, ey, warningColor);
+	*/
+	clearline[0][clearlcount] = dx;
+	clearline[1][clearlcount] = sy;
+	clearline[2][clearlcount] = dx;
+	clearline[3][clearlcount] = ey;
+	clearlcount++;
+    }
+    if ((blk_gwidth - me->p_x) < (WINSIDE / 2) * SCALE) {
+	int     sy, ey;
+	dx = (WINSIDE / 2) + (blk_gwidth - me->p_x) / SCALE;
+	sy = (WINSIDE / 2) + (0 - me->p_y) / SCALE;
+	ey = (WINSIDE / 2) + (blk_gwidth - me->p_y) / SCALE;
+	if (sy < 0)
+	    sy = 0;
+	if (ey > WINSIDE - 1)
+	    ey = WINSIDE - 1;
+	/* XFIX */
+	W_CacheLine(w, dx, sy, dx, ey, warningColor);
+	/*
+	   W_MakeLine(w, dx, sy, dx, ey, warningColor);
+	*/
+	clearline[0][clearlcount] = dx;
+	clearline[1][clearlcount] = sy;
+	clearline[2][clearlcount] = dx;
+	clearline[3][clearlcount] = ey;
+	clearlcount++;
+    }
+    if (me->p_y < (WINSIDE / 2) * SCALE) {
+	int     sx, ex;
+	dy = (WINSIDE / 2) - (me->p_y) / SCALE;
+	sx = (WINSIDE / 2) + (0 - me->p_x) / SCALE;
+	ex = (WINSIDE / 2) + (blk_gwidth - me->p_x) / SCALE;
+	if (sx < 0)
+	    sx = 0;
+	if (ex > WINSIDE - 1)
+	    ex = WINSIDE - 1;
+	/* XFIX */
+	W_CacheLine(w, sx, dy, ex, dy, warningColor);
+	/*
+	   W_MakeLine(w, sx, dy, ex, dy, warningColor);
+	*/
+	clearline[0][clearlcount] = sx;
+	clearline[1][clearlcount] = dy;
+	clearline[2][clearlcount] = ex;
+	clearline[3][clearlcount] = dy;
+	clearlcount++;
+    }
+    if ((blk_gwidth - me->p_y) < (WINSIDE / 2) * SCALE) {
+	int     sx, ex;
+	dy = (WINSIDE / 2) + (blk_gwidth - me->p_y) / SCALE;
+	sx = (WINSIDE / 2) + (0 - me->p_x) / SCALE;
+	ex = (WINSIDE / 2) + (blk_gwidth - me->p_x) / SCALE;
+	if (sx < 0)
+	    sx = 0;
+	if (ex > WINSIDE - 1)
+	    ex = WINSIDE - 1;
+	/* XFIX */
+	W_CacheLine(w, sx, dy, ex, dy, warningColor);
+	/*
+	   W_MakeLine(w, sx, dy, ex, dy, warningColor);
+	*/
+	clearline[0][clearlcount] = sx;
+	clearline[1][clearlcount] = dy;
+	clearline[2][clearlcount] = ex;
+	clearline[3][clearlcount] = dy;
+	clearlcount++;
+    }
+    /* Change border color to signify alert status */
+
+#ifdef UNIX_SOUND
+    if (oldalert != (me->p_flags & (PFGREEN | PFYELLOW | PFRED))) 
+    {
+      if (me->p_flags & PFRED)
+            maybe_play_sound (SND_REDALERT);   /* Red Alert, play ONLY once */
+      else  sound_completed  (SND_REDALERT);   /* Done with Red Alert */
+    }
+#endif
+
+    if (oldalert != (me->p_flags & (PFGREEN | PFYELLOW | PFRED))) {
+	if(paradise && auto_zoom_timer<udcounter && (autoZoom || autoUnZoom)) {
+	    int old_zoom=blk_zoom;
+	    switch(autoZoom) {
+	    case 1:
+		if(me->p_flags & (PFYELLOW | PFRED))
+		    blk_zoom = 1;
+		break;
+	    case 2:
+		if(me->p_flags & (PFRED))
+		    blk_zoom = 1;
+		break;
+	    }
+	    switch(autoUnZoom) {
+	    case 1:
+		if(me->p_flags & (PFGREEN))
+		    blk_zoom = 0;
+		break;
+	    case 2:
+		if(me->p_flags & (PFYELLOW | PFGREEN))
+		    blk_zoom = 0;
+		break;
+	    }
+	    if(old_zoom != blk_zoom)
+		redrawall=1;
+	}
+	oldalert = (me->p_flags & (PFGREEN | PFYELLOW | PFRED));
+	if (infoIcon && iconified)
+	    drawIcon();
+	switch (oldalert) {
+	case PFGREEN:
+	    if (extraBorder)
+		W_ChangeBorder(w, gColor);
+	    W_ChangeBorder(baseWin, gColor);
+	    W_ChangeBorder(iconWin, gColor);
+	    break;
+	case PFYELLOW:
+	    if (extraBorder)
+		W_ChangeBorder(w, yColor);
+	    W_ChangeBorder(baseWin, yColor);
+	    W_ChangeBorder(iconWin, yColor);
+	    break;
+	case PFRED:
+	    if (extraBorder)
+		W_ChangeBorder(w, rColor);
+	    W_ChangeBorder(baseWin, rColor);
+	    W_ChangeBorder(iconWin, rColor);
+	    break;
+	}
+    }
+    /* draw stars */
+
+    if (blk_showStars)
+	drawStars();
+
+#ifdef LOCAL_SHIPSTATS
+    if(localShipStats)
+	doLocalShipstats();
+#endif
+
+
+}
+#define DRAWGRID		4
+
+int
+zoom_offset(v)
+    int     v;
+{
+    if (blk_zoom) {
+	register gwidth, ov;
+	/* dimension of zoom area */
+	gwidth = blk_gwidth / 2;
+	/* offset to bring us into new zoom area */
+	ov = (v / (int) gwidth) * gwidth;
+	if (blk_zoom > 1)
+	    return ov;
+	else
+	    /* sector offset into new zoom area */
+	    return ov + (((v - ov) / GRIDSIZE) * GRIDSIZE) - GRIDSIZE;
+    } else
+	return v;
+}
+
+#ifdef HOCKEY
+void galactic_hockey P((void));
+#endif
+
+#ifndef COW_HAS_IT_WHY_SHOULDNT_WE
+static 
+#endif
+void
+map()
+{
+    int     nplan;
+    register int i, k, tmp = blk_gwidth/250;
+    register struct player *j;
+    register struct planet *l;
+    register int dx, dy, odx, ody;
+    static  osx = 0, osy = 0;	/* old square */
+    static  last_offsetx, last_offsety;
+    static int grid_fuse;	/* TSH */
+    register int gwidth, offsetx, offsety;
+    int     color, pl = 0;
+    /*
+       last_lock is used to hold the begin/end point for lock line; [0] holds
+       me->; [1] holds target lock; lockx[2] holds status of line so we can
+       erase if line is there but lock if off
+    */
+    static  last_lockx[3] = {0, 0, 0}, last_locky[2];
+    int     me_galx, me_galy;
+
+    grid_fuse++;		/* we only draw the grids every DRAWGRID
+				   interval */
+
+    /* set number of planets for later */
+    nplan = (paradise) ? nplanets : 40;
+
+    if (reinitPlanets) {
+	initPlanets();
+	reinitPlanets = 0;
+#ifdef HOCKEY
+	/* planets moved so the lines need updating [BDyess] */
+	if(hockey) hockeyInit();
+#endif /*HOCKEY*/
+    }
+
+#ifdef HOCKEY
+    galactic_hockey();
+#endif /*HOCKEY*/
+
+    if (blk_zoom) {
+	gwidth = blk_gwidth / 2;
+	offsetx = zoom_offset(me->p_x);
+	offsety = zoom_offset(me->p_y);
+
+	if (offsetx != last_offsetx || offsety != last_offsety)
+	    redrawall = 1;
+
+	last_offsetx = offsetx;
+	last_offsety = offsety;
+    } else {
+	gwidth = blk_gwidth;
+	offsetx = 0;
+	offsety = 0;
+    }
+
+    me_galx = (me->p_x - offsetx) * WINSIDE / gwidth;
+    me_galy = (me->p_y - offsety) * WINSIDE / gwidth;
+
+/* draw asteroid dots -- this is a test only.  MDM */
+    if( received_terrain_info && paradise ){
+      /* but avoid that SEGV! */
+      for( i = 0; i < 250; i++ ){
+        for( k = udcounter%10; k < 250; k += 10){
+          if(terrainInfo[i*250+k].types & T_ASTEROIDS) {
+            W_DrawPoint( mapw, 
+	                (i*tmp - offsetx) * WINSIDE / gwidth,
+	                (k*tmp - offsety) * WINSIDE / gwidth, 
+			W_White);
+	  }
+	  if (terrainInfo[i*250+k].types & T_NEBULA) {
+	     W_DrawPoint( mapw, 
+			 ((i*tmp - offsetx) * WINSIDE / gwidth) + 1,
+			 ((k*tmp - offsety) * WINSIDE / gwidth) + 1, 
+			 W_Red);
+	  }
+        }
+      }
+    }
+
+    if (redrawall)
+	W_ClearWindow(mapw);
+
+    /* draw grid on galactic */
+    if ((redrawall || (grid_fuse % DRAWGRID) == 0) && (paradise) && (drawgrid)) {
+	int     x, y, w, h, grid;
+	char    numbuf[1];
+	grid = GRIDSIZE * WINSIDE / gwidth;
+	for (i = 1; i <= 6 / (blk_zoom ? 2 : 1); i++) {
+	    /* looks nasty but we only have to do it 3 times if blk_zoom */
+
+	    /* horizontal line */
+	    x = 0;
+	    y = i * grid;
+	    w = WINSIDE;
+	    numbuf[0] = '0' + (char) i;
+	    if (blk_zoom) {
+		/* we might have to clip */
+		dy = i * GRIDSIZE + offsety;
+		if (dy >= 0 && dy <= blk_gwidth + 2 * GRIDSIZE) {
+		    if (offsetx < 0) {
+			x = grid;
+			w = 2 * x;
+		    } else if (offsetx + 3 * GRIDSIZE > blk_gwidth) {
+			w = 2 * grid;
+		    }
+		    W_MakeTractLine(mapw, x, y, x + w, y, W_Grey);
+		}
+		if (sectorNums) {
+		    numbuf[0] = '0' + (char) (i + offsety / 33333);
+		    if ((numbuf[0] == '0') || (numbuf[0] == '7'))
+			numbuf[0] = ' ';
+		    if (i == 1)	/* so numbers dont overwrite in 1st box */
+			W_WriteText(mapw, x + 2, y - grid + 11, W_Grey, numbuf, 1,
+				    W_RegularFont);
+		    else
+			W_WriteText(mapw, x + 2, y - grid + 2, W_Grey, numbuf, 1,
+				    W_RegularFont);
+		}
+	    } else {
+		W_MakeTractLine(mapw, x, y, x + w, y, W_Grey);
+		if (sectorNums) {
+		    W_WriteText(mapw, x + 2, y - grid + 2, W_Grey, numbuf, 1, W_RegularFont);
+		}
+	    }
+	    /* vertical line */
+	    x = i * grid;
+	    y = 0;
+	    h = WINSIDE;
+
+	    if (blk_zoom) {
+		/* we might have to clip */
+		dx = i * GRIDSIZE + offsetx;
+		if (dx >= 0 && dx <= blk_gwidth + 2 * GRIDSIZE) {
+		    if (offsety < 0) {
+			y = grid;
+			h = 2 * y;
+		    } else if (offsety + 3 * GRIDSIZE > blk_gwidth) {
+			h = 2 * grid;
+		    }
+		    W_MakeTractLine(mapw, x, y, x, y + h, W_Grey);
+		}
+		if (sectorNums) {
+		    numbuf[0] = '0' + (char) (i + offsetx / 33333);
+		    if ((numbuf[0] == '0') || (numbuf[0] == '7'))
+			numbuf[0] = ' ';
+		    if (i == 1)
+			W_WriteText(mapw, x - grid + 11, y + 2, W_Grey, numbuf, 1,
+				    W_RegularFont);
+		    else
+			W_WriteText(mapw, x - grid + 2, y + 2, W_Grey, numbuf, 1,
+				    W_RegularFont);
+		}
+	    } else {
+		W_MakeTractLine(mapw, x, y, x, y + h, W_Grey);
+		if (sectorNums) {
+		    W_WriteText(mapw, x - grid + 2, y + 2, W_Grey, numbuf, 1,
+				W_RegularFont);
+		}
+	    }
+	}
+
+	dx = ((me->p_x - offsetx) / GRIDSIZE) * GRIDSIZE;
+	dy = ((me->p_y - offsety) / GRIDSIZE) * GRIDSIZE;
+	if (!redrawall && ((osx != dx) || (osy != dy))) {
+
+	    /* clear old sector */
+	    x = osx * WINSIDE / gwidth;
+	    y = osy * WINSIDE / gwidth;
+	    w = h = grid;
+
+	    W_DrawSectorHighlight(mapw, x, y, w, h, backColor);
+
+	    osx = dx;
+	    osy = dy;
+	}
+	/* draw our current sector */
+	x = dx * WINSIDE / gwidth;
+	w = h = grid;
+	y = dy * WINSIDE / gwidth;
+
+	W_DrawSectorHighlight(mapw, x, y, w, h, yColor);
+    }
+    /* Erase ships */
+    for (i = 0, j = &players[i]; i < nplayers; i++, j++) {
+	lastUpdate[i]++;
+	/*
+	   Erase the guy if: redrawPlayer[i] is set and the mapmode setting
+	   allows it.
+	*/
+	if (!redrawPlayer[i] || (mapmode == GMAP_INFREQUENT && lastUpdate[i] < 5))
+	    continue;
+	lastUpdate[i] = 0;
+	/* Clear his old image... */
+	if (mclearzone[2][i]) {
+	    /* XFIX */
+	    if (!redrawall) {
+		W_ClearArea(mapw, mclearzone[0][i], mclearzone[1][i],
+			    mclearzone[2][i], mclearzone[3][i]);
+		/* Redraw the hole just left next update */
+		checkRedraw(mclearzone[4][i], mclearzone[5][i]);
+	    }
+	    mclearzone[2][i] = 0;
+	}
+    }
+    /* Draw Planets */
+#ifdef HOCKEY
+    if(! (hockey && cleanHockeyGalactic)) {
+#endif
+      for (i = 0, l = &planets[i]; i < nplan; i++, l++) {
+	  char    buf[4];
+	  int     color;
+	  if (!(l->pl_flags & PLREDRAW) && (!redrawall))
+	      continue;
+	  l->pl_flags &= ~PLREDRAW;	/* Turn redraw flag off! */
+
+	  dx = (l->pl_x - offsetx) * WINSIDE / gwidth;
+	  dy = (l->pl_y - offsety) * WINSIDE / gwidth;
+
+	  if (PtOutsideWin(dx, dy))
+	      continue;
+
+	  if (0 == strncmp(l->pl_name, "New ", 4)) {
+	      strncpy(buf, l->pl_name + 4, 3);
+	  } else if (0 == strncmp(l->pl_name, "Planet ", 7)) {
+	      strncpy(buf, l->pl_name + 7, 3);
+	  } else
+	      strncpy(buf, l->pl_name, 3);
+
+	  /* moving planets */
+	  if (pl_update[l->pl_no].plu_update == 1) {
+	      odx = (pl_update[l->pl_no].plu_x - offsetx) * WINSIDE / gwidth;
+	      ody = (pl_update[l->pl_no].plu_y - offsety) * WINSIDE / gwidth;
+
+	      /* XFIX */
+	      W_ClearArea(mapw, odx - (mplanet_width / 2), ody - (mplanet_height / 2),
+			  mplanet_width, mplanet_height);
+
+	      W_WriteText(mapw, odx - (mplanet_width / 2), ody + (mplanet_height / 2),
+			  backColor, buf, 3, planetFont(l));
+
+	      pl_update[l->pl_no].plu_update = 0;
+	  }
+#if 0
+/* not necessary, pl_update is now set whenever a planet needs to be
+ * erased. -JR
+ */
+	  else {
+
+	      /* XFIX */
+	      W_ClearArea(mapw, dx - (mplanet_width / 2), dy - (mplanet_height / 2),
+			  mplanet_width, mplanet_height);
+	  }
+#endif
+	  color = ((paradise) && (l->pl_flags & (PLSTAR | PLWHOLE))) ?
+	      textColor : planetColor(l);
+#ifdef BEEPLITE
+	  if (UseLite && emph_planet_seq_n[l->pl_no] > 0 &&
+	      (F_beeplite_flags & LITE_PLANETS)) {
+	      int     seq_n = emph_planet_seq_n[l->pl_no] % emph_planet_seq_frames;
+
+	      if ((emph_planet_seq_n[l->pl_no] -= 1) > 0)
+		  W_OverlayBitmap(dx - (emph_planet_seq_width / 2),
+				  dy - (emph_planet_seq_height / 2),
+				  emph_planet_seq[seq_n],
+				  emph_planet_color[l->pl_no]);
+	      else
+		  W_ClearArea(mapw, dx - (emph_planet_seq_width / 2),
+			      dy - (emph_planet_seq_height / 2),
+			      emph_planet_seq_width, emph_planet_seq_height);
+	      W_WriteBitmap(dx - (mplanet_width / 2), dy - (mplanet_height / 2),
+			    planetmBitmap(l), color);
+	      l->pl_flags |= PLREDRAW;	/* Leave redraw on until done
+					     highlighting */
+	      pl_update[l->pl_no].plu_update = 1;
+	  } else
+#endif
+          if (!(PL_TYPE(*l) == PLWHOLE)) { /* non wormholes */
+	  W_WriteBitmap(dx - (mplanet_width / 2), dy - (mplanet_height / 2),
+			    planetmBitmap(l), color);
+	  W_WriteText(mapw, dx - (mplanet_width / 2), dy + (mplanet_height / 2),
+		      color, buf, ((strlen(buf) >= 3) ? 3 : strlen(buf)),
+		      planetFont(l));
+#ifdef SHOW_IND
+	  if (showIND && (l->pl_info & idx_to_mask(me->p_teami)) && (l->pl_owner == NOBODY) && l->pl_flags & PLPLANET)
+	  {
+	      W_MakeLine (mapw, dx + (mplanet_width / 2 - 1), dy + (mplanet_height / 2 - 1),
+			  dx - (mplanet_width / 2), dy - (mplanet_height / 2),
+			  W_White);
+	      W_MakeLine (mapw, dx - (mplanet_width / 2), dy + (mplanet_height / 2 - 1),
+			  dx + (mplanet_width / 2 - 1), dy - (mplanet_height / 2),
+			  W_White);
+	  }
+#endif
+	  } 
+#ifdef VISIBLE_WORMHOLES
+	  else { /* wormholes show when scouted [BDyess] */
+	    if(l->pl_info & idx_to_mask(me->p_teami)) { /* have info [BDyess]*/
+	      printf("l->pl_info == %d\n",l->pl_info);
+	      W_WriteBitmap(dx - (mplanet_width / 2), 
+	                    dy - (mplanet_height / 2),
+			    planetmBitmap(l), 
+			    color);
+	    }
+	  }
+#endif /*VISIBLE_WORMHOLES*/
+#ifdef HOCKEY
+    }
+#endif
+    /* Draw ships */
+    for (i = 0, j = &players[i]; i < nplayers; i++, j++) {
+	/*
+	   We draw the guy if redrawall, or we just erased him. Also, we
+	   redraw if we haven't drawn for 30 frames. (in case he was erased
+	   by other ships).
+	*/
+	if (lastUpdate[i] != 0 && (!redrawall) && lastUpdate[i] < 30)
+	    continue;
+	if (j->p_status != PALIVE)
+	    continue;
+	lastUpdate[i] = 0;
+	dx = (j->p_x - offsetx) * WINSIDE / gwidth;
+	dy = (j->p_y - offsety) * WINSIDE / gwidth;
+
+	if ((showLock & 1) && !(j->p_flags & PFCLOAK)) {
+	    if ((me->p_flags & PFPLOCK) && (me->p_playerl == j->p_no)) {
+		if (lockLine) {
+		    if ((last_lockx[0] != me_galx) || (last_locky[0] != me_galx) ||
+			(last_lockx[1] != dx) || (last_locky[1] != dy)) {
+			W_MakeTractLine(mapw, last_lockx[0], last_locky[0],
+				   last_lockx[1], last_locky[1], backColor);
+			last_lockx[0] = me_galx;
+			last_locky[0] = me_galy;
+			last_lockx[1] = dx;
+			last_locky[1] = dy;
+			last_lockx[2] = 1;
+			W_MakeTractLine(mapw, last_lockx[0], last_locky[0],
+				     last_lockx[1], last_locky[1], W_Green);
+
+		    }
+		}
+		W_WriteTriangle(mapw, dx, dy + 6, 4, 1, foreColor);
+		pl = 1;
+	    }
+	}
+	if (PtOutsideWin(dx, dy))
+	    continue;
+
+	if (blk_friendlycloak == 1) {
+	    if (j->p_flags & PFCLOAK) {
+		if (myPlayer(j))
+		    color = myColor;
+		else if (friendlyPlayer(j))
+		    color = playerColor(j);
+		else
+		    color = unColor;
+	    } else
+		color = playerColor(j);
+
+	    pl = 0;
+	    if (j->p_flags & PFCLOAK)
+		W_WriteText(mapw, dx - W_Textwidth * cloakcharslen / 2,
+		    dy - W_Textheight / 2, color, cloakchars, cloakcharslen,
+			    W_RegularFont);
+	    else
+		W_WriteText(mapw, dx - W_Textwidth,
+			    dy - W_Textheight / 2, color, j->p_mapchars, 2,
+			    shipFont(j));
+	} else {
+	    if (j->p_flags & PFCLOAK) {
+		W_WriteText(mapw, dx - W_Textwidth * cloakcharslen / 2,
+		  dy - W_Textheight / 2, unColor, cloakchars, cloakcharslen,
+			    W_RegularFont);
+	    } else {
+		W_WriteText(mapw, dx - W_Textwidth,
+		    dy - W_Textheight / 2, playerColor(j), j->p_mapchars, 2,
+			    shipFont(j));
+	    }
+	}
+
+#ifdef BEEPLITE
+	if (UseLite && emph_player_seq_n[i] > 0 &&
+	    (F_beeplite_flags & LITE_PLAYERS_MAP)) {
+	    int     seq_n = emph_player_seq_n[i] % emph_player_seq_frames;
+
+	    W_WriteBitmap(dx - (emph_player_seq_width / 2 - 1),
+			  dy - (emph_player_seq_height / 2 + 1),
+			  emph_player_seq[seq_n],
+			  emph_player_color[i]);
+	    emph_player_seq_n[i] -= 1;
+	    mclearzone[0][i] = dx - (emph_player_seq_width / 2 - 1);
+	    mclearzone[1][i] = dy - (emph_player_seq_height / 2 + 1);
+	    mclearzone[2][i] = emph_player_seq_width;
+	    mclearzone[3][i] = emph_player_seq_height;
+	    mclearzone[4][i] = j->p_x;
+	    mclearzone[5][i] = j->p_y;
+	    /*
+	       Force redraw for this guy no matter what. Even if stationary.
+	    */
+	    lastUpdate[i] = 30;
+	    /* Leave redraw on until done highlighting */
+	    redrawPlayer[i] = 1;
+	} else
+#endif
+	{
+	    if (j->p_flags & PFCLOAK) {
+		mclearzone[0][i] = dx - W_Textwidth * cloakcharslen / 2;
+		mclearzone[1][i] = dy - W_Textheight / 2;
+		mclearzone[2][i] = W_Textwidth * cloakcharslen;
+	    } else {
+		mclearzone[0][i] = dx - W_Textwidth;
+		mclearzone[1][i] = dy - W_Textheight / 2;
+		mclearzone[2][i] = W_Textwidth * 2;
+	    }
+	    if (pl)
+		mclearzone[3][i] = W_Textheight + 8;
+	    else
+		mclearzone[3][i] = W_Textheight;
+	    /* Set these so we can checkRedraw() next time */
+	    mclearzone[4][i] = j->p_x;
+	    mclearzone[5][i] = j->p_y;
+	    redrawPlayer[i] = 0;
+	}
+    }
+    /* draw viewBox if wanted [BDyess] */
+#define VIEWDIST SCALE * WINSIDE * WINSIDE / (gwidth * 2)
+#define REDRAWDIST SCALE * WINSIDE / 2
+    if (viewBox && allowViewBox) {
+	static int viewx = 0, viewy = 0;
+
+	dx = (me->p_x - offsetx) * WINSIDE / gwidth;
+	dy = (me->p_y - offsety) * WINSIDE / gwidth;
+	if (viewx != dx || viewy != dy || redrawall) {
+	    /* clear old dots - placed here for less flicker */
+	    W_DrawPoint(mapw, viewx + VIEWDIST, viewy + VIEWDIST, backColor);
+	    W_DrawPoint(mapw, viewx + VIEWDIST, viewy - VIEWDIST, backColor);
+	    W_DrawPoint(mapw, viewx - VIEWDIST, viewy + VIEWDIST, backColor);
+	    W_DrawPoint(mapw, viewx - VIEWDIST, viewy - VIEWDIST, backColor);
+	    /* redraw any planets they overwrote */
+	    viewx *= gwidth / WINSIDE + offsetx;	/* correct from view
+							   scale */
+	    viewy *= gwidth / WINSIDE + offsety;
+	    checkRedraw(viewx + REDRAWDIST, viewy + REDRAWDIST);
+	    checkRedraw(viewx + REDRAWDIST, viewy - REDRAWDIST);
+	    checkRedraw(viewx - REDRAWDIST, viewy + REDRAWDIST);
+	    checkRedraw(viewx - REDRAWDIST, viewy - REDRAWDIST);
+	    /* draw the new points */
+	    W_DrawPoint(mapw, dx + VIEWDIST, dy + VIEWDIST, W_White);
+	    W_DrawPoint(mapw, dx + VIEWDIST, dy - VIEWDIST, W_White);
+	    W_DrawPoint(mapw, dx - VIEWDIST, dy + VIEWDIST, W_White);
+	    W_DrawPoint(mapw, dx - VIEWDIST, dy - VIEWDIST, W_White);
+	    viewx = dx;		/* store the points for later */
+	    viewy = dy;		/* clearing */
+	}
+    }
+#undef VIEWDIST
+#undef REDRAWDIST
+
+    if (clearlmcount) {
+	W_WriteTriangle(mapw, clearlmark[0], clearlmark[1], 4, 0, backColor);
+	clearlmcount--;
+    }
+    if (showLock & 1) {
+	/* for now draw this everytime */
+	if ((me->p_flags & PFPLLOCK) && (me->p_status != POBSERVE)) {
+	    struct planet *l = &planets[me->p_planet];
+	    dx = (l->pl_x - offsetx) * WINSIDE / gwidth;
+	    dy = (l->pl_y - offsety) * WINSIDE / gwidth;
+
+	    if (lockLine) {
+		if ((last_lockx[0] != me_galx) || (last_locky[0] != me_galx) ||
+		    (last_lockx[1] != dx) || (last_locky[1] != dy)) {
+		    W_MakeTractLine(mapw, last_lockx[0], last_locky[0],
+				    last_lockx[1], last_locky[1], backColor);
+		    last_lockx[0] = me_galx;
+		    last_locky[0] = me_galy;
+		    last_lockx[1] = dx;
+		    last_locky[1] = dy;
+		    last_lockx[2] = 1;
+		    W_MakeTractLine(mapw, last_lockx[0], last_locky[0],
+				    last_lockx[1], last_locky[1], W_Green);
+		}
+	    }
+	    if (!PtOutsideWin(dx, dy)) {
+		W_WriteTriangle(mapw, dx, dy - (mplanet_height) / 2 - 4, 4, 0,
+				foreColor);
+		clearlmark[0] = dx;
+		clearlmark[1] = dy - (mplanet_height) / 2 - 4;
+		clearlmcount++;
+	    }
+	}
+    }
+    /* if lock line is drawn but no lock; erase lock line */
+    if (lockLine && ((me->p_flags & (PFPLLOCK | PFPLOCK)) == 0) && last_lockx[2]) {
+	W_MakeTractLine(mapw, last_lockx[0], last_locky[0], last_lockx[1],
+			last_locky[1], backColor);
+	last_lockx[2] = 0;
+    }
+    /* redraw warp beacon routes */
+
+    for (i = 0; i < ngthingies; i += 2) {
+	struct thingy *k = &thingies[i + nplayers * npthingies];
+	if (k[0].t_shape == SHP_WARP_BEACON &&
+	    k[1].t_shape == SHP_WARP_BEACON) {
+	    W_MakeLine(mapw, (k[0].t_x - offsetx) * WINSIDE / gwidth,
+		       (k[0].t_y - offsety) * WINSIDE / gwidth,
+		       (k[1].t_x - offsetx) * WINSIDE / gwidth,
+		       (k[1].t_y - offsety) * WINSIDE / gwidth,
+		       W_Grey);
+	}
+    }
+  }
+  redrawall = 0;
+}
+
+#define TWODIGIT_L(p, val) \
+{ \
+    if ((val)<10) { \
+		      (p)[0] = (val)+'0'; \
+		      (p)[1] = ' '; \
+    } else { \
+	       (p)[0] = (val)/10 + '0'; \
+	       (p)[1] = (val)%10 + '0'; \
+	   } \
+}
+
+#define TWODIGIT_R(p, val) \
+{ \
+    if ((val)<10) { \
+		      (p)[0] = ' '; \
+		      (p)[1] = (val)+'0'; \
+    } else { \
+	       (p)[0] = (val)/10 + '0'; \
+	       (p)[1] = (val)%10 + '0'; \
+	   } \
+}
+
+#define THREEDIGIT_C(p, val) \
+{ \
+    if ((val)<10) { \
+		    (p)[0] = ' '; (p)[1] = (val)+'0'; (p)[2] = ' '; \
+    } else if ((val)<100) { \
+			    (p)[0] = (val)/10 + '0'; \
+			    (p)[1] = (val)%10 + '0'; \
+			    (p)[2] = ' ';  \
+    } else { \
+	       (p)[0] = (val)/100 + '0'; \
+	       (p)[1] = ((val)/10 %10) + '0'; \
+	       (p)[2] = (val)%10 + '0'; \
+	   } \
+}
+
+#define THREEDIGIT_R(p, val) \
+{ \
+    if ((val)<10) { \
+		    (p)[0] = ' '; (p)[1] = ' '; (p)[2] = (val)+'0'; \
+    } else if ((val)<100) { \
+			    (p)[0] = ' ';  \
+			    (p)[1] = (val)/10 + '0'; \
+			    (p)[2] = (val)%10 + '0'; \
+    } else { \
+	       (p)[0] = (val)/100 + '0'; \
+	       (p)[1] = ((val)/10 %10) + '0'; \
+	       (p)[2] = (val)%10 + '0'; \
+	   } \
+}
+
+#define FOURDIGIT_R(p, val) \
+{ \
+    if ((val)<10) { \
+		      (p)[0] = ' '; \
+		      (p)[1] = ' '; \
+		      (p)[2] = ' '; \
+		      (p)[3] = (val)+'0'; \
+    } else if ((val)<100) { \
+			      (p)[0] = ' ';  \
+			      (p)[1] = ' ';  \
+			      (p)[2] = (val)/10 + '0'; \
+			      (p)[3] = (val)%10 + '0'; \
+    } else if ((val)<1000) { \
+			       (p)[0] = ' ';  \
+			       (p)[1] = (val)/100 + '0'; \
+			       (p)[2] = ((val)/10 %10) + '0'; \
+			       (p)[3] = (val)%10 + '0'; \
+    } else { \
+	       (p)[0] = (val)/1000 + '0'; \
+	       (p)[1] = ((val)/100 %10) + '0'; \
+	       (p)[2] = ((val)/10 %10) + '0'; \
+	       (p)[3] = (val)%10 + '0'; \
+	   } \
+}
+
+#define SIXDIGIT_R(p, val) \
+{ \
+    if ((val)<10) { \
+		      (p)[0] = ' '; \
+		      (p)[1] = ' '; \
+		      (p)[2] = ' '; \
+		      (p)[3] = ' '; \
+		      (p)[4] = ' '; \
+		      (p)[5] = (val)+'0'; \
+    } else if ((val)<100) { \
+			      (p)[0] = ' ';  \
+			      (p)[1] = ' ';  \
+			      (p)[2] = ' ';  \
+			      (p)[3] = ' ';  \
+			      (p)[4] = (val)/10 + '0'; \
+			      (p)[5] = (val)%10 + '0'; \
+    } else if ((val)<1000) { \
+			       (p)[0] = ' ';  \
+			       (p)[1] = ' ';  \
+			       (p)[2] = ' ';  \
+			       (p)[3] = (val)/100 + '0'; \
+			       (p)[4] = ((val)/10 %10) + '0'; \
+			       (p)[5] = (val)%10 + '0'; \
+    } else if ((val)<10000) { \
+				(p)[0] = ' ';  \
+				(p)[1] = ' ';  \
+				(p)[2] = ((val)/1000 %10) + '0';  \
+				(p)[3] = ((val)/100 %10) + '0'; \
+				(p)[4] = ((val)/10 %10) + '0'; \
+				(p)[5] = (val)%10 + '0'; \
+    } else if ((val)<100000) { \
+				 (p)[0] = ' ';  \
+				 (p)[1] = ((val)/10000 %10) + '0';  \
+				 (p)[2] = ((val)/1000 %10) + '0';  \
+				 (p)[3] = ((val)/100 %10) + '0'; \
+				 (p)[4] = ((val)/10 %10) + '0'; \
+				 (p)[5] = (val)%10 + '0'; \
+    } else { \
+	       (p)[0] = (val)/100000 + '0';  \
+	       (p)[1] = ((val)/10000 %10) + '0';  \
+	       (p)[2] = ((val)/1000 %10) + '0'; \
+	       (p)[3] = ((val)/100 %10) + '0'; \
+	       (p)[4] = ((val)/10 %10) + '0'; \
+	       (p)[5] = (val)%10 + '0'; \
+	   } \
+}
+
+#define SIXnTWOf_R(p, val) \
+{ \
+    (p)[3] = '.'; \
+    (p)[4] = ((int) (10*(val))) %10 + '0'; \
+    (p)[5] = ((int) (100*(val))) %10 + '0'; \
+    if ((val)<10) { \
+		      (p)[0] = ' '; \
+		      (p)[1] = ' '; \
+		      (p)[2] = ((int)(val))+'0'; \
+    } else if ((val)<100) { \
+			      (p)[0] = ' ';  \
+			      (p)[1] = ((int)(val))/10 + '0'; \
+			      (p)[2] = ((int)(val))%10 + '0'; \
+    } else { \
+	       (p)[0] = ((int)(val))/100 + '0'; \
+	       (p)[1] = (((int)(val))/10 %10) + '0'; \
+	       (p)[2] = ((int)(val))%10 + '0'; \
+	   } \
+}
+
+#if 0
+
+static void
+stline(flag)
+    int     flag;
+{
+    static char buf1[80];
+    static char buf2[80];
+    static char whichbuf = 0;
+    static int lastnewDashboard;
+    register char *buf, *oldbuf;
+    register char *s;
+    register int i, j;
+    int     k;
+/* if you don't do something like this, then switching in the options menu
+   is 'entertaining'  */
+    if (newDashboard != lastnewDashboard) {
+	lastnewDashboard = newDashboard;
+	redrawTstats();
+	return;
+    }
+/* use the new dashboard if we can */
+
+
+
+
+
+
+    if (newDashboard) {
+	db_redraw(flag);
+	return;
+    }
+    /* Instead of one sprintf, we do all this by hand for optimization */
+
+    if (flag)
+	whichbuf = 0;		/* We must completely refresh */
+
+    if (whichbuf != 2) {
+	buf = buf1;
+	oldbuf = buf2;
+    } else {
+	buf = buf2;
+	oldbuf = buf1;
+    }
+    buf[0] = (me->p_flags & PFSHIELD ? 'S' : ' ');
+    if (me->p_flags & PFGREEN)
+	buf[1] = 'G';
+    else if (me->p_flags & PFYELLOW)
+	buf[1] = 'Y';
+    else if (me->p_flags & PFRED)
+	buf[1] = 'R';
+    buf[2] = (me->p_flags & (PFPLLOCK | PFPLOCK) ? 'L' : ' ');
+    buf[3] = (me->p_flags & PFREPAIR ? 'R' : ' ');
+    buf[4] = (me->p_flags & PFBOMB ? 'B' : ' ');
+    buf[5] = (me->p_flags & PFORBIT ? 'O' : ' ');
+    buf[6] = (me->p_flags & PFDOCKOK ? 'D' : ' ');
+/*      buf[6] = (me->p_flags & PFDOCK ? 'D' : ' ');*/
+    buf[7] = (me->p_flags & PFCLOAK ? 'C' : ' ');
+    buf[8] = (me->p_flags & PFWEP ? 'W' : ' ');
+    buf[9] = (me->p_flags & PFENG ? 'E' : ' ');
+    if (me->p_flags & PFPRESS)
+	buf[10] = 'P';
+    else if (me->p_flags & PFTRACT)
+	buf[10] = 'T';
+    else
+	buf[10] = ' ';
+    if (me->p_flags & PFBEAMUP)
+	buf[11] = 'u';
+    else if (me->p_flags & PFBEAMDOWN)
+	buf[11] = 'd';
+    else
+	buf[11] = ' ';
+    if (!paradise)
+	buf[12] = (status->tourn) ? 't' : ' ';
+    else
+	buf[12] = (status2->tourn) ? 't' : ' ';
+
+    buf[13] = ' ';
+
+#if 1
+/* w/i indicator is a kludge - it just guesses based on the speed of
+   the ship */
+    sprintf(buf + 14, "%2d%c   %3d %3d  %1d  %6.2f %3d %6d  %4d %4d  ",
+	me->p_speed, (me->p_speed > me->p_ship->s_maxspeed + 2) ? 'w' : 'i',
+	    me->p_damage, me->p_shield, me->p_ntorp, me->p_kills,
+	    me->p_armies, me->p_fuel, me->p_wtemp, me->p_etemp);
+#else
+#if 0
+    TWODIGIT_L(&buf[14], me->p_speed);
+    buf[16] = 'i';
+    buf[17] = ' ';
+    buf[18] = ' ';
+    buf[19] = ' ';
+    THREEDIGIT_R(&buf[20], me->p_damage);
+    buf[23] = ' ';
+    THREEDIGIT_R(&buf[24], me->p_shield);
+    buf[27] = ' ';
+    TWODIGIT_R(&buf[28], me->p_ntorp);
+    buf[30] = ' ';
+    buf[31] = ' ';
+    SIXnTWOf_R(&buf[32], me->p_kills);
+    buf[38] = ' ';
+    THREEDIGIT_C(&buf[39], me->p_armies);
+    buf[42] = ' ';
+    SIXDIGIT_R(&buf[43], me->p_fuel);
+    buf[49] = ' ';
+    buf[50] = ' ';
+    FOURDIGIT_R(&buf[51], me->p_wtemp / 10);
+    buf[55] = ' ';
+    FOURDIGIT_R(&buf[56], me->p_etemp / 10);
+    buf[60] = ' ';
+    buf[61] = ' ';
+#else
+    buf[14] = '0' + ((me->p_speed % 100) / 10);
+    if (buf[14] == '0')
+	buf[14] = ' ';
+    buf[15] = '0' + (me->p_speed % 10);	/* speed */
+    buf[16] = ' ';
+    buf[17] = ' ';
+    buf[18] = '0' + (me->p_damage / 100);
+    if (buf[18] == '0')
+	buf[18] = ' ';
+    buf[19] = '0' + ((me->p_damage % 100) / 10);
+    if ((buf[19] == '0') && (me->p_damage < 100))
+	buf[19] = ' ';
+    buf[20] = '0' + (me->p_damage % 10);
+    buf[21] = ' ';
+    buf[22] = '0' + (me->p_shield / 100);
+    if (buf[22] == '0')
+	buf[22] = ' ';
+    buf[23] = '0' + ((me->p_shield % 100) / 10);
+    if ((buf[23] == '0') && (me->p_shield < 100))
+	buf[23] = ' ';
+    buf[24] = '0' + (me->p_shield % 10);
+    buf[25] = ' ';
+    buf[26] = ' ';
+    buf[27] = '0' + ((me->p_ntorp % 100) / 10);
+    if (buf[27] == '0')
+	buf[27] = ' ';
+    buf[28] = '0' + (me->p_ntorp % 10);
+    buf[29] = ' ';
+    buf[30] = ' ';
+    buf[31] = ' ';
+    buf[32] = ' ';
+    buf[33] = '0' + ((int) (me->p_kills / 10));
+    if (buf[33] == '0')
+	buf[33] = ' ';
+    buf[34] = '0' + (((int) me->p_kills) % 10);
+    buf[35] = '.';
+    buf[36] = '0' + (((int) (me->p_kills * 10)) % 10);
+    buf[37] = '0' + (((int) (me->p_kills * 100)) % 10);
+    buf[38] = ' ';
+    buf[39] = ' ';
+    buf[40] = ' ';
+    buf[41] = '0' + ((me->p_armies % 100) / 10);
+    if (buf[41] == '0')
+	buf[41] = ' ';
+    buf[42] = '0' + (me->p_armies % 10);
+    buf[43] = ' ';
+    buf[44] = ' ';
+    buf[45] = ' ';
+
+    buf[46] = '0' + (me->p_fuel / 100000);
+    if (buf[46] == '0')
+	buf[46] = ' ';
+    buf[47] = '0' + ((me->p_fuel % 100000) / 10000);
+    if ((buf[47] == '0') && (me->p_fuel < 100000))
+	buf[47] = ' ';
+    buf[48] = '0' + ((me->p_fuel % 10000) / 1000);
+    if ((buf[48] == '0') && (me->p_fuel < 10000))
+	buf[48] = ' ';
+    buf[49] = '0' + ((me->p_fuel % 1000) / 100);
+    if ((buf[49] == '0') && (me->p_fuel < 1000))
+	buf[49] = ' ';
+    buf[50] = '0' + ((me->p_fuel % 100) / 10);
+    if ((buf[50] == '0') && (me->p_fuel < 100))
+	buf[50] = ' ';
+    buf[51] = '0' + (me->p_fuel % 10);
+    buf[52] = ' ';
+    buf[53] = ' ';
+    buf[54] = ' ';
+
+    buf[55] = '0' + ((me->p_wtemp / 10) / 100);
+    if (buf[55] == '0')
+	buf[55] = ' ';
+    buf[56] = '0' + (((me->p_wtemp / 10) % 100) / 10);
+    if ((buf[56] == '0') && (me->p_wtemp < 1000))
+	buf[56] = ' ';
+    buf[57] = '0' + ((me->p_wtemp / 10) % 10);
+
+    buf[58] = ' ';
+    buf[59] = ' ';
+    buf[60] = ' ';
+    buf[61] = '0' + ((me->p_etemp / 10) / 1000);
+    if (buf[61] == '0')
+	buf[61] = ' ';
+    buf[62] = '0' + (((me->p_etemp / 10) % 1000) / 100);
+    if (buf[62] == '0' && me->p_etemp < 1000)
+	buf[62] = ' ';
+    buf[63] = '0' + (((me->p_etemp / 10) % 100) / 10);
+    if ((buf[63] == '0') && (me->p_etemp < 1000))
+	buf[63] = ' ';
+    buf[64] = '0' + ((me->p_etemp / 10) % 10);
+    buf[65] = ' ';
+#endif
+#endif
+
+    if (whichbuf == 0) {
+	/* Draw status line */
+	W_WriteText(tstatw, TSTATW_BASEX, 16, textColor, buf, 66, W_RegularFont);
+	whichbuf = 1;
+    } else {			/* Hacks to make it print only what is
+				   necessary */
+	whichbuf = 3 - whichbuf;
+	j = -1;
+	for (i = 0; i < 66; i++) {
+	    if (*(buf++) != *(oldbuf++)) {
+		/* Different string */
+		if (j == -1) {
+		    k = i;
+		    s = buf - 1;
+		}
+		j = 0;
+	    } else {
+		/* Same string */
+		if (j == -1)
+		    continue;
+		j++;
+		if (j == 20) {	/* Random number */
+		    W_WriteText(tstatw, TSTATW_BASEX + W_Textwidth * k, 16, textColor,
+				s, i - k - 19, W_RegularFont);
+		    j = -1;
+		}
+	    }
+	}
+	if (j != -1) {
+	    W_WriteText(tstatw, TSTATW_BASEX + W_Textwidth * k, 16, textColor, s, i - k - j,
+			W_RegularFont);
+	}
+    }
+}
+
+void
+redrawTstats()
+{
+    char    buf[100];
+    W_ClearWindow(tstatw);
+    /* use new dashboard if possible */
+    if (newDashboard) {
+	db_redraw(1);
+	return;
+    }
+    stline(1);			/* This is for refresh.  We redraw player
+				   stats too */
+    strcpy(buf, "Flags        Speed  Dam Shd Trp  Kills Ams   Fuel  Wtmp Etmp  Special"	/* "Flags        Warp
+											   Dam Shd Torps  Kills
+											   Armies   Fuel  Wtemp
+	       Etemp" */ );
+    W_WriteText(tstatw, TSTATW_BASEX, 5, textColor, buf, strlen(buf), W_RegularFont);
+    sprintf(buf,
+	    "Maximum:      %2d    %3d %3d  8         %3d %6d  %4d %4d ",
+	    me->p_ship->s_maxspeed, me->p_ship->s_maxdamage,
+	    me->p_ship->s_maxshield, me->p_ship->s_maxarmies,
+	    me->p_ship->s_maxfuel, me->p_ship->s_maxwpntemp / 10,
+	    me->p_ship->s_maxegntemp / 10);
+    W_WriteText(tstatw, TSTATW_BASEX, 27, textColor, buf, strlen(buf), W_RegularFont);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/reserved.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,44 @@
+/* $Id: reserved.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/* reserved.c
+
+ * Kevin P. Smith   7/3/89
+ */
+#include "copyright2.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include "defs.h"
+#include "packets.h"
+
+void
+makeReservedPacket(packet)
+    struct reserved_spacket *packet;
+{
+    int     i;
+
+    for (i = 0; i < 16; i++) {
+	packet->data[i] = random() % 256;
+    } packet->type = SP_RESERVED;
+}
+
+void
+encryptReservedPacket(spacket, cpacket, server, pno)
+    struct reserved_spacket *spacket;
+    struct reserved_cpacket *cpacket;
+    char   *server;
+    int     pno;
+{
+
+    memcpy(cpacket->data, spacket->data, 16);
+    memcpy(cpacket->resp, spacket->data, 16);
+    cpacket->type = CP_RESERVED;
+
+    /*
+       Encryption algorithm goes here. Take the 16 bytes in cpacket->data,
+       and create cpacket->resp, which you require the client to also do.  If
+       he fails, he gets kicked out.
+    */
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rotate.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,130 @@
+/* $Id: rotate.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/*
+ * rotate.c
+ *
+ */
+#include "copyright2.h"
+
+#include <stdio.h>
+#include <sys/types.h>
+#ifndef AMIGA			/* not that this file needs any network
+				   stuff... -JR */
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#endif
+#include <math.h>
+#include <errno.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+
+#ifdef ROTATERACE
+
+void
+rotate_dir(d, r)
+    unsigned char *d;
+    int     r;
+{
+    (*d) += r;
+}
+
+/* general rotation */
+
+void
+rotate_coord(x, y, d, cx, cy)
+    int    *x, *y;		/* values used and returned */
+    int     d;			/* degree (pi == 128) */
+    int     cx, cy;		/* around center point */
+{
+    register
+    int     ox, oy;
+
+    ox = *x;
+    oy = *y;
+
+    switch (d) {
+
+    case 0:
+	return;
+
+    case 64:
+    case -192:
+	*x = cy - oy + cx;
+	*y = ox - cx + cy;
+	break;
+
+    case 128:
+    case -128:
+	*x = cx - ox + cx;
+	*y = cy - oy + cy;
+	break;
+
+    case 192:
+    case -64:
+	*x = oy - cy + cx;
+	*y = cx - ox + cy;
+	break;
+
+    default:{
+	    /* do it the hard way */
+	    /*
+	       there is another way to do this, by using the cos(d) and
+	       sin(d) and the stock rotation matrix from linear algebra.
+	    */
+	    double  dir;
+	    double  r, dx, dy;
+	    double  rd = (double) d * 3.1415927 / 128.;
+
+	    if (*x != cx || *y != cy) {
+		dx = (double) (*x - cx);
+		dy = (double) (cy - *y);
+		dir = atan2(dx, dy) - 3.1415927 / 2.;
+		r = hypot(dx, dy);
+		dir += rd;
+		*x = (int) (r * cos(dir) + cx);
+		*y = (int) (r * sin(dir) + cy);
+	    }
+	}
+    }
+}
+
+void
+rotate_gcenter(x, y)
+    int    *x, *y;		/* values used and returned */
+{
+    rotate_coord(x, y, rotate_deg, blk_gwidth / 2, blk_gwidth / 2);
+}
+
+#endif
+
+void rotate_all()
+{
+    register i;
+    register struct planet *l;
+    register struct player *j;
+
+    int     nplan = (paradise) ? nplanets : 40;
+    int     old_rotate_deg = rotate_deg;
+
+    redrawall = 1;
+    reinitPlanets = 1;
+
+    rotate_deg = -old_rotate_deg + rotate * 64;
+
+    for (i = 0, l = planets; i < nplan; i++, l++) {
+	rotate_gcenter(&l->pl_x, &l->pl_y);
+    }
+
+    for (i=0, j = players; i < nplayers; i++, j++) {
+	rotate_gcenter(&j->p_x, &j->p_y);
+	rotate_dir(&j->p_dir, rotate_deg);
+    }
+
+    rotate_deg = rotate * 64;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sample.xtrekrc	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,681 @@
+# Sample .xtrekrc
+#
+# Specify this file with:
+#   netrek -r defaults
+#
+# If you do not specify a file, then .paradiserc from your home directory
+#   is used.  If .paradiserc does not exist then .xtrekrc is used.
+#
+# Documentation for all options is available at
+# http://www.pnetrek.org/
+#
+# You can have defaults from other files included using '#include <file>'.
+# This lets you put all your public settings into one file, .xtrekrc for
+# example and all your private stuff into another file. You can use ~ in
+# the file name to signify your $HOME directory. In your private
+# file you can have passwords in the form of 'password: passwd' for a
+# general password, or 'password.player: passwd' for passwd's associated
+# with your player name, or 'password.server: passwd' for server specific
+# passwords.
+
+name: 			guest
+
+# changes to the basic colors:
+#color.white:   	white
+#color.black:  		black
+#color.red:		paleVioletRed1
+#color.green: 		green
+#color.yellow: 		yellow
+#color.cyan:            cyan
+#color.cyan:		dodgerblue
+color.cyan:		DeepSkyBlue
+#color.light grey:   	light grey
+
+#miscellaneous toggles
+# 0=none, 1=time of day, 2=time on server, 3=time in ship, 4=user set time
+timerType:		3
+#shipBitmapPath:         /home/smpatel/netrek/bitmaps/
+#soundPath:              /home/smpatel/netrek/sounds
+#soundDev:               /dev/dsp
+# put enemy on left with sorted playerlist
+robsort:		on
+# show dead players in playerlist
+showDead:		on
+# sort outfitting ('--') players to bottom
+sortOutfitting:		on
+# show pre-login players
+showPreLogins:		on
+# replace 0.00 with "     " when acceptable (paradise servers)
+hideNoKills:		on
+warpStreaks:		on
+# use rainbow dashboard in paradise
+# 0=old dashboard, 1=new dashboard, 2=color dashboard, 3=rainbow dashboard
+Dashboard:		3
+# clear my keymap each time, ie ignore the server's copy 
+clearMap:		on
+# use hull warning dots
+warnHull:		on
+# replace ?? cloaker symbol with ><
+cloakChars:		><
+showShields:		on
+#showStats:		on
+reportKills:		on
+showMySpeed:		on
+# vary color of shields with damage
+varyShields:		on
+keepPeace:		on
+galacticFrequent:       on
+showTractor:		on
+showTractorPressor:     on
+showPlanetNames:	on
+showPlanetOwner:	off
+sortPlayers:	   	on
+warp:			on
+defaultShip: 		CA
+logging: 		on
+logMessage:		on
+logfile:                /home/smpatel/paradise.log
+# galactic map stuff: 0=ownership  1=resources  2=nothing
+showGalactic:    	1
+showLocal:		1
+# lock :  0=don't show 1=galactic only  2=tactical only  3=both
+showLock:		3
+netStats:  		off
+tryUDP:			on
+# udpClientSend: 0=TCP only 1=simple UDP  2=enforced UDP (state only)  
+# 3=enforced UDP (state & weap)
+udpClientSend:          3
+# udpClientReceive:  0=TCP only  1=simple UDP 2=fat UDP 3=double UDP
+udpClientReceive:       2
+udpSequenceCheck:       on
+# udpDebug: 0 = OFF   1 = ON (conect msgs only)  2 = ON (verbose output)
+udpDebug:               0
+udpUpdates:		5
+# I'd turn this on, but there's no 'fat S_P' - I can manually enable if lag
+# is bad
+tryShort:		off
+WaitMotd.mapped: 	on
+# show tractor/pressor of everyone in tactical
+showAllTractorPressor:  on
+# show # per team and messages
+infoIcon:               on
+updateSpeed:            0
+# set time for autoquit
+autoQuit:               199
+# show blinking lights on console for packets
+packetLights:           on
+# show box on galactic map representing tactical window
+viewBox:                on
+# number sectors in galactic map
+sectorNums:             on
+# display a line from you to target of lock
+lockLine:               on
+# use new sorting for planet list
+mapSort:		on
+# automaticly set war dec's according the scheme:
+# 1) set war with nonzero player teams, peace w/ 0 player teams
+# 2) set war with largest enemy team,  peace w/ everyone else
+autoSetWar:           1
+# extra info on resources of local planets; add the values of what you want
+# displayed: 1 = army count; 2 = repair; 4 = fuel; 8 = agri; 16 = shipyard
+# paradise option only
+tacPlanetInfo:                9
+# cycle phaser hits through all colors
+jubileePhasers:		on
+# send request for full update ('=') each time you enter
+askforupdate: 		on
+# allow a lower case t to send messages to team
+lowercaset:		on
+#use the flight recorder?
+#recordGame: on
+#recordFile: /tmp/netrek.record
+#set maximum record file size in bytes:
+maxRecord: 1000000
+# Playback (also, -F <filename> from command line)
+#playback: on
+#playFile: /tmp/netrek.record
+#A minimum of x/10's of a second between redraws:
+redrawDelay: 0
+#Draw an X over independant planets: (good for b&w)
+showIND: off
+#some very silly stuff to draw ship status on local window.
+# Either needs work, or needs to be tossed ;)
+#(part of an effort to get rid of the dashboard on my small display)
+#stats that can be shown:
+#'D'amage, 'S'hields, 'F'uel, 'A'rmies, s'P'eed, 'W'temp, 'E'temp
+#a lower case letter reverses the line for that stat.
+statString: dASF
+localShipStats: on
+localStatsX: 25
+localStatsY: 450
+statHeight:  80
+#only with short packets: remove "GOD->ALL" from the front of kill msgs.
+godToAllOnKills: off
+#don't beep when you try to scroll too far:
+scrollBeep: off
+# Also in scrolling windows: ^p scrolls one line back, ^n one line forward,
+# left button one page pack, right button page forward, middle button to end,
+# ^e clears the window(but not the scrollback)
+  
+#----[ fonts
+#italicfont:	6x10i
+#font:          -*-clean-medium-r-normal--10-100-75-75-c-60-*
+#boldfont:      -*-clean-bold-r-normal--10-100-75-75-c-60-*
+#italicfont:     -*-clean-italic-r-normal--10-100-75-75-c-60-*
+#italicfont:     -schumacher-clean-bold-r-normal--10-100-75-75-c-60-iso8859-1
+# italic=normal
+italicfont:     -*-clean-medium-r-normal--10-100-75-75-c-60-*
+#bigfont:       -*-fixed-medium-r-normal--24-*-100-100-c-120-*-*
+
+# Here I start messing around with window placement.
+# For *all* of the windows listed, you can specify if you want them mapped,
+#   their geometry, and their parent.
+# When specifying geometry for text (and scrolling) windows, specify
+#   in terms of characters wide and high.  Specify size of a menu only
+#   at your own risk (there is no real benefit to doing this).
+
+netrek.geometry:        1000x800+0+1	# The main window
+netrek_icon.geometry:   +1031+0      	# The icon
+#stats.geometry:		+512+576
+#player.geometry:        82x24+0+576	# The player list
+player.geometry:        82x24+0+550	# The player list
+player.mapped:          on
+player.parent:		netrek
+#review.geometry:        82x24+512+576	# Main message window 
+review.geometry:        82x24+500+548	# Main message window 
+review.mapped:		on
+review.parent:		netrek
+
+#
+# This is my keymap help file followed by keymap:
+# comments to Bill.Dyess@eng.auburn.edu (Thought)
+#
+# Key        Default Function                       New Function           Key
+#------------------------------------------------------------------------------
+#| a | ?                               | afterburners (`)                 | a |
+#| b | bomb planet                     |                                  | b |
+#| c | cloaking                        |                                  | c |
+#| d | detonate other torpedoes        | detonate own torps (D)           | d |
+#| e | docking permission toggle       | max warp (%)                     | e |
+#| f | launch plasma torpedoes         |                                  | f |
+#| g | -                               | fire phasers (p)                 | g |
+#| h | help window toggle              | whatever 'a' was (a)             | h |
+#| i | info on player / planet         |                                  | i |
+#| j | -                               | war window toggle (w)            | j |
+#| k | set course                      |                                  | k |
+#| l | lock onto player / planet       |                                  | l |
+#| n | -                               | change ship types (r)            | n |
+#| o | orbit (dock at starbase)        |                                  | o |
+#| p | fire phaser                     |                                  | p |
+#| q | quick quit                      | warp 3 (3)                       | q |
+#| r | change ship type                | pressor beam on (^)              | r |
+#| s | shields toggle                  |                                  | s |
+#| t | launch torpedoes                | tractor beam off (_)             | t |
+#| u | shields toggle                  |                                  | u |
+#| v | -                               | info on player / planet (i)      | v |
+#| w | war window toggle               | warp 5 (5)                       | w |
+#| x | beam down armies                | Macro mode (X)                   | x |
+#| y | pressor beam toggle             | tractor/pressor off ($)          | y |
+#| z | beam up armies                  | Coup/Change weapons (C)          | z |
+#| ' | start message to team           |                                  | ' |
+#| A | -                               | army call (F)                    | A |
+#| B | show galactic info (two levels) |                                  | B |
+#| C | coup a planet / change weapons  | show local info (two levels) (V) | C |
+#| D | detonate my torpedoes           | ludicrous speed (-)              | D |
+#| E | emergency distress call         |                                  | E |
+#| F | army call                       | lock onto player / planet (l)    | F |
+#| G | -                               | lock onto planet (;)             | G |
+#| I | extended info on player         |                                  | I |
+#| L | list players                    |                                  | L |
+#| O | options window                  |                                  | O |
+#| M | map updates toggle              |                                  | M |
+#| N | name mode toggle                |                                  | N |
+#| P | list planets                    |                                  | P |
+#| Q | self destruct                   | quick quit (q)                   | Q |
+#| R | repair mode                     |                                  | R |
+#| S | toggle status graph             |                                  | S |
+#| T | toggle tractor beam             | transwarp (*)                    | T |
+#| U | list ranks                      |                                  | U |
+#| V | show local info (two levels)    | extended info on player (I)      | V |
+#| W | -                               | toggle war window                | W |
+#| X | macro mode                      | beam down armies (x)             | X |
+#| Z | -                               | beam up armies (z)               | Z |
+#| ? | message window toggle           | help window toggle (h)           | ? |
+#| _ | turn on tractor beam            |                                  | _ |
+#| ^ | turn on pressor beam            |                                  | ^ |
+#| $ | turn off tractor/pressor        |                                  | $ |
+#| ; | lock onto planet                |                                  | ; |
+#| * | bring in practice robot         |                                  | * |
+#| [ | shield down                     |                                  | [ |
+#| ] | shield up                       |                                  | ] |
+#| * | practice robot / transwarp      | torps (t)                        | * |
+#| & | re-read .xtrekrc                |                                  | & |
+#| ` | afterburners                    | warp 0 (0)                       | ` |
+#|0-9| warp 0-9                        |                                  |0-9|
+#| ) | warp 10                         |                                  | ) |
+#| ! | warp 11                         |                                  | ! |
+#| @ | warp 12                         |                                  | @ |
+#| % | max warp                        |                                  | % |
+#| # | half warp                       |                                  | # |
+#|Spc| clear all windows               | det other torpedoes (d)          |Spc|
+#| / | -                               | docking permission toggle (e)    | / |
+#| - | ludicrous speed                 |                                  | - |
+#------------------------------------------------------------------------------
+#buttonmap uses the remapped keys (annoying)
+#buttonmap: 	1*2p3k4*5p6k7*8p9ka*bpck
+#
+#This is the default keymap
+#keymap: aabbccddeeffhhiikklloopprrssttuuwwxxyyzz  BBCCDDEEIILLOOMMNNPPRRSSTTUUVV??[[]]**00112233445566778899((!!@@%%##
+#
+keymap:  a`bbccdDe%ffgphaiijjkkllmmnrooppq3sst_uuviw5xXy$zC dAFBBCVD-EEFlG;HHIIJJKKLLMMNNOOPPQqRRSST*UUVIWwXxYYZz?h[[]]*t`01133/er^
+#        ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
+#ckeymap: ^q^1^w^2^e^3^r^4^xX
+#        ^   ^   ^   ^   ^ 
+#keymap:  a`dDe%ffgphajwnrq3rytTviw5xXylzCAFCVD-FlGeT*QQVIWwXxZz?h d/e`01133*t
+# 
+#Messages : put cursor in lower thin window, type: 0-9a-j for player, t 
+#for team, A for all, F/R/K/O for races.  Hit Esc to cancel a message.  
+#
+#New keymap graphically:
+#
+#   (q)         (w)         (e)        (r)       (t)       (y)
+#  warp3       warp5       maxwarp    pressor   tractor   lockon
+#
+#    (a)         (s)         (d)        (f)       (g)       (h)
+#   aftrbrnrs   shields     detmyown   phaser    plasma    whatever-a
+#
+#     (z)         (x)         (c)        (v)       (b)       (n)
+#   weapchange   macromode   cloak      viewinfo  bomb      newship
+#
+#Shifted:
+#
+#   (Q)         (W)         (E)        (R)       (T)
+#   quit       warwindow   emermesg   repair    transwarp
+#
+#    (A)         (S)         (D)        (F)       (G)
+#   army call   status      ludicrous  lockon    dockingtoggle
+#
+#     (Z)         (X)         (C)        (V)       (B)
+#    beamup      beamdown    localinfo2 xtrainfo  galacinfo 
+#
+###############################################################################
+# this sets the default server and port (and verification scheme)
+server:			fod.pnetrek.org
+server.arctica:		netrek.cis.ufl.edu
+server.eden:		eelpout.micro.umn.edu
+port.arctica		2592
+useRSA.arctica		on
+
+# phaser window
+# 0 = don't show    1 = show on kill window   2 = show on phaser window
+# 3 = show on total review window only
+showPhaser:   		2
+review_phaser.mapped:   on
+review_phaser.parent:   netrek
+review_phaser.geometry: 81x3+501+500
+#review_phaser.geometry: 81x4+501+543 # pre-newdash
+
+###############################################################################
+# from: jjudy@argon.berkeley.edu (Jack W. Judy)
+# Heh! This makes it almost impossible to screw-up and *accidently* choose
+# the *wrong* team!  Got this idea from an old post.
+fed.parent:		local			#fed - Fed selection window
+fed.geometry:		100x100+0+400
+rom.parent:		local			#rom - Romulan selection window
+rom.geometry:		100x100+0+0
+kli.parent:		local			#kli - Klingon selection window
+kli.geometry:		100x100+400+0
+ori.parent:		local			#ori - Orion selection window
+ori.geometry:		100x100+400+400
+quit.parent:		local			#quit
+quit.geometry:		100x100+200+0
+
+###############################################################################
+#      Macro stuff
+###############################################################################
+#Standard:
+#
+#%a      armies carried by sender
+#%d      sender damage percentage
+#%s      sender shield percentage
+#%f      sender fuel percentage
+#%w      sender wtemp percentage
+#%e      sender etemp percentage
+#%t      team id character of target planet
+#%T      team id character of sender team
+#%c      sender id character
+#%n      armies on target planet
+#%E      1 if etemped, 0 if not
+#%W      1 if wtemped, 0 if not
+#%S      sender two character ship type
+#%p      id character of target player
+#%g	id char of target friendly player
+#%h	id char of target enemy player
+#%P      id character of player nearest sender
+#%G	id char of friendly player nearest sender
+#%H	id char of enemy player nearest sender
+#%l      three character name of target planet
+#%i	sender full player name (16 character max)
+#%u	full name of target player (16 character max)
+#%z	3 letter team id of target planet
+#%b      sender nearest planet
+#%*	abort macro immediately, sending nothing
+#% 	<space> sends nothing - allows macros to start with spaces
+#%2	1 if on a paradise server, 0 otherwise
+#
+#FULLY CAPITALIZED:
+#%L	three character name of target planet
+#%I	sender full player name (16 character max)
+#%U	full name of target player (16 character max)
+#%Z	3 letter team id of target planet
+#%B      sender nearest planet
+#
+#Ping stats: (may differ slightly from server '!' ping stats)
+#%v    average ping stat round trip time 
+#%V    ping stat round trip standard deviation
+#%y    percent total packet loss as calculated by server formula
+#
+#Miscellanous:
+#%m      the last message you sent
+#%M	the last message you sent in all caps
+#
+#As a further extension to NEWMACRO, a macro may now be sent
+#to any of the following destinations:
+#
+#%i %I %c	send message to self
+#%u %U %p	send message to player nearest mouse
+#%t %z %Z	send message to team of player nearest mouse
+#%g		send message to nearest friendly player to my ship
+#%h		send message to nearest enemy player to my ship
+#
+#Further, tests may be done within the macro system, the syntax
+#for these test is as follows.
+#%?	introduces a test
+#=	equivalence
+#>	greater
+#<	less
+#
+#Expressions are evaluated on a character by character basis until the
+#test is resolved.  The text of the test is then replaced in the macro
+#by 1 or 0.
+#
+#Test are then fed to a syntax I call conditional text.  The best way
+#to demonstrate how this works is example.
+#
+#1%{included if true%!included if false%}
+#
+#This would print:
+#included if true
+#
+#0%{included if true%!included if false%}
+#included if false
+#
+# Paradise orthoganal macros (Robert Forsman)
+#
+#   start with a $
+#
+#   field 1:
+#   (n)earest
+#   (t)arget
+#   (s)elf	(doesn't have fields 2 and 3)
+#   (_) ego	(has no other fields)
+#
+#   field 2:
+#   (a)ny
+#   (t)eammate
+#   (f)riendly
+#   (h)ostile
+#
+#   field 3:
+#   (a)ny
+#   (u)ser
+#   (p)lanet (includes asteroids)
+#   (s)tar
+#   (n)ebula
+#   (b)lack hole
+#   (^) non-planet
+#   (*) any stellar object
+#
+#   field 4: (optional)		NYI
+#   (U)ppercase
+#   (C)apitalize
+#   (L)owercase
+#
+#   field 5:
+#   full (n)ame (Hammor, Thought)
+#   (i)dentifier (e.g. R5, Ka, Can, Sco)
+#   (#) number (0-9a-z for players, %d for planets)
+#   (t)eam name (Romulan)
+#   (s)hort team id (ROM)
+#   (l)etter of team (R)
+#   (a)rmies
+#   (@) sector
+#   (M) 0=not metal planet, 1=metal, 2=repair, 3=shipyard
+#   (A) 0=not arable, 1=arable, 2=agri
+#   (D) 0=not dilithium, 1=dilithium, 2=fuel
+#
+#   Any implementation of the paradise $ codes (subset or superset)
+#   must implement and document the $_ code.      -- Robert Forsman
+#start macros:
+
+mac.a.T:	%?%n<0%{TOUCH %2%{$tasUi->%}%L!%!%2%{$tasLi->%}%l@%n%}
+mac.b.T:        bomb %2%{$tasLi->%}%l%?%n>4%{ @ %n%} %2%{%?$tapD>1%{ FUEL%}%?$tapA=2%{ AGRI%}%?$tapM>1%{ REPAIR%}%?$tapM>2%{ SHIPYARD%}%}
+mac.c:  	Carrying %?%a>0%{%a arm%?%a=1%{y.%!ies.%}%!no armies.%}
+#mac.d.T:        %E%{%!%W%{%!I'm fine.%}%}%E%{ETEMPED!!!  %}%W%{WTEMPED!!!  %}Carrying %?%a>0%{%a armies!%!NO armies.%}
+mac.d.T:	ogg %p
+mac.e.T:  	Need ESCORT to %l%?%a>0%{, carrying %a arm%?%a=1%{y%!ies!%}%}
+mac.f.T:	%2%{$tasi->%}%l @ %n
+mac.g.T: 	going to %l%?%a>0%{, carrying %a arm%?%a=1%{y%!ies!%}%}
+#mac.h.T:        %E%{ETEMPED!!!  %}%W%{WTEMPED!!!  %}Carrying %?%a>0%{%a armies!%!NO armies.%}
+mac.m:		%m
+mac.n:		no
+mac.o:		ok
+# pig call (5 spaces)
+mac.p.A: 	%      
+mac.q.%i:	queue
+mac.r.%H:	resistance is futile
+mac.s.T: 	We need a sc bomber.
+mac.t.T: 	no t-mode :(
+mac.t:		thanks
+#mac.u.%i: 	test u macro to self
+mac.v:		%T%c PING stats: Average: %v ms, Stdv: %V ms, Loss: %y%%
+mac.x.T:	%L!
+mac.y:		yes
+mac.D.T:	%p++ near %l
+#mac.E.T:	Ignore that last distress
+mac.F:		resistance is not futile??
+#mac.G.T:	Ogg %p!
+#mac.G:		Go to %l
+mac.I.%u:	%u: det when you escort!
+mac.K.A:	KissMy%S
+#mac.N.%i:	NEWGALAXY
+mac.O.%u:	(%i) ogging
+#mac.R.A:        I'm a %?%S=SB%{star base!%!twink!%}
+#mac.S.%i:	START
+#mac.T.%i:	%Z
+mac.T.T: 	T-MODE!
+#mac.W.%t:	SHUT UP, TWINKS!!
+#mac.X.T:	EMERGENCY @ %L!!
+
+# hacker note: I have no idea what the stuff in quotes means -RF
+#** Giardia Froth's "Ich mochte einen Diebstahl melden." **
+
+mac.1.A:	$nhuLn, %i taunts your uncle's monkey.
+mac.2.A:	$nhuLn, %i taunts your ecelesiastical roadkill.
+mac.3.A:	$nhuLn, %i taunts your upper left bicuspid.
+mac.4.A:	$nhuLn, %i taunts your favorite obtuse angle.
+
+mac.`.A:	%i wishes that he wasn't a twink like $nhuLn.
+
+
+#whatever
+macro.5.%i: %%v %v, %%V %V, %%y %y
+
+# test macros.
+macro.6.%i: %%a %a, %%d %d, %%s %s, %%f %f, %%w %w, %%e %e
+macro.7.%i: %%E %E, %%W %w, %%i %i, %%o %o, %%T %T, %%c %c, %%S %S
+#target
+macro.8.%i: %%t %t, %%p %p, %%g %g, %%h %h, %%n %n
+macro.9.%i: %%l %l, %%u %u, %%z %z, 
+
+# nearest
+macro.0.%i:  %%P %P, %%G %G, %%H %H, %%b %b
+
+# new distresses
+singleMacro:    EA
+#mac.F.T:        %?%S=SB%{Your starbase (%i) is carrying %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%}%!%T%c@%B: I have %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%} on board, heading for %L%?%n<0%{ (untouched)%!@%n%}%}
+mac.A.T:        %?%S=SB%{Your starbase (%i) is carrying %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%}%!%T%c@%B: I have %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%} on board%}
+#mac.Z.T:        Going for %L NOW!!  DET for me!! (%?%a=0%{NO%!%a%} %?%a=1%{army%!armies%})
+#mac.E.T:        HELP! %T%c@%B: %?%a=0%{NO%!%a%} %?%a=1%{army%!armies%}, %d%% dam, %s%% shlds, %?%S=SB%{%!%?%f<15%{NO%!%f%%%} gas%} %E%{ETMP!!%} %?%S=SB%{%W%{WTMP!!%!%w%% wtmp%}%}
+
+# Multi line macros!  One regular macro for each line of the multi-macro:
+mac.d.A:%  __    _    _ _   _
+mac.d.A:% | _\  /_\  // \\ / \
+mac.d.A:% || \\// \\//___\\\_/
+mac.d.A:% ||_//\\_//\\---// _
+mac.d.A:% |__/  \_/  \\ // {_}
+
+# use the 'M' flag to specify where multi-macros are displayed:
+# (they go to review and review_all by default)
+review_all.allow: AM
+review.allow: ATIM
+
+# Receiver Configurable Distress
+# each one defined with
+#dist.key.name:   <format string>
+#  key is the key you want to use to send that type, format string is how
+# an RCD of that type should appear to YOU.  You cannot affect how an RCD
+# looks to anyone else.  The key works just like a macro key, IE press 'X'
+# first and then the key, unless that key is defined as a singleMacro, in
+# which case you press just that key.
+#
+#  The format string uses the same format as regular macros...except that
+# I haven't yet fixed it to use Paradise extensions.  That means especially
+# that $ escapes do not work, as well as a couple of % escapes which do not
+# exist in COW-lite (where I got the code)
+#
+# The types of RCD for the name field are:
+# taking
+# ogg
+# bomb
+# space_control
+# save_planet
+# base_ogg
+# help1
+# help2
+# escorting
+# ogging
+# bombing
+# controlling
+# asw
+# asbomb
+# doing1
+# doing2
+# free_beer
+# no_gas
+# crippled
+# pickup
+# pop
+# carrying
+# other1
+# other2
+# help
+#
+# defaults are defined for all of them, look at the macro window ('X?')
+# to see them.  Also, the macro window has 2 pages now, click a mouse
+# button to flip between RCD's and regular macros.
+# 
+# The client will send an RCD for E and F by default if on a server that
+# supports it. other types of rcd's have macro keys defined.
+#
+# Note:  If you have a macro and an RCD defined for the same key, the macro
+# ALWAYS over-rides the RCD.  I'm not sure that's the right way to do it,
+# but that's what it says in the docs for RCD, so that's how I programmed it...
+#
+# samples:  (these are some of what I use)
+dist.E.help:            %T%c(%S) %B: HELP! %?%d>90%{HULL GONE! %!%?%d>20%{%d%% dam %}%}%?%s<10%{SHLDS OUT! %!%?%s<80%{%s%% shd %}%}%?%f<10%{NO %!%f%% %}fuel %?%S=SB%{%w%%wtmp%}%E%{ETEMP! %}%W%{WTEMP! %}%?%a>0%{%a %?%a=1%{ogre%!ogres%}%}
+dist.F.carrying:        %T%c(%S) %B: (%?%S=SB%{%w%%wt%} %s%%sh %d%%dm %f%%fu) Carrying %a armies.
+dist.+.pickup:          %i(%T%c): %p++ @ %l
+dist.p.taking:          %T%c(%S) %B: Carrying %a to %l%?%n>-1%{ @ %n%}          
+
+# Beep-lite!
+#
+# Read the normal beep-lite docs.  As an extension, you may specify
+# the color for each lite by placing a letter for the color after a
+# particular lite.  This is being disallowed by most servers, currently
+# it only works on calvin.  The letters allowed are wrygce, case is not
+# important.  (e is for grey, the rest should be obvious) example:
+
+# hilite taker and target in red
+lite.taking: /cr/lr
+
+# To use beep-lite, you must have the next line, or set it from
+# the options menu:
+UseLite: on
+# also, there are several built in lites defined that can be enabled
+# by:
+DefLite: on
+
+
+###############################################################################
+#
+#  This is the list of windows I've been able to find.  Most you will
+#  probably not want to screw around with, but these can be controlled
+#  (at least it appears that way in the code...).
+#
+# I found these by greping for:
+#   checkMapped
+#   W_MakeWindow
+#   W_MakeTextWindow
+#   W_MakeScrollingWindow
+#   W_MakeMenu
+#
+#Window list:
+#
+#planet          - Planet listing (P)
+#rank	         - The rank window (U)
+#help            - Help window (h)
+#macro           - Macro Listing (X-?)
+#MetaServer List - Metaserver stuff (not quite sure how to use it)
+#review		 - The munged list of messages from all sources
+#review_all      - Messages to all
+#review_team     - Messages to your team
+#review_your     - Messages to you
+#review_kill     - Kill messages
+#review_phaser	 - The phaser damage window
+#netstat	 - Network statistics
+#lagMeter	 - The Lag-o-Meter
+#pingStats	 - Ping statistics window
+#player		 - Player list
+#tstat		 - Dashboard
+#UDP		 - UDP controls
+#network	  -
+#local	         - Main fighting window
+#map	         - Galactic map
+#option	         - The options window
+#wait		 -
+#count		 -
+#waitquit	 -
+#waitmotd	 -
+#info		 -
+#netrek		 - The "main" window (parent)
+#netrek_icon	 -
+#warn		 - Warnings ("forgot your toothbrush",et al)
+#message	 - Message sending window
+#FED	         - Team windows on entry
+#ROM	         - Team windows on entry
+#KLI	         - Team windows on entry
+#ORI	         - Team windows on entry
+#quit		 - Quit box on entry
+#stats		 -
+#scanner	 -
+#war		 - War delcarations
+#
+# This gives you:
+#    name.mapped    (on/off for initial mapping)
+#    name.parent    (which window you want this one to be in)
+#    name.geometry  (size and location)
+#
+###############################################################################
+#        THE END
+###############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/senddist.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,174 @@
+/* $Id: senddist.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/*
+ * distress.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <ctype.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "gameconf.h"
+
+
+/* #$!@$#% length of address field of messages */
+#define ADDRLEN 10
+
+
+/* this loads all sorts of useful data into a distress struct.
+ */
+struct distress *
+loaddistress(i, data)
+    enum dist_type i;
+    W_Event *data;
+{
+    struct distress *dist;
+    struct obtype *gettarget(), *gettarget2(), *target;
+
+    dist = (struct distress *) malloc(sizeof(struct distress));
+
+    dist->sender = me->p_no;
+    dist->dam = (100 * me->p_damage) / me->p_ship->s_maxdamage;
+    dist->shld = (100 * me->p_shield) / me->p_ship->s_maxshield;
+    dist->arms = me->p_armies;
+    dist->fuelp = (100 * me->p_fuel) / me->p_ship->s_maxfuel;
+    dist->wtmp = (100 * me->p_wtemp) / me->p_ship->s_maxwpntemp;
+    dist->etmp = (100 * me->p_etemp) / me->p_ship->s_maxegntemp;
+    /* so.. call me paranoid -jmn */
+    dist->sts = (me->p_flags & 0xff) | 0x80;
+    dist->wtmpflag = ((me->p_flags & PFWEP) > 0) ? 1 : 0;
+    dist->etempflag = ((me->p_flags & PFENG) > 0) ? 1 : 0;
+    dist->cloakflag = ((me->p_flags & PFCLOAK) > 0) ? 1 : 0;
+
+    dist->distype = i;
+    if (dist->distype > generic || dist->distype < take)
+	dist->distype = generic;
+
+    target = gettarget(0, me->p_x, me->p_y, TARG_PLANET);
+    dist->close_pl = target->o_num;
+
+    target = gettarget(data->Window, data->x, data->y, TARG_PLANET);
+    dist->tclose_pl = target->o_num;
+
+    target = gettarget(0, me->p_x, me->p_y, TARG_PLAYER | TARG_ENEMY);
+    dist->close_en = target->o_num;
+
+    target = gettarget(data->Window, data->x, data->y, TARG_PLAYER | TARG_ENEMY);
+    dist->tclose_en = target->o_num;
+
+    target = gettarget(0, me->p_x, me->p_y, TARG_PLAYER | TARG_FRIENDLY);
+    dist->close_fr = target->o_num;
+
+    target = gettarget(data->Window, data->x, data->y, TARG_PLAYER | TARG_FRIENDLY);
+    dist->tclose_fr = target->o_num;
+
+    target = gettarget(0, me->p_x, me->p_y, TARG_PLAYER);
+    dist->close_j = target->o_num;
+
+    target = gettarget(data->Window, data->x, data->y, TARG_PLAYER);
+    dist->tclose_j = target->o_num;
+
+    /* lets make sure these aren't something stupid */
+    dist->cclist[0] = 0x80;
+    dist->preappend[0] = '\0';
+    dist->macroflag = 0;
+
+    return (dist);
+}
+
+/* Coordinating function for _SENDING_ a RCD */
+/* Send an rcd signal out to everyone. */
+
+void
+rcd(i, data)
+    enum dist_type i;
+    W_Event *data;
+{
+    char    ebuf[200];
+    struct distress *dist;
+    char    cry[MSG_LEN];
+    char   *info, *getaddr2();
+    int     len;
+    int     recip;
+    int     group;
+
+
+    group = MTEAM;
+    recip = idx_to_mask(me->p_teami);
+
+    dist = loaddistress(i, data);
+
+    if (F_gen_distress) {
+	/* send a generic distress message */
+	Dist2Mesg(dist, ebuf);
+	pmessage(ebuf, recip, group | MDISTR);
+    } else {
+	len = makedistress(dist, cry, distmacro[dist->distype].macro);
+
+	if (len > 0) {
+	    /* klude alert */
+	    info = cry;
+	    if (strncmp(getaddr2(MTEAM, mask_to_idx(recip)), cry, 8) == 0) {
+		/*
+		   this means we should _strip_ the leading bit because it's
+		   redundant
+		*/
+		info = cry + 9;
+	    }
+	}
+	pmessage(info, recip, group);
+    }
+
+    free(dist);
+}
+
+/* the primary subroutine for newmacro, converts the strange and wonderful
+   ** newmacro syntax into an actual message.
+   ** This is about as inefficient as they come, but how often is the player
+   ** going to send a macro??
+   **  6/3/93 - jn
+ */
+int
+pmacro(mnum, who, data)
+    int     mnum;
+    char    who;
+    W_Event *data;
+{
+    char    addr;
+    int     group, len, recip;
+    char    cry[MSG_LEN];
+    char   *pm;
+    struct distress *dist;
+
+
+    if (!F_UseNewMacro)
+	return 0;
+
+    /* get recipient and group */
+    if ((who == 't') || (who == 'T'))
+	addr = teaminfo[me->p_teami].letter;
+    else
+	addr = who;
+
+    group = getgroup(addr, &recip);
+
+    if (!group) {
+	printf("Bad group!\n");
+	return (0);
+    }
+    pm = macrotable[mnum]->string;
+
+    dist = loaddistress(0, data);
+
+    len = makedistress(dist, cry, pm);
+
+    if (len > 0)
+	pmessage(cry, recip, group);
+
+    free(dist);
+    return 1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shipbitmaps.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,863 @@
+/* $Id: shipbitmaps.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/* with this file, now the user can define and develop new ship bitmap
+   sets ('albums') more easily.
+
+     The user need only create a file in the proper directory with the
+proper name with the proper format.  The directory is specified by the
+shipBitmapPath resource in the .xtrekrc.  Its default is
+/usr/games/lib/netrek.  The name of the file is "R%d.C%d" where the
+first integer is the race number and the second is the ship class
+number.
+
+  The format of the file is: 3 4-byte integers in network byte order.
+The first is the number of views in the file (this field is currently
+ignored but should have the value 16).  The second integer is the
+width and the third is the height.  Then follows raw bitmap data.  I
+don't know what the format is, but it's basically a binary version of
+the X bitmap file format.  Translate those hex numbers to raw bytes
+and you have it.  I can tell you that each line is padded to 8 bits.
+
+*/
+
+#include <stdio.h>
+#ifndef AMIGA
+#include <sys/param.h>
+#include <netinet/in.h>
+#endif
+#include <errno.h>
+
+#ifdef m_flags
+ /* appears under HPUX */
+#undef m_flags
+#endif
+
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "gameconf.h"
+
+#ifdef NOSHIPBITMAPS
+#include "bitmaps_CASB.h"
+#else
+#include "bitmaps_NEW.h"
+#ifdef HOCKEY
+#include "puck.h"
+#endif /*HOCKEY*/
+#endif
+
+static int
+get_ship_width(team, shipn)
+    int     team, shipn;
+{
+#ifndef NOSHIPBITMAPS
+    if (shipn == ATT && paradise)
+	return att_width;
+    switch (team) {
+    case 0:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+            return puck_width;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return fed_scout_width;
+	case DESTROYER:
+	    return fed_destroyer_width;
+	case CRUISER:
+	    return fed_cruiser_width;
+	case BATTLESHIP:
+	    return fed_battleship_width;
+	case ASSAULT:
+	    return fed_assault_width;
+	case STARBASE:
+	    return fed_starbase_width;
+	case JUMPSHIP:
+	    return fed_jumpship_width;
+	case FLAGSHIP:
+	    return fed_galaxy_width;
+	case GALAXY:
+	    return fed_galaxy_width;
+	case WARBASE:
+	    return fed_warbase_width;
+	case LIGHTCRUISER:
+	    return fed_lightcruiser_width;
+	case CARRIER:
+	    return fed_carrier_height;
+	case UTILITY:
+	    return fed_utility_width;
+	case PATROL:
+	    return fed_patrol_width;
+	}
+    case 1:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+            return puck_width;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return rom_scout_width;
+	case DESTROYER:
+	    return rom_destroyer_width;
+	case CRUISER:
+	    return rom_cruiser_width;
+	case BATTLESHIP:
+	    return rom_battleship_width;
+	case ASSAULT:
+	    return rom_assault_width;
+	case STARBASE:
+	    return rom_starbase_width;
+	case JUMPSHIP:
+	    return rom_jumpship_width;
+	case FLAGSHIP:
+	    return rom_galaxy_width;
+	case GALAXY:
+	    return rom_galaxy_width;
+	case WARBASE:
+	    return rom_warbase_width;
+	case LIGHTCRUISER:
+	    return rom_lightcruiser_width;
+	case CARRIER:
+	    return rom_carrier_height;
+	case UTILITY:
+	    return rom_utility_width;
+	case PATROL:
+	    return rom_patrol_width;
+	}
+    case 2:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+            return puck_width;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return kli_scout_width;
+	case DESTROYER:
+	    return kli_destroyer_width;
+	case CRUISER:
+	    return kli_cruiser_width;
+	case BATTLESHIP:
+	    return kli_battleship_width;
+	case ASSAULT:
+	    return kli_assault_width;
+	case STARBASE:
+	    return kli_starbase_width;
+	case JUMPSHIP:
+	    return kli_jumpship_width;
+	case FLAGSHIP:
+	    return kli_galaxy_width;
+	case GALAXY:
+	    return kli_galaxy_width;
+	case WARBASE:
+	    return kli_warbase_width;
+	case LIGHTCRUISER:
+	    return kli_lightcruiser_width;
+	case CARRIER:
+	    return kli_carrier_height;
+	case UTILITY:
+	    return kli_utility_width;
+	case PATROL:
+	    return kli_patrol_width;
+	}
+    case 3:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+            return puck_width;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return ori_scout_width;
+	case DESTROYER:
+	    return ori_destroyer_width;
+	case CRUISER:
+	    return ori_cruiser_width;
+	case BATTLESHIP:
+	    return ori_battleship_width;
+	case ASSAULT:
+	    return ori_assault_width;
+	case STARBASE:
+	    return ori_starbase_width;
+	case JUMPSHIP:
+	    return ori_jumpship_width;
+	case FLAGSHIP:
+	    return ori_galaxy_width;
+	case GALAXY:
+	    return ori_galaxy_width;
+	case WARBASE:
+	    return ori_warbase_width;
+	case LIGHTCRUISER:
+	    return ori_lightcruiser_width;
+	case CARRIER:
+	    return ori_carrier_height;
+	case UTILITY:
+	    return ori_utility_width;
+	case PATROL:
+	    return ori_patrol_width;
+	}
+    case -1:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_width;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return ind_scout_width;
+	case DESTROYER:
+	    return ind_destroyer_width;
+	case CRUISER:
+	    return ind_cruiser_width;
+	case BATTLESHIP:
+	    return ind_battleship_width;
+	case ASSAULT:
+	    return ind_assault_width;
+	case STARBASE:
+	    return ind_starbase_width;
+	case JUMPSHIP:
+	    return ind_starbase_width;
+	case FLAGSHIP:
+	    return ind_galaxy_width;
+	case GALAXY:
+	    return ind_galaxy_width;
+	case WARBASE:
+	    return ind_starbase_width;
+	case LIGHTCRUISER:
+	    return ind_lightcruiser_width;
+	case CARRIER:
+	    return ind_carrier_height;
+	case UTILITY:
+	    return ind_utility_width;
+	case PATROL:
+	    return ind_patrol_width;
+	}
+    }
+#endif				/* NOSHIPBITMAPS */
+    return 20;
+}
+
+
+static int
+get_ship_height(team, shipn)
+    int     team, shipn;
+{
+#ifndef NOSHIPBITMAPS
+    if (shipn == ATT && paradise)
+	return att_height;
+    switch (team) {
+    case 0:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_height;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return fed_scout_height;
+	case DESTROYER:
+	    return fed_destroyer_height;
+	case CRUISER:
+	    return fed_cruiser_height;
+	case BATTLESHIP:
+	    return fed_battleship_height;
+	case ASSAULT:
+	    return fed_assault_height;
+	case STARBASE:
+	    return fed_starbase_height;
+	case JUMPSHIP:
+	    return fed_jumpship_height;
+	case FLAGSHIP:
+	    return fed_galaxy_height;
+	case GALAXY:
+	    return fed_galaxy_height;
+	case WARBASE:
+	    return fed_warbase_height;
+	case LIGHTCRUISER:
+	    return fed_lightcruiser_height;
+	case CARRIER:
+	    return fed_carrier_height;
+	case UTILITY:
+	    return fed_utility_height;
+	case PATROL:
+	    return fed_patrol_height;
+	}
+    case 1:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_height;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return rom_scout_height;
+	case DESTROYER:
+	    return rom_destroyer_height;
+	case CRUISER:
+	    return rom_cruiser_height;
+	case BATTLESHIP:
+	    return rom_battleship_height;
+	case ASSAULT:
+	    return rom_assault_height;
+	case STARBASE:
+	    return rom_starbase_height;
+	case JUMPSHIP:
+	    return rom_jumpship_height;
+	case FLAGSHIP:
+	    return rom_galaxy_height;
+	case GALAXY:
+	    return rom_galaxy_height;
+	case WARBASE:
+	    return rom_warbase_height;
+	case LIGHTCRUISER:
+	    return rom_lightcruiser_height;
+	case CARRIER:
+	    return rom_carrier_height;
+	case UTILITY:
+	    return rom_utility_height;
+	case PATROL:
+	    return rom_patrol_height;
+	}
+    case 2:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_height;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return kli_scout_height;
+	case DESTROYER:
+	    return kli_destroyer_height;
+	case CRUISER:
+	    return kli_cruiser_height;
+	case BATTLESHIP:
+	    return kli_battleship_height;
+	case ASSAULT:
+	    return kli_assault_height;
+	case STARBASE:
+	    return kli_starbase_height;
+	case JUMPSHIP:
+	    return kli_jumpship_height;
+	case FLAGSHIP:
+	    return kli_galaxy_height;
+	case GALAXY:
+	    return kli_galaxy_height;
+	case WARBASE:
+	    return kli_warbase_height;
+	case LIGHTCRUISER:
+	    return kli_lightcruiser_height;
+	case CARRIER:
+	    return kli_carrier_height;
+	case UTILITY:
+	    return kli_utility_height;
+	case PATROL:
+	    return kli_patrol_height;
+	}
+    case 3:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_height;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return ori_scout_height;
+	case DESTROYER:
+	    return ori_destroyer_height;
+	case CRUISER:
+	    return ori_cruiser_height;
+	case BATTLESHIP:
+	    return ori_battleship_height;
+	case ASSAULT:
+	    return ori_assault_height;
+	case STARBASE:
+	    return ori_starbase_height;
+	case JUMPSHIP:
+	    return ori_jumpship_height;
+	case FLAGSHIP:
+	    return ori_galaxy_height;
+	case GALAXY:
+	    return ori_galaxy_height;
+	case WARBASE:
+	    return ori_warbase_height;
+	case LIGHTCRUISER:
+	    return ori_lightcruiser_height;
+	case CARRIER:
+	    return ori_carrier_height;
+	case UTILITY:
+	    return ori_utility_height;
+	case PATROL:
+	    return ori_patrol_height;
+	}
+    case -1:
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_height;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return ind_scout_height;
+	case DESTROYER:
+	    return ind_destroyer_height;
+	case CRUISER:
+	    return ind_cruiser_height;
+	case BATTLESHIP:
+	    return ind_battleship_height;
+	case ASSAULT:
+	    return ind_assault_height;
+	case STARBASE:
+	    return ind_starbase_height;
+	case JUMPSHIP:
+	    return ind_starbase_height;
+	case FLAGSHIP:
+	    return ind_galaxy_height;
+	case GALAXY:
+	    return ind_galaxy_height;
+	case WARBASE:
+	    return ind_starbase_height;
+	case LIGHTCRUISER:
+	    return ind_lightcruiser_height;
+	case CARRIER:
+	    return ind_carrier_height;
+	case UTILITY:
+	    return ind_utility_height;
+	case PATROL:
+	    return ind_patrol_height;
+	}
+    }
+#endif	/* NOSHIPBITMAPS */
+    return 20;
+}
+
+static int
+get_ship_nviews(shipn)
+    int     shipn;
+{
+    if (shipn == STARBASE ||
+	shipn == WARBASE ||
+	shipn == JUMPSHIP 
+#ifdef HOCKEY
+	|| shipn == PUCK
+#endif /*HOCKEY*/
+	)
+	return 1;
+    else
+	return 16;
+}
+
+static unsigned char *
+get_ship_bits(team, shipn, view)
+    int     team, shipn;
+    int     view;
+{
+#ifndef NOSHIPBITMAPS
+    if (shipn == ATT && paradise) {
+	if (view > 0)
+	    view = 0;
+	return att_bits[view];
+    }
+#endif
+    if (view > 16)
+	view = 0;
+    switch (team) {
+    case 0:
+#ifndef NOSHIPBITMAPS
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_bits;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return fed_scout_bits[view];
+	case DESTROYER:
+	    return fed_destroyer_bits[view];
+	case CRUISER:
+	    return fed_cruiser_bits[view];
+	case BATTLESHIP:
+	    return fed_battleship_bits[view];
+	case ASSAULT:
+	    return fed_assault_bits[view];
+	case STARBASE:
+	    return fed_starbase_bits;
+	case JUMPSHIP:
+	    return fed_jumpship_bits;
+	case FLAGSHIP:
+	    return fed_galaxy_bits[view];
+	case GALAXY:
+	    return fed_galaxy_bits[view];
+	case WARBASE:
+	    return fed_warbase_bits;
+	case LIGHTCRUISER:
+	    return fed_lightcruiser_bits[view];
+	case CARRIER:
+	    return fed_carrier_bits[view];
+	case UTILITY:
+	    return fed_utility_bits[view];
+	case PATROL:
+	    return fed_patrol_bits[view];
+	}
+#else
+	if (get_ship_nviews(shipn) == 1)
+	    return fed_starbase_bits;
+	else
+	    return fed_cruiser_bits[view];
+#endif
+    case 1:
+#ifndef NOSHIPBITMAPS
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_bits;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return rom_scout_bits[view];
+	case DESTROYER:
+	    return rom_destroyer_bits[view];
+	case CRUISER:
+	    return rom_cruiser_bits[view];
+	case BATTLESHIP:
+	    return rom_battleship_bits[view];
+	case ASSAULT:
+	    return rom_assault_bits[view];
+	case STARBASE:
+	    return rom_starbase_bits;
+	case JUMPSHIP:
+	    return rom_jumpship_bits;
+	case FLAGSHIP:
+	    return rom_galaxy_bits[view];
+	case GALAXY:
+	    return rom_galaxy_bits[view];
+	case WARBASE:
+	    return rom_warbase_bits;
+	case LIGHTCRUISER:
+	    return rom_lightcruiser_bits[view];
+	case CARRIER:
+	    return rom_carrier_bits[view];
+	case UTILITY:
+	    return rom_utility_bits[view];
+	case PATROL:
+	    return rom_patrol_bits[view];
+	}
+#else
+	if (get_ship_nviews(shipn) == 1)
+	    return rom_starbase_bits;
+	else
+	    return rom_cruiser_bits[view];
+#endif
+    case 2:
+#ifndef NOSHIPBITMAPS
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_bits;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return kli_scout_bits[view];
+	case DESTROYER:
+	    return kli_destroyer_bits[view];
+	case CRUISER:
+	    return kli_cruiser_bits[view];
+	case BATTLESHIP:
+	    return kli_battleship_bits[view];
+	case ASSAULT:
+	    return kli_assault_bits[view];
+	case STARBASE:
+	    return kli_starbase_bits;
+	case JUMPSHIP:
+	    return kli_jumpship_bits;
+	case FLAGSHIP:
+	    return kli_galaxy_bits[view];
+	case GALAXY:
+	    return kli_galaxy_bits[view];
+	case WARBASE:
+	    return kli_warbase_bits;
+	case LIGHTCRUISER:
+	    return kli_lightcruiser_bits[view];
+	case CARRIER:
+	    return kli_carrier_bits[view];
+	case UTILITY:
+	    return kli_utility_bits[view];
+	case PATROL:
+	    return kli_patrol_bits[view];
+	}
+#else
+	if (get_ship_nviews(shipn) == 1)
+	    return kli_starbase_bits;
+	else
+	    return kli_cruiser_bits[view];
+#endif
+    case 3:
+#ifndef NOSHIPBITMAPS
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_bits;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return ori_scout_bits[view];
+	case DESTROYER:
+	    return ori_destroyer_bits[view];
+	case CRUISER:
+	    return ori_cruiser_bits[view];
+	case BATTLESHIP:
+	    return ori_battleship_bits[view];
+	case ASSAULT:
+	    return ori_assault_bits[view];
+	case STARBASE:
+	    return ori_starbase_bits;
+	case JUMPSHIP:
+	    return ori_jumpship_bits;
+	case FLAGSHIP:
+	    return ori_galaxy_bits[view];
+	case GALAXY:
+	    return ori_galaxy_bits[view];
+	case WARBASE:
+	    return ori_warbase_bits;
+	case LIGHTCRUISER:
+	    return ori_lightcruiser_bits[view];
+	case CARRIER:
+	    return ori_carrier_bits[view];
+	case UTILITY:
+	    return ori_utility_bits[view];
+	case PATROL:
+	    return ori_patrol_bits[view];
+	}
+#else
+	if (get_ship_nviews(shipn) == 1)
+	    return ori_starbase_bits;
+	else
+	    return ori_cruiser_bits[view];
+#endif
+    case -1:
+#ifndef NOSHIPBITMAPS
+	switch (shipn) {
+#ifdef HOCKEY
+	case PUCK:
+	    return puck_bits;
+#endif /*HOCKEY*/
+	case SCOUT:
+	    return ind_scout_bits[view];
+	case DESTROYER:
+	    return ind_destroyer_bits[view];
+	case CRUISER:
+	    return ind_cruiser_bits[view];
+	case BATTLESHIP:
+	    return ind_battleship_bits[view];
+	case ASSAULT:
+	    return ind_assault_bits[view];
+	case STARBASE:
+	    return ind_starbase_bits;
+	case JUMPSHIP:
+	    return ind_starbase_bits;
+	case FLAGSHIP:
+	    return ind_galaxy_bits[view];
+	case GALAXY:
+	    return ind_galaxy_bits[view];
+	case WARBASE:
+	    return ind_starbase_bits;
+	case LIGHTCRUISER:
+	    return ind_lightcruiser_bits[view];
+	case CARRIER:
+	    return ind_carrier_bits[view];
+	case UTILITY:
+	    return ind_utility_bits[view];
+	case PATROL:
+	    return ind_patrol_bits[view];
+	}
+#else
+	if (get_ship_nviews(shipn) == 1)
+	    return fed_starbase_bits;
+	else
+	    return fed_cruiser_bits[view];
+#endif
+    }
+    return fed_cruiser_bits[view];
+}
+
+
+/* points at the beginning of the fed ship shapes.  Independent are
+   at negative indices */
+static struct ship_shape *all_ship_shapes = 0;
+
+struct ship_shape *
+shape_of_ship(team, shipclass)
+    int     team, shipclass;
+{
+    if (team < -1 || team >= number_of_teams ||
+	shipclass < 0 || shipclass >= nshiptypes)
+	return &all_ship_shapes[-nshiptypes];
+    return &all_ship_shapes[team * nshiptypes + shipclass];
+}
+
+void
+clear_one_ship_shape(shp)
+    struct ship_shape *shp;
+{
+    int     j;
+    for (j = 0; j < shp->nviews; j++) {
+	W_FreeBitmap(shp->bmap[j]);
+    }
+    shp->nviews = 0;
+    free(shp->bmap);
+    shp->bmap = 0;
+    W_FreeBitmap(shp->shield);
+    shp->shield = 0;
+}
+
+void
+free_shipshapes()
+{
+    /* don't forget that IND offset */
+    int     race, i;
+    if (!all_ship_shapes)	/* if nothing there to begin with */
+	return;
+    for (race = -1; race < number_of_teams; race++) {
+	for (i = 0; i < nshiptypes; i++) {
+	    clear_one_ship_shape(shape_of_ship(race, i));
+	}
+    }
+    free(all_ship_shapes - nshiptypes);
+    all_ship_shapes = 0;
+}
+
+void
+slurp_ship_bitmaps()
+{
+    int     i, race, k;
+    int     width, height, size = 0;
+    int     nviews;		/* NYI */
+    unsigned char *buf = 0, *buf2;
+    char   *freeme;
+    char   *mainbitmapdir, *bitmapdir;
+    static char path[MAXPATHLEN];
+
+    if (all_ship_shapes == 0) {
+	all_ship_shapes = nshiptypes + (struct ship_shape *)
+	    malloc(sizeof(*all_ship_shapes) * (number_of_teams + 1) * nshiptypes);
+    }
+    mainbitmapdir = stringDefault("shipBitmapPath",
+#ifndef AMIGA			/* worked this way, sort of... was annoying. */
+				  "/usr/games/lib/netrek"
+#else
+				  "netrek:graphics"
+#endif				/* AMIGA */
+	);
+    mainbitmapdir = expandFilename(mainbitmapdir);
+
+    for (race = -1 /* IND */ ; race < number_of_teams; race++) {
+	freeme = NULL;
+	/* you can now have a different bitmapDir for each race [BDyess] */
+	sprintf(path, "shipBitmapPath.%d", race);
+	if ((bitmapdir = getdefault(path)) == NULL)
+	    bitmapdir = mainbitmapdir;
+	else
+	    bitmapdir = freeme = expandFilename((char *) strdup(bitmapdir));
+	for (k = 0; k < nshiptypes; k++) {
+	    struct ship_shape *curr_shape = shape_of_ship(race, k);
+	    FILE   *fp;
+	    sprintf(path, "%s/R%d.C%d", bitmapdir, race, k);
+
+	    fp = fopen(path, "r");
+	    if (fp == 0) {
+		if (errno != ENOENT) {
+		    fprintf(stderr, "Error accessing ship bitmap file %s:", path);
+		    perror("");
+		}
+		nviews = get_ship_nviews(k, 0);
+		width = get_ship_width(race, k, 0);
+		height = get_ship_height(race, k, 0);
+	    } else {
+		fread(&nviews, sizeof(nviews), 1, fp);
+		nviews = ntohl(nviews);
+		fread(&width, sizeof(width), 1, fp);
+		width = ntohl(width);
+		fread(&height, sizeof(height), 1, fp);
+		height = ntohl(height);
+		if (nviews > get_ship_nviews(k, 0))
+		    nviews = get_ship_nviews(k, 0);
+		size = (width + 7) / 8 * height;
+		buf = (unsigned char *) malloc(size);
+	    }
+
+	    curr_shape->nviews = nviews /* nviews */ ;
+	    curr_shape->width = width;
+	    curr_shape->height = height;
+	    curr_shape->shield = W_MakeShieldBitmap(width, height, w);
+
+	    curr_shape->bmap = (W_Icon *) malloc(sizeof(*curr_shape->bmap) *
+						 nviews);
+
+	    for (i = 0; i < nviews; i++) {
+		if (fp) {
+		    fread(buf, size, 1, fp);
+		    curr_shape->bmap[i] =
+			W_StoreBitmap(width, height, buf, w);
+		} else {
+		    buf2 = get_ship_bits(race, k, i);
+		    curr_shape->bmap[i] =
+			W_StoreBitmap(width, height, buf2, w);
+		}
+
+#if 0
+		/* these widths and heights are not necessarily correct */
+		if (fp)
+		    buf2 = get_ship_bits(race, k, i, blk_altbits);
+		else
+		    buf2 = get_ship_bits(race, k, i, !blk_altbits);
+
+		curr_shape->bmap[i + (blk_altbits ? 0 : nviews)] =
+		    W_StoreBitmap(width, height, buf2, w);
+#endif
+	    }
+
+	    if (fp) {
+		free(buf);
+		fclose(fp);
+	    }
+	}
+	if (freeme)
+	    free(freeme);
+    }
+}
+
+void
+replace_shipshape(race, shiptype, nviews, width, height)
+    int     race, shiptype, nviews, width, height;
+{
+    struct ship_shape *shp = shape_of_ship(race, shiptype);
+    int     i;
+
+    clear_one_ship_shape(shp);
+
+    shp->nviews = nviews;
+    shp->bmap = (W_Icon *) malloc(sizeof(*shp->bmap) * nviews);
+    shp->width = width;
+    shp->height = height;
+    shp->shield = W_MakeShieldBitmap(width, height, w);
+    for (i = 0; i < nviews; i++) {
+	/* we really should check the files again. */
+	shp->bmap[i] = W_StoreBitmap(get_ship_width(race, shiptype),
+				     get_ship_height(race, shiptype),
+				     get_ship_bits(race, shiptype, i, 0),
+				     w);
+#if 0
+	shp->bmap[i + nviews] = W_StoreBitmap(get_ship_width(race, shiptype),
+					    get_ship_height(race, shiptype),
+					get_ship_bits(race, shiptype, i, 0),
+					      w);
+#endif
+    }
+}
+
+
+void
+replace_ship_bitmap(race, shiptype, view, bits)
+    int     race, shiptype, view;
+    unsigned char *bits;
+{
+    struct ship_shape *shp = shape_of_ship(race, shiptype);
+
+    if (view >= shp->nviews) {
+	fprintf(stderr, "race %d, ship class %d: view %d out of range (0..%d)\n",
+		race, shiptype, view, shp->nviews - 1);
+	return;
+    }
+    W_FreeBitmap(shp->bmap[view]);
+    /* store the bitmaps into the auxiliary view */
+    shp->bmap[view] = W_StoreBitmap(shp->width, shp->height, bits, w);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/shortcomm.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1387 @@
+/* $Id: shortcomm.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $ */
+
+/* This file implements all SHORT_PACKETS functions */
+/*  HW 19.07.93 */
+#ifdef SHORT_PACKETS
+
+#ifdef HPBSD
+#include <machine/endian.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#ifdef RS6K
+#include <sys/select.h>
+#endif				/* RS6K */
+#include <netdb.h>
+#include <math.h>
+#include <errno.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "gameconf.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif
+#include "sound.h"
+
+#if 1
+
+char   *
+ship_type(shp)
+    struct ship *shp;
+{
+    static char ring[4][3];
+    static int ri;
+    char   *rval;
+    ring[ri][0] = shp->s_desig[0];
+    ring[ri][1] = shp->s_desig[1];
+    ring[ri][2] = 0;
+    rval = ring[ri];
+    ri++;
+    if (ri >= sizeof(ring) / sizeof(*ring))
+	ri = 0;
+    return rval;
+}
+#define TEAM_LETTER(p) ( teaminfo[(p).p_teami].letter )
+#define TEAM_SHORT(p) ( teaminfo[(p).p_teami].shortname )
+#define TEAM_LETTERP(pl) ( teaminfo[mask_to_idx((pl).pl_owner)].letter )
+#define TEAM_SHORTP(pl) ( teaminfo[mask_to_idx((pl).pl_owner)].shortname )
+#define reviewWin	messWin[WREVIEW].window
+#define MAXTORP	ntorps
+#define MAXPLANETS	nplanets
+#define MAXPLASMA	nplasmas
+
+#else
+
+#define ship_type(shp)	shiptype[(shp).s_type]
+#define TEAM_LETTER(p) ( teamlet[(p).p_team] )
+#define TEAM_SHORT(p) ( teamshort[(p).p_team] )
+#define TEAM_LETTERP(pl) ( teamlet[(pl).pl_owner] )
+#define TEAM_SHORTP(pl) ( teamshort[(pl).pl_owner] )
+
+#endif
+
+/* from here on all SHORT_PACKETS */
+#include "wtext.h"		/* here are all warningdefines */
+
+/*      Here are all warnings that are send with SP_S_WARNING */
+/*              HW 93           */
+
+/* DaemonMessages */
+char   *daemon_texts[] =
+{
+/* Game_Paused() */
+    "Game is paused.  CONTINUE to continue.",	/* 0 */
+    "Game is no-longer paused!",/* 1 */
+    "Game is paused. Captains CONTINUE to continue.",	/* 2 */
+    "Game will continue in 10 seconds",	/* 3 */
+/* send_about_to_start() */
+    "Teams chosen.  Game will start in 1 minute.",	/* 4 */
+    "----------- Game will start in 1 minute -------------",	/* 5 */
+};
+
+/* VARITEXTE = warnings with 1 or more arguments argument */
+char   *vari_texts[] =
+{
+/* redraw.c */
+    "Engineering:  Energizing transporters in %d seconds",	/* 0 */
+    "Stand By ... Self Destruct in %d seconds",	/* 1 */
+    "Helmsman:  Docking manuever completed Captain.  All moorings secured at port %d.",	/* 2 */
+/* interface.c from INL server */
+    "Not constructed yet. %d minutes required for completion",	/* 3 */
+
+};
+
+
+
+char   *w_texts[] =
+{
+/* socket.c             */
+    "Tractor beams haven't been invented yet.",	/* 0 */
+    "Weapons's Officer:  Cannot tractor while cloaked, sir!",	/* 1 */
+    "Weapon's Officer:  Vessel is out of range of our tractor beam.",	/* 2 */
+
+/* handleRepressReq */
+/****************       coup.c  ***********************/
+/*      coup()  */
+    "You must have one kill to throw a coup",	/* 3 */
+    "You must orbit your home planet to throw a coup",	/* 4 */
+    "You already own a planet!!!",	/* 5 */
+    "You must orbit your home planet to throw a coup",	/* 6 */
+    "Too many armies on planet to throw a coup",	/* 7 */
+    "Planet not yet ready for a coup",	/* 8 */
+/*      getentry.c              */
+/*      getentry()              */
+    "I cannot allow that.  Pick another team",	/* 9 */
+    "Please confirm change of teams.  Select the new team again.",	/* 10 */
+    "That is an illegal ship type.  Try again.",	/* 11 */
+    "That ship hasn't beed designed yet.  Try again.",	/* 12 */
+    "Your new starbase is still under construction",	/* 13 */
+    "Your team is not capable of defending such an expensive ship!",	/* 14 */
+    "Your team's stuggling economy cannot support such an expenditure!",	/* 15 */
+    "Your side already has a starbase!",	/* 16 */
+/*      plasma.c        */
+/* nplasmatorp(course, type)    */
+    "Plasmas haven't been invented yet.",	/* 17 */
+    "Weapon's Officer:  Captain, this ship is not armed with plasma torpedoes!",	/* 18 */
+    "Plasma torpedo launch tube has exceeded the maximum safe temperature!",	/* 19 */
+    "Our fire control system limits us to 1 live torpedo at a time captain!",	/* 20 */
+    "Our fire control system limits us to 1 live torpedo at a time captain!",	/* 21 */
+    "We don't have enough fuel to fire a plasma torpedo!",	/* 22 */
+    "We cannot fire while our vessel is undergoing repairs.",	/* 23 */
+    "We are unable to fire while in cloak, captain!",	/* 24 */
+/********       torp.c  *********/
+/*      ntorp(course, type)     */
+    "Torpedo launch tubes have exceeded maximum safe temperature!",	/* 25 */
+    "Our computers limit us to having 8 live torpedos at a time captain!",	/* 26 */
+    "We don't have enough fuel to fire photon torpedos!",	/* 27 */
+    "We cannot fire while our vessel is in repair mode.",	/* 28 */
+    "We are unable to fire while in cloak, captain!",	/* 29 */
+    "We only have forward mounted cannons.",	/* 30 */
+/*      phasers.c       */
+/*      phaser(course) */
+    "Weapons Officer:  This ship is not armed with phasers, captain!",	/* 31 */
+    "Phasers have not recharged",	/* 32 */
+    "Not enough fuel for phaser",	/* 33 */
+    "Can't fire while repairing",	/* 34 */
+    "Weapons overheated",	/* 35 */
+    "Cannot fire while cloaked",/* 36 */
+    "Phaser missed!!!",		/* 37 */
+    "You destroyed the plasma torpedo!",	/* 38 */
+/*      interface.c     */
+/* bomb_planet()        */
+    "Must be orbiting to bomb",	/* 39 */
+    "Can't bomb your own armies.  Have you been reading Catch-22 again?",	/* 40 */
+    "Must declare war first (no Pearl Harbor syndrome allowed here).",	/* 41 */
+    "Bomb out of T-mode?  Please verify your order to bomb.",	/* 42 */
+    "Hoser!",			/* 43 */
+/*      beam_up()       */
+    "Must be orbiting or docked to beam up.",	/* 44 */
+    "Those aren't our men.",	/* 45 */
+    "Comm Officer: We're not authorized to beam foriegn troops on board!",	/* 46 */
+/* beam_down() */
+    "Must be orbiting or docked to beam down.",	/* 47 */
+    "Comm Officer: Starbase refuses permission to beam our troops over.",	/* 48 */
+/*      declare_war(mask)       */
+    "Pausing ten seconds to re-program battle computers.",	/* 49 */
+/* do_refit(type) */
+    "You must orbit your HOME planet to apply for command reassignment!",	/* 50 */
+    "You must orbit your home planet to apply for command reassignment!",	/* 51 */
+    "Can only refit to starbase on your home planet.",	/* 52 */
+    "You must dock YOUR starbase to apply for command reassignment!",	/* 53 */
+    "Must orbit home planet or dock your starbase to apply for command reassignment!",	/* 54 */
+    "Central Command refuses to accept a ship in this condition!",	/* 55 */
+    "You must beam your armies down before moving to your new ship",	/* 56 */
+    "That ship hasn't been designed yet.",	/* 57 */
+    "Your side already has a starbase!",	/* 58 */
+    "Your team is not capable of defending such an expensive ship",	/* 59 */
+    "Your new starbase is still under construction",	/* 60 */
+    "Your team's stuggling economy cannot support such an expenditure!",	/* 61 */
+    "You are being transported to your new vessel .... ",	/* 62 */
+/* redraw.c */
+/* auto_features()  */
+    "Engineering:  Energize. [ SFX: chimes ]",	/* 63 */
+    "Wait, you forgot your toothbrush!",	/* 64 */
+    "Nothing like turning in a used ship for a new one.",	/* 65 */
+    "First officer:  Oh no, not you again... we're doomed!",	/* 66 */
+    "First officer:  Uh, I'd better run diagnostics on the escape pods.",	/* 67 */
+    "Shipyard controller:  This time, *please* be more careful, okay?",	/* 68 */
+    "Weapons officer:  Not again!  This is absurd...",	/* 69 */
+    "Weapons officer:  ... the whole ship's computer is down?",	/* 70 */
+    "Weapons officer:  Just to twiddle a few bits of the ship's memory?",	/* 71 */
+    "Weapons officer:  Bah! [ bangs fist on inoperative console ]",	/* 72 */
+    "First Officer:  Easy, big guy... it's just one of those mysterious",	/* 73 */
+    "First Officer:  laws of the universe, like 'tires on the ether'.",	/* 74 */
+    "First Officer:  laws of the universe, like 'Klingon bitmaps are ugly'.",	/* 75 */
+    "First Officer:  laws of the universe, like 'all admirals have scummed'.",	/* 76 */
+    "First Officer:  laws of the universe, like 'Mucus Pig exists'.",	/* 77 */
+    "First Officer:  laws of the universe, like 'guests advance 5x faster'.",	/* 78 */
+/* orbit.c */
+/*orbit() */
+    "Helmsman: Captain, the maximum safe speed for docking or orbiting is warp 2!",	/* 79 */
+    "Central Command regulations prohibits you from orbiting foreign planets",	/* 80 */
+    "Helmsman:  Sensors read no valid targets in range to dock or orbit sir!",	/* 81 */
+/* redraw.c */
+    "No more room on board for armies",	/* 82 */
+    "You notice everyone on the bridge is staring at you.",	/* 83 */
+/* startdaemon.c */
+/* practice_robo() */
+    "Can't send in practice robot with other players in the game.",	/* 84 */
+/*      socket.c */
+/*      doRead(asock) */
+    "Self Destruct has been canceled",	/* 85 */
+/* handleMessageReq(packet) */
+    "Be quiet",			/* 86 */
+    "You are censured.  Message was not sent.",	/* 87 */
+    "You are ignoring that player.  Message was not sent.",	/* 88 */
+    "That player is censured.  Message was not sent.",	/* 89 */
+/* handleQuitReq(packet) */
+    "Self destruct initiated",	/* 90 */
+/* handleScan(packet) */
+    "Scanners haven't been invented yet",	/* 91 */
+/* handleUdpReq(packet) */
+    "WARNING: BROKEN mode is enabled",	/* 92 */
+    "Server can't do that UDP mode",	/* 93 */
+    "Server will send with TCP only",	/* 94 */
+    "Server will send with simple UDP",	/* 95 */
+    "Request for fat UDP DENIED (set to simple)",	/* 96 */
+    "Request for double UDP DENIED (set to simple)",	/* 97 */
+/* forceUpdate() */
+    "Update request DENIED (chill out!)",	/* 98 */
+/* INL redraw.c */
+    "Player lock lost while player dead.",	/* 99 */
+    "Can only lock on own team.",	/* 100 */
+    "You can only warp to your own team's planets!",	/* 101 */
+    "Planet lock lost on change of ownership.",	/* 102 */
+    " Weapons officer: Finally! systems are back online!",	/* 103 */
+
+};
+
+#define NUMWTEXTS (sizeof w_texts / sizeof w_texts[0])
+#define NUMVARITEXTS ( sizeof vari_texts / sizeof   vari_texts[0])
+#define NUMDAEMONTEXTS ( sizeof daemon_texts / sizeof daemon_texts[0])
+
+
+void    add_whydead();
+
+extern int vtisize[];
+extern unsigned char numofbits[];
+#if 0
+int     Plx[MAX_PLAYER], Ply[MAX_PLAYER], Pgx[MAX_PLAYER], Pgy[MAX_PLAYER];
+unsigned char Pdir[MAX_PLAYER];
+#endif
+int     my_x, my_y;		/* for rotation we need to keep track of our
+				   real coordinates */
+/* SP_S_WARNING vari texte */
+char   *s_texte[256];		/* Better with a malloc scheme */
+char    no_memory[] =
+{"Not enough memory for warning string!"};
+
+#if 0
+/* For INL Server */
+char   *shiptype[NUM_TYPES] =
+{"SC", "DD", "CA", "BB", "AS", "SB", "??"};
+#endif
+int     spwinside = 500;	/* WINSIDE from Server */
+long    spgwidth = 100000;
+
+
+void
+sendThreshold(v)
+    unsigned short v;
+{
+    struct threshold_cpacket p;
+
+    p.type = CP_S_THRS;
+    p.thresh = v;
+    sendServerPacket((struct player_spacket *) & p);
+}
+
+void
+handleVTorp(sbuf)
+    unsigned char *sbuf;
+{
+    unsigned char *which, *data;
+    unsigned char bitset;
+    struct torp *thetorp;
+    int     dx, dy;
+    int     shiftvar;
+
+    int     i;
+    register int shift = 0;	/* How many torps are extracted (for shifting
+				   ) */
+
+/* now we must find the data ... :-) */
+    if (sbuf[0] == SP_S_8_TORP) {	/* MAX packet */
+	bitset = 0xff;
+	which = &sbuf[1];
+	data = &sbuf[2];
+    } else {			/* Normal Packet */
+	bitset = sbuf[1];
+	which = &sbuf[2];
+	data = &sbuf[3];
+    }
+
+#ifdef CORRUPTED_PACKETS
+/* we probably should do something clever here - jmn */
+#endif
+
+    thetorp = &torps[((unsigned char) *which * 8)];
+    for (shift = 0, i = 0; i < 8;
+#if defined(RS6K) || defined(__SABER__)
+	 i++, thetorp++, bitset >>= 1) {
+#else
+	 i++, thetorp++, bitset = ((unsigned char)bitset) >> 1) {
+#endif
+	if (bitset & 01) {
+	    dx = (*data >> shift);
+	    data++;
+	    shiftvar = (unsigned char) *data;	/* to silence gcc */
+	    shiftvar <<= (8 - shift);
+	    dx |= (shiftvar & 511);
+	    shift++;
+	    dy = (*data >> shift);
+	    data++;
+	    shiftvar = (unsigned char) *data;	/* to silence gcc */
+	    shiftvar <<= (8 - shift);
+	    dy |= (shiftvar & 511);
+	    shift++;
+	    if (shift == 8) {
+		shift = 0;
+		data++;
+	    }
+/* This is necessary because TFREE/TMOVE is now encoded in the bitset */
+	    if (thetorp->t_status == TFREE) {
+		thetorp->t_status = TMOVE;	/* guess */
+		players[thetorp->t_owner].p_ntorp++;
+#ifdef UNIX_SOUND
+            play_sound (SND_FIRETORP); /* Fire Torp */
+#endif
+	    } else if (thetorp->t_owner == me->p_no && thetorp->t_status == TEXPLODE) {
+		thetorp->t_status = TMOVE;	/* guess */
+	    }
+	    /* Check if torp is visible */
+	    if (dx > spwinside || dy > spwinside) {
+		thetorp->t_x = -100000;	/* Not visible */
+		thetorp->t_y = -100000;
+	    } else {		/* visible */
+/*	    thetorp->t_x = me->p_x + ((dx - spwinside / 2) * SCALE);
+	    thetorp->t_y = me->p_y + ((dy - spwinside / 2) * SCALE); */
+		thetorp->t_x = my_x + ((dx - spwinside / 2) * SCALE);
+		thetorp->t_y = my_y + ((dy - spwinside / 2) * SCALE);
+#ifdef ROTATERACE
+		if (rotate) {
+		    rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg,
+				 spgwidth / 2, spgwidth / 2);
+		}
+#endif
+	    }
+	}
+	/* if */
+	else {			/* We got a TFREE */
+	    if (thetorp->t_status && thetorp->t_status != TEXPLODE) {
+		players[thetorp->t_owner].p_ntorp--;
+		thetorp->t_status = TFREE;	/* That's no guess */
+	    }
+	}
+    }				/* for */
+}
+
+void
+handleSelfShort(packet)
+    struct youshort_spacket *packet;
+{
+    me = (ghoststart ? &players[ghost_pno] : &players[packet->pnum]);
+    myship = me->p_ship;
+    mystats = &(me->p_stats);
+    me->p_hostile = packet->hostile;
+    me->p_swar = packet->swar;
+    me->p_armies = packet->armies;
+    me->p_flags = ntohl(packet->flags);
+    me->p_whydead = packet->whydead;
+    me->p_whodead = packet->whodead;
+#ifdef SOUND
+    S_HandlePFlags();
+#endif
+}
+
+void
+handleSelfShip(packet)
+    struct youss_spacket *packet;
+{
+    if (!me)
+	return;			/* wait.. */
+
+    me->p_damage = ntohs(packet->damage);
+    me->p_shield = ntohs(packet->shield);
+    me->p_fuel = ntohs(packet->fuel);
+    me->p_etemp = ntohs(packet->etemp);
+    me->p_wtemp = ntohs(packet->wtemp);
+#ifdef SOUND
+    S_HandlePFlags();
+#endif
+}
+
+void
+handleVPlayer(sbuf)
+    unsigned char *sbuf;
+{
+    register int x, y, i, numofplayers, pl_no, save;
+    register struct player *pl;
+    unsigned char newdir;	/* needed for uncloak kludge with ROTATERACE */
+    int     offset;
+
+    numofplayers = (unsigned char) sbuf[1] & 0x3f;
+
+    if (sbuf[1] & (unsigned char) 128) {	/* Short Header + Extended */
+	sbuf += 4;
+	offset = 32;		/* more than 32 players? */
+    } else if (sbuf[1] & 64) {	/* Short Header  */
+	sbuf += 4;
+	offset = 0;
+    } else {
+	struct player_s_spacket *packet = (struct player_s_spacket *) sbuf;
+	pl = &players[me->p_no];
+	pl->p_dir = (unsigned char) packet->dir;
+#if 0
+	Pdir[me->p_no] = (unsigned char) rosette(pl->p_dir, 16);
+#endif
+	pl->p_speed = packet->speed;
+#ifdef FEATURE
+	if (F_dead_warp && (pl->p_speed == 14)) {
+	    if (pl->p_status == PALIVE) {
+		pl->p_status = PEXPLODE;
+		pl->p_explode = 0;
+	    }
+	} else
+#endif
+	{
+	    pl->p_x = my_x = ntohl(packet->x);
+	    pl->p_y = my_y = ntohl(packet->y);
+#ifdef ROTATERACE
+	    if (rotate) {
+		rotate_coord(&pl->p_x, &pl->p_y,
+			     rotate_deg, spgwidth / 2, spgwidth / 2);
+		rotate_dir(&pl->p_dir, rotate_deg);
+	    }
+#endif
+#if 0
+	    Plx[me->p_no] = WINSIDE / 2;
+	    Ply[me->p_no] = WINSIDE / 2;
+	    Pgx[me->p_no] = pl->p_x * WINSIDE / spgwidth;
+	    Pgy[me->p_no] = pl->p_y * WINSIDE / spgwidth;
+#endif
+	}
+	redrawPlayer[me->p_no] = 1;
+	sbuf += 12;		/* Now the small packets */
+	offset = 0;
+    }
+    for (i = 0; i < numofplayers; i++) {
+	pl_no = ((unsigned char) *sbuf & 0x1f) + offset;
+	if (pl_no >= nplayers)
+	    continue;
+	save = (unsigned char) *sbuf;
+	sbuf++;
+	pl = &players[pl_no];
+	pl->p_speed = (unsigned char) *sbuf & 15;	/* SPEED */
+#if 0
+	Pdir[pl_no] = (unsigned char) *sbuf >> 4;	/* DIR */
+#endif
+	newdir = (unsigned char) *sbuf & 0xf0;	/* realDIR */
+
+#ifdef ROTATERACE
+	if (rotate)
+	    rotate_dir(&newdir, rotate_deg);
+#endif
+#ifdef FEATURE
+	if (cloakerMaxWarp) {
+	    if (pl->p_speed == 15)
+		pl->p_flags |= PFCLOAK;
+	    else
+		pl->p_flags &= ~(PFCLOAK);
+	} else
+#endif
+	{
+#ifdef CHECK_DROPPED
+	    /*
+	       this is a mess.  Too many exceptions.  I don't use it any
+	       more.  cloakerMaxWarp is much much better, but requires server
+	       support.
+	    */
+	    /*
+	       Kludge to fix lost uncloak packets! [3/94] -JR may be a
+	       problem with server sending directions after cloakphase is at
+	       CLOAK_PHASES-1, since cloakphase is strictly a client variable
+	       :(
+	    */
+	    if (pl->p_flags & PFCLOAK && pl->p_cloakphase >= (CLOAK_PHASES - 1) &&
+		(pl->p_dir & 0xf0 != newdir & 0xf0) && !(pl->p_flags & PFORBIT)) {
+		int     i, plocked = 0;
+		for (i = 0; i < nplayers; i++) {
+		    if ((phasers[i].ph_status & PHHIT) && (phasers[i].ph_target == pl_no)) {
+			plocked = 1;
+			break;
+		    }
+		}
+		if (!plocked)
+		    /*
+		       if all of the above, the guy is *probably* uncloaked.
+		       Ask the server.
+		    */
+		    sendShortReq(SPK_SALL);
+	    }
+#endif
+	}
+	pl->p_dir = newdir;	/* realDIR */
+
+	sbuf++;
+	x = (unsigned char) *sbuf++;
+	y = (unsigned char) *sbuf++;	/* The lower 8 Bits are saved */
+
+	/* Now we must preprocess the coordinates */
+	if ((unsigned char) save & 64)
+	    x |= 256;
+	if ((unsigned char) save & 128)
+	    y |= 256;
+#ifdef FEATURE
+	/*
+	   MAY CHANGE!  dead_warp is still an experiment, some servers are
+	   also sending illegal co-ords for dead players, so we'll just
+	   ignore 'em for now if the guy's dead.
+	*/
+	if (F_dead_warp && pl->p_speed == 14) {
+	    if (pl->p_status == PALIVE) {
+		pl->p_status = PEXPLODE;
+		pl->p_explode = 0;
+	    }
+	    redrawPlayer[pl->p_no] = 1;
+	    continue;
+	}
+#endif
+	/* Now test if it's galactic or local coord */
+	if (save & 32) {	/* It's galactic */
+#if 0
+	    if (x >= 501 || y >= 501) {
+		pl->p_x = -500 * spgwidth / spwinside;
+		pl->p_y = -500 * spgwidth / spwinside;
+	    } else
+#endif
+	    {
+		pl->p_x = x * spgwidth / spwinside;
+		pl->p_y = y * spgwidth / spwinside;
+	    }
+#if 0
+	    Pgx[pl_no] = x;
+	    Pgy[pl_no] = y;
+	    Plx[pl_no] = -1;	/* Not visible */
+	    Ply[pl_no] = -1;
+#endif
+	} else {		/* Local */
+	    pl->p_x = my_x + ((x - spwinside / 2) * SCALE);
+	    pl->p_y = my_y + ((y - spwinside / 2) * SCALE);
+#if 0
+	    Plx[pl_no] = x;
+	    Ply[pl_no] = y;
+	    Pgx[pl_no] = pl->p_x * spwinside / spgwidth;
+	    Pgy[pl_no] = pl->p_y * spwinside / spgwidth;
+#endif
+	}
+	redrawPlayer[pl->p_no] = 1;
+#ifdef ROTATERACE
+	if (rotate) {
+	    rotate_coord(&pl->p_x, &pl->p_y,
+			 rotate_deg, spgwidth / 2, spgwidth / 2);
+	}
+#endif
+    }				/* for */
+}
+
+void
+handleSMessage(packet)
+    struct mesg_s_spacket *packet;
+{
+    char    buf[100];
+    char    addrbuf[9];
+
+#if 0
+    if (debug)
+	printf("Length of Message is: %d  total Size %d \n", strlen(&packet->mesg), (int) packet->length);
+#endif
+    if (packet->m_from >= nplayers)
+	packet->m_from = 255;
+
+    if (packet->m_from == 255)
+	strcpy(addrbuf, "GOD->");
+    else {
+	sprintf(addrbuf, " %c%c->", TEAM_LETTER(players[packet->m_from]),
+		shipnos[players[packet->m_from].p_no]);
+    }
+
+    switch (packet->m_flags & (MTEAM | MINDIV | MALL)) {
+    case MALL:
+	sprintf(addrbuf + 5, "ALL");
+	break;
+    case MTEAM:
+	sprintf(addrbuf + 5, TEAM_SHORT(*me));
+	break;
+    case MINDIV:
+	/* I know that it's me -> xxx but i copied it straight ... */
+	sprintf(addrbuf + 5, "%c%c ", TEAM_LETTER(players[packet->m_recpt]),
+		shipnos[packet->m_recpt]);
+	break;
+    default:
+	sprintf(addrbuf + 5, "ALL");
+	break;
+    }
+    sprintf(buf, "%-9s%s", addrbuf, &packet->mesg);
+    dmessage(buf, packet->m_flags, packet->m_from, packet->m_recpt);
+}
+
+void
+handleShortReply(packet)
+    struct shortreply_spacket *packet;
+{
+    switch (packet->repl) {
+    case SPK_VOFF:
+	recv_short = 0;
+	sprefresh(SPK_VFIELD);
+	break;
+    case SPK_VON:
+	recv_short = 1;
+	sprefresh(SPK_VFIELD);
+
+	spwinside = (CARD16) ntohs(packet->winside);
+	/*
+	   bug in server-side SP code, wrong-endian machines confuse a client
+	   with normal byte order
+	*/
+	if (spwinside == 0xf401)
+	    spwinside = 0x01f4;
+
+	if (paradise) {
+	    spgwidth = (INT32) ntohl(packet->gwidth);
+	    blk_gwidth = spgwidth;
+	    blk_windgwidth = (float)spwinside;
+	    redrawall = 1;
+
+	    /*
+	       bug in server-side SP code, wrong-endian machines confuse a
+	       client with normal byte order
+	    */
+	    if (spgwidth == 0xa0860100)
+		spgwidth = 0x000186a0;
+	    if (spgwidth == 0x0100)
+		spgwidth = 0x000186a0;
+	}
+	break;
+    case SPK_MOFF:
+	recv_mesg = 0;
+	sprefresh(SPK_MFIELD);
+	W_SetSensitive(reviewWin, 0);
+	break;
+    case SPK_MON:
+	recv_mesg = 1;
+	sprefresh(SPK_MFIELD);
+	W_SetSensitive(reviewWin, 1);
+	break;
+    case SPK_M_KILLS:
+	recv_kmesg = 1;
+	sprefresh(SPK_KFIELD);
+	break;
+    case SPK_M_NOKILLS:
+	recv_kmesg = 0;
+	sprefresh(SPK_KFIELD);
+	break;
+    case SPK_M_WARN:
+	recv_warn = 1;
+	sprefresh(SPK_WFIELD);
+	break;
+    case SPK_M_NOWARN:
+	recv_warn = 0;
+	sprefresh(SPK_WFIELD);
+	break;
+
+    case SPK_THRESHOLD:
+	break;
+    default:
+	fprintf(stderr, "%s: unknown response packet value short-req: %d\n",
+		"netrek", packet->repl);
+    }
+}
+
+void
+handleVTorpInfo(sbuf)
+    unsigned char *sbuf;
+{
+    unsigned char *bitset, *which, *data, *infobitset, *infodata;
+    struct torp *thetorp;
+    int     dx, dy;
+    int     shiftvar;
+    char    status, war;
+    register int i;
+    register int shift = 0;	/* How many torps are extracted (for shifting
+				   ) */
+
+/* now we must find the data ... :-) */
+    bitset = &sbuf[1];
+    which = &sbuf[2];
+    infobitset = &sbuf[3];
+/* Where is the data ? */
+    data = &sbuf[4];
+    infodata = &sbuf[vtisize[numofbits[(unsigned char) sbuf[1]]]];
+
+    thetorp = &torps[(unsigned char) (*which * 8)];
+
+    for (shift = 0, i = 0; i < 8;
+#if defined(RS6K) || defined(__SABER__)
+	 thetorp++, *bitset >>= 1, *infobitset >>= 1, i++) {
+#else
+	 thetorp++, *bitset = ((unsigned char)*bitset)  >> 1, *infobitset = ((unsigned char) *infobitset) >> 1, i++) {
+#endif
+
+	if (*bitset & 01) {
+	    dx = (*data >> shift);
+	    data++;
+	    shiftvar = (unsigned char) *data;	/* to silence gcc */
+	    shiftvar <<= (8 - shift);
+	    dx |= (shiftvar & 511);
+	    shift++;
+	    dy = (*data >> shift);
+	    data++;
+	    shiftvar = (unsigned char) *data;	/* to silence gcc */
+	    shiftvar <<= (8 - shift);
+	    dy |= (shiftvar & 511);
+	    shift++;
+	    if (shift == 8) {
+		shift = 0;
+		data++;
+	    }
+	    /* Check for torp with no TorpInfo */
+	    if (!(*infobitset & 01)) {
+		if (thetorp->t_status == TFREE) {
+		    thetorp->t_status = TMOVE;	/* guess */
+		    players[thetorp->t_owner].p_ntorp++;
+		} else if (thetorp->t_owner == me->p_no &&
+			   thetorp->t_status == TEXPLODE) {	/* If TFREE got lost */
+		    thetorp->t_status = TMOVE;	/* guess */
+		}
+	    }
+	    /* Check if torp is visible */
+	    if (dx > spwinside || dy > spwinside) {
+		thetorp->t_x = -100000;	/* Not visible */
+		thetorp->t_y = -100000;
+	    } else {		/* visible */
+/*	    thetorp->t_x = me->p_x + ((dx - spwinside / 2) * SCALE);
+	    thetorp->t_y = me->p_y + ((dy - spwinside / 2) * SCALE);
+*/
+		thetorp->t_x = my_x + ((dx - spwinside / 2) *
+				       SCALE);
+		thetorp->t_y = my_y + ((dy - spwinside / 2) *
+				       SCALE);
+
+#ifdef ROTATERACE
+		if (rotate) {
+		    rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg,
+				 spgwidth / 2, spgwidth / 2);
+		}
+#endif
+	    }
+	}
+	/* if */
+	else {			/* Got a TFREE ? */
+	    if (!(*infobitset & 01)) {	/* No other TorpInfo for this Torp */
+		if (thetorp->t_status && thetorp->t_status != TEXPLODE) {
+		    players[thetorp->t_owner].p_ntorp--;
+		    thetorp->t_status = TFREE;	/* That's no guess */
+		}
+	    }
+	}
+	/* Now the TorpInfo */
+	if (*infobitset & 01) {
+	    war = (unsigned char) *infodata & 15 /* 0x0f */ ;
+	    status = ((unsigned char) *infodata & 0xf0) >> 4;
+	    infodata++;
+	    if (status == TEXPLODE && thetorp->t_status == TFREE) {
+		/* FAT: redundant explosion; don't update p_ntorp */
+		continue;
+	    }
+	    if (thetorp->t_status == TFREE && status) {
+		players[thetorp->t_owner].p_ntorp++;
+#ifdef UNIX_SOUND
+                play_sound (SND_FIRETORP); /* Fire Torp */
+#endif
+	    }
+	    if (thetorp->t_status && status == TFREE) {
+		players[thetorp->t_owner].p_ntorp--;
+	    }
+	    thetorp->t_war = war;
+	    if (status != thetorp->t_status) {
+		/* FAT: prevent explosion reset */
+		thetorp->t_status = status;
+		if (thetorp->t_status == TEXPLODE) {
+		    thetorp->t_fuse = NUMDETFRAMES;
+		}
+	    }
+	}			/* if */
+    }				/* for */
+}
+
+void
+handleVPlanet(sbuf)
+    unsigned char *sbuf;
+{
+    register int i;
+    register int numofplanets;	/* How many Planets are in the packet */
+    struct planet *plan;
+    struct planet_s_spacket *packet = (struct planet_s_spacket *) & sbuf[2];
+    /* FAT: prevent excessive redraw */
+    int     redraw = 0;
+
+    numofplanets = (unsigned char) sbuf[1];
+
+    if (numofplanets > MAXPLANETS + 1)
+	return;
+
+    for (i = 0; i < numofplanets; i++, packet++) {
+	if (packet->pnum < 0 || packet->pnum >= MAXPLANETS)
+	    continue;
+
+	plan = &planets[packet->pnum];
+	if (plan->pl_owner != packet->owner)
+	    redraw = 1;
+	plan->pl_owner = packet->owner;
+
+	if (plan->pl_info != packet->info)
+	    redraw = 1;
+
+	plan->pl_info = packet->info;
+	/* Redraw the planet because it was updated by server */
+
+	if (plan->pl_flags != (int) ntohs(packet->flags))
+	    redraw = 1;
+	plan->pl_flags = (int) ntohs(packet->flags);
+
+	if (plan->pl_armies != (unsigned char) packet->armies) {
+/*#ifdef EM*/
+	    /*
+	       don't redraw when armies change unless it crosses the '4' *
+	       army limit. Keeps people from watching for planet 'flicker' *
+	       when players are beaming
+	    */
+	    int     planetarmies = (unsigned char) packet->armies;
+	    if ((plan->pl_armies < 5 && planetarmies > 4) ||
+		(plan->pl_armies > 4 && planetarmies < 5))
+/*#endif*/
+		redraw = 1;
+	}
+
+	plan->pl_armies = (unsigned char) packet->armies;
+	if (plan->pl_info == 0) {
+	    plan->pl_owner = NOBODY;
+	}
+
+	if (redraw) {
+	    plan->pl_flags |= PLREDRAW;
+	    pl_update[packet->pnum].plu_update = 1;
+	    pl_update[packet->pnum].plu_x = plan->pl_x;
+	    pl_update[packet->pnum].plu_y = plan->pl_y;
+
+	}
+    }				/* FOR */
+}
+
+void
+sendShortReq(state)
+    char    state;
+{
+    struct shortreq_cpacket shortReq;
+
+    shortReq.type = CP_S_REQ;
+    shortReq.req = state;
+    shortReq.version = SHORTVERSION;
+    switch (state) {
+    case SPK_VON:
+	warning("Sending short packet request");
+	break;
+    case SPK_VOFF:
+	warning("Sending old packet request");
+	break;
+    default:
+	break;
+    }
+    if ((state == SPK_SALL || state == SPK_ALL) && recv_short) {
+	/* Let the client do the work, and not the network :-) */
+
+	register int i;
+	for (i = 0; i < nplayers * MAXTORP; i++)
+	    torps[i].t_status = TFREE;
+
+	for (i = 0; i < nplayers * MAXPLASMA; i++)
+	    plasmatorps[i].pt_status = PTFREE;
+
+	for (i = 0; i < nplayers; i++) {
+	    players[i].p_ntorp = 0;
+	    players[i].p_nplasmatorp = 0;
+	    phasers[i].ph_status = PHFREE;
+	}
+	if (state == SPK_SALL)
+	    warning("Sent request for small update (weapons+planets+kills)");
+	else if (state == SPK_ALL)
+	    warning("Sent request for medium update (all except stats)");
+	else
+	    warning("Sent some unknown request...");
+    }
+    sendServerPacket((struct shortreq_cpacket *) & shortReq);
+}
+
+char   *whydeadmess[] =
+{"", "[quit]", "[photon]", "[phaser]", "[planet]", "[explosion]",
+    "", "", "[ghostbust]", "[genocide]", "", "[plasma]", "[detted photon]", "[chain explosion]",
+"[TEAM]", "", "[team det]", "[team explosion]"};
+
+
+void
+handleSWarning(packet)
+    struct warning_s_spacket *packet;
+{
+    char    buf[80];
+    register struct player *target;
+    register int damage;
+    static int arg3, arg4;	/* Here are the arguments for warnings with
+				   more than 2 arguments */
+    static int karg3, karg4, karg5 = 0;
+    char    killmess[20];
+
+    switch (packet->whichmessage) {
+    case TEXTE:		/* damage used as tmp var */
+	damage = (unsigned char) packet->argument;
+	damage |= (unsigned char) packet->argument2 << 8;
+	if (damage >= 0 && damage < NUMWTEXTS)
+	    warning(w_texts[damage]);
+	break;
+    case PHASER_HIT_TEXT:
+	target = &players[(unsigned char) packet->argument & 0x3f];
+	damage = (unsigned char) packet->argument2;
+	if ((unsigned char) packet->argument & 64)
+	    damage |= 256;
+	if ((unsigned char) packet->argument & 128)
+	    damage |= 512;
+	(void) sprintf(buf, "Phaser burst hit %s for %d points", target->p_name, damage);
+	warning(buf);
+	break;
+    case BOMB_INEFFECTIVE:
+	sprintf(buf, "Weapons Officer: Bombing is ineffective.  Only %d armies are defending.",
+		(int) packet->argument);	/* nifty info feature 2/14/92
+						   TMC */
+	warning(buf);
+	break;
+    case BOMB_TEXT:
+	sprintf(buf, "Weapons Officer: Bombarding %s...  Sensors read %d armies left.",
+		planets[(unsigned char) packet->argument].pl_name,
+		(unsigned char) packet->argument2);
+	warning(buf);
+	break;
+    case BEAMUP_TEXT:
+	sprintf(buf, "%s: Too few armies to beam up",
+		planets[(unsigned char) packet->argument].pl_name);
+	warning(buf);
+	break;
+    case BEAMUP2_TEXT:
+	sprintf(buf, "Beaming up. (%d/%d)", (unsigned char) packet->argument, (unsigned char) packet->argument2);
+	warning(buf);
+	break;
+    case BEAMUPSTARBASE_TEXT:
+	sprintf(buf, "Starbase %s: Too few armies to beam up",
+		players[packet->argument].p_name);
+	warning(buf);
+	break;
+    case BEAMDOWNSTARBASE_TEXT:
+	sprintf(buf, "No more armies to beam down to Starbase %s.",
+		players[packet->argument].p_name);
+	warning(buf);
+
+	break;
+    case BEAMDOWNPLANET_TEXT:
+	sprintf(buf, "No more armies to beam down to %s.",
+		planets[(unsigned char) packet->argument].pl_name);
+	warning(buf);
+	break;
+    case SBREPORT:
+	sprintf(buf, "Transporter Room:  Starbase %s reports all troop bunkers are full!",
+		players[packet->argument].p_name);
+	warning(buf);
+	break;
+    case ONEARG_TEXT:
+	if (packet->argument >= 0 && packet->argument < NUMVARITEXTS) {
+	    sprintf(buf, vari_texts[packet->argument], (unsigned char) packet->argument2);
+	    warning(buf);
+	}
+	break;
+    case BEAM_D_PLANET_TEXT:
+	sprintf(buf, "Beaming down.  (%d/%d) %s has %d armies left",
+		arg3,
+		arg4,
+		planets[(unsigned char) packet->argument].pl_name,
+		packet->argument2);
+	warning(buf);
+	break;
+    case ARGUMENTS:
+	arg3 = (unsigned char) packet->argument;
+	arg4 = (unsigned char) packet->argument2;
+	break;
+    case BEAM_U_TEXT:
+	sprintf(buf, "Transfering ground units.  (%d/%d) Starbase %s has %d armies left",
+		(unsigned char) arg3, (unsigned char) arg4, players[packet->argument].p_name, (unsigned char) packet->argument2);
+	warning(buf);
+	break;
+    case LOCKPLANET_TEXT:
+	sprintf(buf, "Locking onto %s", planets[(unsigned char) packet->argument].pl_name);
+	warning(buf);
+	break;
+    case SBRANK_TEXT:
+	sprintf(buf, "You need a rank of %s or higher to command a starbase!", ranks[packet->argument].name);
+	warning(buf);
+	break;
+    case SBDOCKREFUSE_TEXT:
+	sprintf(buf, "Starbase %s refusing us docking permission captain.",
+		players[packet->argument].p_name);
+	warning(buf);
+	break;
+    case SBDOCKDENIED_TEXT:
+	sprintf(buf, "Starbase %s: Permission to dock denied, all ports currently occupied.", players[packet->argument].p_name);
+	warning(buf);
+	break;
+    case SBLOCKSTRANGER:
+	sprintf(buf, "Locking onto %s (%c%c)",
+		players[packet->argument].p_name,
+		TEAM_LETTER(players[packet->argument]),
+		shipnos[players[packet->argument].p_no]);
+	warning(buf);
+	break;
+    case SBLOCKMYTEAM:
+	sprintf(buf, "Locking onto %s (%c%c) (docking is %s)",
+		players[packet->argument].p_name,
+		TEAM_LETTER(players[packet->argument]),
+		shipnos[players[packet->argument].p_no],
+		(players[packet->argument].p_flags & PFDOCKOK) ? "enabled" : "disabled");
+	warning(buf);
+	break;
+    case DMKILL:
+	{
+	    struct mesg_spacket msg;
+	    int     killer, victim, armies;
+	    float   kills;
+	    victim = (unsigned char) packet->argument & 0x3f;
+	    killer = (unsigned char) packet->argument2 & 0x3f;
+	    /* that's only a temp */
+	    damage = (unsigned char) karg3;
+	    damage |= (karg4 & 127) << 8;
+	    kills = damage / 100.0;
+	    if (kills == 0.0)
+		strcpy(killmess, "NO CREDIT");
+	    else
+		sprintf(killmess, "%0.2f", kills);
+	    armies = (((unsigned char) packet->argument >> 6) | ((unsigned char) packet->argument2 & 192) >> 4);
+	    if (karg4 & 128)
+		armies |= 16;
+	    if (armies == 0) {
+		(void) sprintf(msg.mesg, "%s%s (%c%c) [%c%c] was kill %s for %s (%c%c) [%c%c]",
+			       (godToAllOnKills ? "GOD->ALL " : ""),
+			       players[victim].p_name,
+			       TEAM_LETTER(players[victim]),
+			       shipnos[victim],
+			       players[victim].p_ship->s_desig[0],
+			       players[victim].p_ship->s_desig[1],
+			       killmess,
+			       players[killer].p_name,
+			       TEAM_LETTER(players[killer]),
+			       shipnos[killer],
+			       players[killer].p_ship->s_desig[0],
+			       players[killer].p_ship->s_desig[1]);
+		msg.m_flags = MALL | MVALID | MKILL;
+	    } else {
+#ifdef SOUND			/* was feeling a little silly :-) */
+		if (killer == me->p_no || alwaysSoundDoosh)
+		    S_PlaySound(S_DOOSH);
+#endif
+		(void) sprintf(msg.mesg, "%s%s (%c%c+%d armies) [%c%c]: kill %s for %s (%c%c) [%c%c]",
+			       (godToAllOnKills ? "GOD->ALL " : ""),
+			       players[victim].p_name,
+			       TEAM_LETTER(players[victim]),
+			       shipnos[victim],
+			       armies,
+			       players[victim].p_ship->s_desig[0],
+			       players[victim].p_ship->s_desig[1],
+			       killmess,
+			       players[killer].p_name,
+			       TEAM_LETTER(players[killer]),
+			       shipnos[killer],
+			       players[killer].p_ship->s_desig[0],
+			       players[killer].p_ship->s_desig[1]);
+		msg.m_flags = MALL | MVALID | MKILLA;
+	    }
+	    if (why_dead) {
+		add_whydead(msg.mesg, karg5);
+		karg5 = 0;
+	    }
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_recpt = 0;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case KILLARGS:
+	karg3 = (unsigned char) packet->argument;
+	karg4 = (unsigned char) packet->argument2;
+	break;
+    case KILLARGS2:
+	karg5 = (unsigned char) packet->argument;
+	break;
+    case DMKILLP:
+	{
+	    struct mesg_spacket msg;
+	    (void) sprintf(msg.mesg, "%s%s (%c%c) [%c%c] killed by %s (%c)",
+			   (godToAllOnKills ? "GOD->ALL " : ""),
+			   players[packet->argument].p_name,
+			   TEAM_LETTER(players[packet->argument]),
+			   shipnos[packet->argument],
+			   players[packet->argument].p_ship->s_desig[0],
+			   players[packet->argument].p_ship->s_desig[1],
+			 planets[(unsigned char) packet->argument2].pl_name,
+		  TEAM_LETTERP(planets[(unsigned char) packet->argument2]));
+	    if (why_dead) {
+		add_whydead(msg.mesg, karg5);
+		karg5 = 0;
+	    }
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_flags = MALL | MVALID | MKILLP;
+	    msg.m_recpt = 0;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case DMBOMB:
+	{
+	    struct mesg_spacket msg;
+	    char    buf1[80];
+	    (void) sprintf(buf, "%-3s->%-3s", planets[(unsigned char) packet->argument2].pl_name, TEAM_SHORTP(planets[(unsigned char) packet->argument2]));
+	    (void) sprintf(buf1, "We are being attacked by %s %c%c who is %d%% damaged.",
+			   players[packet->argument].p_name,
+			   TEAM_LETTER(players[packet->argument]),
+			   shipnos[packet->argument],
+			   arg3);
+	    (void) sprintf(msg.mesg, "%s %s", buf, buf1);
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_flags = MTEAM | MBOMB | MVALID;
+	    msg.m_recpt = planets[(unsigned char) packet->argument2].pl_owner;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case DMDEST:
+	{
+	    struct mesg_spacket msg;
+	    char    buf1[80];
+	    (void) sprintf(buf, "%s destroyed by %s (%c%c)",
+			   planets[(unsigned char) packet->argument].pl_name,
+			   players[packet->argument2].p_name,
+			   TEAM_LETTER(players[packet->argument2]),
+			   shipnos[(unsigned char) packet->argument2]);
+	    (void) sprintf(buf1, "%-3s->%-3s",
+			   planets[(unsigned char) packet->argument].pl_name, TEAM_SHORTP(planets[(unsigned char) packet->argument]));
+	    (void) sprintf(msg.mesg, "%s %s", buf1, buf);
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_flags = MTEAM | MDEST | MVALID;
+	    msg.m_recpt = planets[(unsigned char) packet->argument].pl_owner;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case DMTAKE:
+	{
+	    struct mesg_spacket msg;
+	    char    buf1[80];
+	    (void) sprintf(buf, "%s taken over by %s (%c%c)",
+			   planets[(unsigned char) packet->argument].pl_name,
+			   players[packet->argument2].p_name,
+			   TEAM_LETTER(players[packet->argument2]),
+			   shipnos[packet->argument2]);
+	    (void) sprintf(buf1, "%-3s->%-3s",
+			   planets[(unsigned char) packet->argument].pl_name, TEAM_SHORT(players[packet->argument2]));
+	    (void) sprintf(msg.mesg, "%s %s", buf1, buf);
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_flags = MTEAM | MTAKE | MVALID;
+	    msg.m_recpt = idx_to_mask(players[packet->argument2].p_teami);
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case DGHOSTKILL:
+	{
+	    struct mesg_spacket msg;
+	    ushort  damage;
+	    damage = (unsigned char) karg3;
+	    damage |= (unsigned char) (karg4 & 0xff) << 8;
+	    (void) sprintf(msg.mesg, "GOD->ALL %s (%c%c) was kill %0.2f for the GhostBusters",
+			   players[(unsigned char) packet->argument].p_name, TEAM_LETTER(players[(unsigned char) packet->argument]),
+			   shipnos[(unsigned char) packet->argument],
+			   (float) damage / 100.0);
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_flags = MALL | MVALID;
+	    msg.m_recpt = 0;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+/* INL Daemon Mesages */
+    case INLDMKILLP:
+	{
+	    struct mesg_spacket msg;
+	    *buf = 0;
+	    if (arg3) {		/* Armies */
+		sprintf(buf, "+%d", arg3);
+#ifdef SOUND
+		if(alwaysSoundDoosh)
+		    S_PlaySound(S_DOOSH);
+#endif
+	    }
+	    (void) sprintf(msg.mesg, "%s%s[%s] (%c%c%s) killed by %s (%c)",
+			   (godToAllOnKills ? "GOD->ALL " : ""),
+			   players[(unsigned char) packet->argument].p_name,
+			   ship_type(players[(unsigned char) packet->argument].p_ship),
+			   TEAM_LETTER(players[(unsigned char) packet->argument]),
+			   shipnos[(unsigned char) packet->argument],
+			   buf,
+			 planets[(unsigned char) packet->argument2].pl_name,
+		  TEAM_LETTERP(planets[(unsigned char) packet->argument2]));
+	    if (why_dead) {
+		add_whydead(msg.mesg, karg5);
+		karg5 = 0;
+	    }
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_flags = MALL | MVALID | MKILLP;
+	    msg.m_recpt = 0;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case INLDMKILL:
+	{
+	    struct mesg_spacket msg;
+	    int     killer, victim, armies;
+	    float   kills;
+	    victim = (unsigned char) packet->argument & 0x3f;
+	    killer = (unsigned char) packet->argument2 & 0x3f;
+	    /* that's only a temp */
+	    damage = (unsigned char) karg3;
+	    damage |= (karg4 & 127) << 8;
+	    kills = damage / 100.0;
+	    armies = (((unsigned char) packet->argument >> 6) | ((unsigned char) packet->argument2 & 192) >> 4);
+	    if (karg4 & 128)
+		armies |= 16;
+	    if (armies == 0) {
+		(void) sprintf(msg.mesg, "%s%s[%s] (%c%c) was kill %0.2f for %s[%s] (%c%c)",
+			       (godToAllOnKills ? "GOD->ALL " : ""),
+			       players[victim].p_name,
+			       ship_type(players[victim].p_ship),
+			       TEAM_LETTER(players[victim]),
+			       shipnos[victim],
+			       kills,
+			       players[killer].p_name,
+			       ship_type(players[killer].p_ship),
+			       TEAM_LETTER(players[killer]),
+			       shipnos[killer]);
+		msg.m_flags = MALL | MVALID | MKILL;
+	    } else {
+#ifdef SOUND
+		if(killer == me->p_no || alwaysSoundDoosh)
+		    S_PlaySound(S_DOOSH);
+#endif
+		(void) sprintf(msg.mesg, "%s%s[%s] (%c%c+%d armies) was kill %0.2f for %s[%s] (%c%c)",
+			       (godToAllOnKills ? "GOD->ALL " : ""),
+			       players[victim].p_name,
+			       ship_type(players[victim].p_ship),
+			       TEAM_LETTER(players[victim]),
+			       shipnos[victim],
+			       armies,
+			       kills,
+			       players[killer].p_name,
+			       ship_type(players[killer].p_ship),
+			       TEAM_LETTER(players[killer]),
+			       shipnos[killer]);
+		msg.m_flags = MALL | MVALID | MKILLA;
+	    }
+	    if (why_dead) {
+		add_whydead(msg.mesg, karg5);
+		karg5 = 0;
+	    }
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_recpt = 0;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case INLDRESUME:
+	{
+	    struct mesg_spacket msg;
+	    sprintf(msg.mesg, " Game will resume in %d seconds", (unsigned char) packet->argument);
+	    msg.m_flags = MALL | MVALID;
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_recpt = 0;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case INLDTEXTE:
+	if (packet->argument >= 0 && (unsigned char) packet->argument < NUMDAEMONTEXTS) {
+	    struct mesg_spacket msg;
+	    strcpy(msg.mesg, daemon_texts[(unsigned char) packet->argument]);
+	    msg.m_flags = MALL | MVALID;
+	    msg.type = SP_MESSAGE;
+	    msg.mesg[79] = '\0';
+	    msg.m_recpt = 0;
+	    msg.m_from = 255;
+	    handleMessage(&msg);
+	}
+	break;
+    case STEXTE:
+	warning(s_texte[(unsigned char) packet->argument]);
+	break;
+    case SHORT_WARNING:
+	{
+	    struct warning_spacket *warn = (struct warning_spacket *) packet;
+	    warning(warn->mesg);
+	}
+	break;
+    case STEXTE_STRING:
+	{
+	    struct warning_spacket *warn = (struct warning_spacket *) packet;
+	    warning(warn->mesg);
+	    s_texte[(unsigned char) warn->pad2] = (char *) malloc(warn->pad3 - 4);
+	    if (s_texte[(unsigned char) warn->pad2] == NULL) {
+		s_texte[(unsigned char) warn->pad2] = no_memory;
+		warning("Could not add warning! (No memory!)");
+	    } else
+		strcpy(s_texte[(unsigned char) warn->pad2], warn->mesg);
+	}
+	break;
+    default:
+	warning("Unknown Short Warning!");
+	break;
+    }
+}
+
+#define MY_SIZEOF(a) (sizeof(a) / sizeof(*(a)))
+
+void
+add_whydead(s, m)		/* 7/22/93 LAB */
+    char   *s;
+    int     m;
+{
+    char    b[256];
+
+    if (m < MY_SIZEOF(whydeadmess)) {
+	sprintf(b, "%-50s %s", s, whydeadmess[m]);
+	b[79] = '\0';
+	strcpy(s, b);
+    }
+}
+
+#endif
+
+/* END SHORT_PACKETS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sintab.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,114 @@
+/* $Id: sintab.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * sintab.c
+ *
+ * Also initialize blk_giwdth to 100000 and blk_windgwidth
+ * to WINSIDE/blk_gwidth
+ */
+#include "copyright.h"
+
+double *Cos;
+double  Sin[] = {
+    -1.0000, -0.9997, -0.9988, -0.9973, -0.9952, -0.9925,
+    -0.9892, -0.9853, -0.9808, -0.9757, -0.9701, -0.9638,
+    -0.9570, -0.9496, -0.9416, -0.9330, -0.9239, -0.9143,
+    -0.9040, -0.8933, -0.8820, -0.8701, -0.8578, -0.8449,
+    -0.8315, -0.8176, -0.8033, -0.7884, -0.7731, -0.7573,
+    -0.7410, -0.7243, -0.7072, -0.6896, -0.6716, -0.6533,
+    -0.6345, -0.6153, -0.5958, -0.5759, -0.5557, -0.5351,
+    -0.5142, -0.4930, -0.4715, -0.4497, -0.4277, -0.4054,
+    -0.3828, -0.3600, -0.3370, -0.3138, -0.2904, -0.2668,
+    -0.2431, -0.2192, -0.1952, -0.1711, -0.1469, -0.1225,
+    -0.0982, -0.0737, -0.0492, -0.0247, /* Cos */ -0.0001, 0.0244,	/* 90 */
+    0.0489, 0.0734, 0.0979, 0.1223, 0.1466, 0.1708,
+    0.1949, 0.2190, 0.2428, 0.2666, 0.2901, 0.3135,
+    0.3367, 0.3598, 0.3825, 0.4051, 0.4274, 0.4495,
+    0.4713, 0.4928, 0.5140, 0.5349, 0.5554, 0.5757,
+    0.5956, 0.6151, 0.6343, 0.6531, 0.6714, 0.6894,
+    0.7070, 0.7241, 0.7408, 0.7571, 0.7729, 0.7882,
+    0.8031, 0.8175, 0.8314, 0.8448, 0.8576, 0.8700,
+    0.8818, 0.8931, 0.9039, 0.9141, 0.9238, 0.9329,
+    0.9415, 0.9495, 0.9569, 0.9637, 0.9700, 0.9757,
+    0.9808, 0.9852, 0.9891, 0.9925, 0.9952, 0.9973,
+    0.9988, 0.9997, 1.0000, 0.9997, 0.9988, 0.9973,	/* 180 */
+    0.9952, 0.9925, 0.9892, 0.9853, 0.9808, 0.9757,
+    0.9700, 0.9638, 0.9569, 0.9495, 0.9415, 0.9330,
+    0.9239, 0.9142, 0.9040, 0.8932, 0.8819, 0.8701,
+    0.8577, 0.8449, 0.8315, 0.8176, 0.8032, 0.7884,
+    0.7730, 0.7572, 0.7410, 0.7243, 0.7071, 0.6896,
+    0.6716, 0.6532, 0.6344, 0.6153, 0.5957, 0.5758,
+    0.5556, 0.5350, 0.5141, 0.4929, 0.4714, 0.4496,
+    0.4276, 0.4053, 0.3827, 0.3599, 0.3369, 0.3137,
+    0.2903, 0.2667, 0.2430, 0.2191, 0.1951, 0.1710,
+    0.1468, 0.1225, 0.0981, 0.0736, 0.0491, 0.0246,
+    0.0000, -0.0245, -0.0490, -0.0735, -0.0980, -0.1224,	/* 270 */
+    -0.1467, -0.1709, -0.1950, -0.2190, -0.2429, -0.2667,
+    -0.2902, -0.3136, -0.3368, -0.3598, -0.3826, -0.4052,
+    -0.4275, -0.4496, -0.4713, -0.4928, -0.5140, -0.5349,
+    -0.5555, -0.5758, -0.5956, -0.6152, -0.6343, -0.6531,
+    -0.6715, -0.6895, -0.7071, -0.7242, -0.7409, -0.7572,
+    -0.7730, -0.7883, -0.8032, -0.8175, -0.8314, -0.8448,
+    -0.8577, -0.8700, -0.8819, -0.8932, -0.9040, -0.9142,
+    -0.9238, -0.9330, -0.9415, -0.9495, -0.9569, -0.9638,
+    -0.9700, -0.9757, -0.9808, -0.9853, -0.9892, -0.9925,
+    -0.9952, -0.9973, -0.9988, -0.9997,	/* }; */
+/*
+double Cos[] = {
+    0.0000, 0.0245, 0.0491, 0.0736, 0.0980, 0.1224,
+    0.1467, 0.1710, 0.1951, 0.2191, 0.2430, 0.2667,
+    0.2903, 0.3137, 0.3369, 0.3599, 0.3827, 0.4052,
+    0.4275, 0.4496, 0.4714, 0.4929, 0.5141, 0.5350,
+    0.5556, 0.5758, 0.5957, 0.6152, 0.6344, 0.6532,
+    0.6715, 0.6895, 0.7071, 0.7242, 0.7409, 0.7572,
+    0.7730, 0.7883, 0.8032, 0.8176, 0.8315, 0.8448,
+    0.8577, 0.8701, 0.8819, 0.8932, 0.9040, 0.9142,
+    0.9239, 0.9330, 0.9415, 0.9495, 0.9569, 0.9638,
+    0.9700, 0.9757, 0.9808, 0.9853, 0.9892, 0.9925,
+    0.9952, 0.9973, 0.9988, 0.9997, 1.0000, 0.9997,
+    0.9988, 0.9973, 0.9952, 0.9925, 0.9892, 0.9853,
+    0.9808, 0.9757, 0.9700, 0.9638, 0.9570, 0.9495,
+    0.9416, 0.9330, 0.9239, 0.9142, 0.9040, 0.8933,
+    0.8819, 0.8701, 0.8578, 0.8449, 0.8315, 0.8176,
+    0.8032, 0.7884, 0.7731, 0.7573, 0.7410, 0.7243,
+    0.7072, 0.6896, 0.6716, 0.6532, 0.6344, 0.6153,
+    0.5958, 0.5759, 0.5556, 0.5351, 0.5142, 0.4930,
+    0.4715, 0.4497, 0.4276, 0.4053, 0.3828, 0.3600,
+    0.3370, 0.3138, 0.2904, 0.2668, 0.2431, 0.2192,
+    0.1952, 0.1710, 0.1468, 0.1225, 0.0981, 0.0737,
+    0.0492, 0.0246, 0.0001, -0.0244, -0.0490, -0.0735,
+    -0.0979, -0.1223, -0.1466, -0.1709, -0.1950, -0.2190,
+    -0.2429, -0.2666, -0.2902, -0.3136, -0.3368, -0.3598,
+    -0.3826, -0.4051, -0.4275, -0.4495, -0.4713, -0.4928,
+    -0.5140, -0.5349, -0.5555, -0.5757, -0.5956, -0.6151,
+    -0.6343, -0.6531, -0.6715, -0.6895, -0.7070, -0.7242,
+    -0.7409, -0.7571, -0.7729, -0.7883, -0.8031, -0.8175,
+    -0.8314, -0.8448, -0.8577, -0.8700, -0.8819, -0.8932,
+    -0.9039, -0.9142, -0.9238, -0.9329, -0.9415, -0.9495,
+    -0.9569, -0.9637, -0.9700, -0.9757, -0.9808, -0.9853,
+    -0.9892, -0.9925, -0.9952, -0.9973, -0.9988, -0.9997,
+*/
+
+    -1.0000, -0.9997, -0.9988, -0.9973, -0.9952, -0.9925,
+    -0.9892, -0.9853, -0.9808, -0.9757, -0.9701, -0.9638,
+    -0.9570, -0.9496, -0.9416, -0.9330, -0.9239, -0.9143,
+    -0.9041, -0.8933, -0.8820, -0.8702, -0.8578, -0.8449,
+    -0.8316, -0.8177, -0.8033, -0.7884, -0.7731, -0.7573,
+    -0.7411, -0.7244, -0.7072, -0.6897, -0.6717, -0.6533,
+    -0.6345, -0.6154, -0.5958, -0.5759, -0.5557, -0.5351,
+    -0.5142, -0.4930, -0.4715, -0.4498, -0.4277, -0.4054,
+    -0.3828, -0.3601, -0.3371, -0.3138, -0.2905, -0.2669,
+    -0.2432, -0.2193, -0.1953, -0.1711, -0.1469, -0.1226,
+-0.0982, -0.0737, -0.0493, -0.0247};
+
+#define WINSIDE 500
+extern int blk_gwidth;
+extern float blk_windgwidth;
+
+void
+inittrigtables()
+{
+    Cos = Sin + 64;
+    blk_gwidth = 100000;
+    blk_windgwidth = ((float) WINSIDE) / blk_gwidth;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smessage.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,728 @@
+/* $Id: smessage.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * smessage.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include <string.h>
+#include <ctype.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "gameconf.h"
+
+#define ADDRLEN 10
+#define M_XOFF	5
+#ifndef AMIGA
+#define M_YOFF	5
+#else
+#define M_YOFF 1
+#endif
+
+#define MSGLEN	80
+
+/* XFIX */
+#define BLANKCHAR(col, n) W_ClearArea(messagew, M_XOFF+W_Textwidth*(col), \
+	M_YOFF, W_Textwidth * (n), W_Textheight);
+#define DRAWCURSOR(col) W_WriteText(messagew, M_XOFF+W_Textwidth*(col), \
+	M_YOFF, textColor, &cursor, 1, W_RegularFont);
+
+static int lcount;
+static char buf[MSGLEN];
+static char cursor = '_';
+
+char    addr, *addr_str;
+
+/* Prototypes */
+static void smessage_first P((int ichar));
+ /*static*/ char *getaddr P((int who));
+ /*static*/ char *getaddr2 P((int flags, int recip));
+
+void
+message_expose()
+{
+    if (!messpend)
+	return;
+
+    W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str,
+		strlen(addr_str), W_RegularFont);
+    W_WriteText(messagew, M_XOFF + ADDRLEN * W_Textwidth, M_YOFF, textColor,
+		buf, lcount - ADDRLEN, W_RegularFont);
+    DRAWCURSOR(lcount);
+}
+
+void
+smessage_ahead(head, ichar)
+    char    head;
+    char    ichar;
+{
+    if (messpend == 0) {
+	smessage_first(head);
+    }
+    smessage(ichar);
+}
+
+static void
+smessage_first(ichar)
+    char    ichar;
+{
+    messpend = 1;
+
+    /* clear out message window in case messages went there */
+    W_ClearWindow(messagew);
+    if (mdisplayed) {
+	BLANKCHAR(0, lastcount);
+	mdisplayed = 0;
+    }
+    /* Put the proper recipient in the window */
+    if (/*(ichar == 't') || */
+    /* that's a player number! */
+    /* YUCK! */
+	(ichar == 'T'))
+	addr = teaminfo[me->p_teami].letter;
+    else
+	addr = ichar;
+    addr_str = getaddr(addr);
+    if (addr_str == 0) {
+	/* print error message */
+	messpend = 0;
+#ifdef NOWARP
+	message_off();
+#else
+	W_WarpPointer(NULL);
+#endif
+    } else {
+	W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str,
+		    strlen(addr_str), W_RegularFont);
+	lcount = ADDRLEN;
+	DRAWCURSOR(ADDRLEN);
+    }
+}
+
+void
+smessage(ichar)
+    int     ichar;
+{
+    register int i;
+    char    twochar[2], *delim;
+
+    if (messpend == 0) {
+	if(lowercaset && ichar == 't')
+	    ichar='T';
+	else if(lowercaset && (ichar == 'T'))
+	    ichar='t';
+	smessage_first(ichar);
+	return;
+    }
+    switch (ichar) {
+    case '\b':			/* character erase */
+    case '\177':
+	if (--lcount < ADDRLEN) {
+	    lcount = ADDRLEN;
+	    break;
+	}
+	BLANKCHAR(lcount + 1, 1);
+	DRAWCURSOR(lcount);
+	break;
+
+    case 'w'+256:		/* word erase */
+	i = 0;
+	/* back up over blanks */
+	while (--lcount >= ADDRLEN &&
+	       isspace((unsigned char) buf[lcount - ADDRLEN] & ~(0x80)))
+	    i++;
+	lcount++;
+	/* back up over non-blanks */
+	while (--lcount >= ADDRLEN &&
+	       !isspace((unsigned char) buf[lcount - ADDRLEN] & ~(0x80)))
+	    i++;
+	lcount++;
+
+	if (i > 0) {
+	    BLANKCHAR(lcount, i + 1);
+	    DRAWCURSOR(lcount);
+	}
+	break;
+
+    case 'u'+256:		/* kill line */
+    case 'x'+256:
+	if (lcount > ADDRLEN) {
+	    BLANKCHAR(ADDRLEN, lcount - ADDRLEN + 1);
+	    lcount = ADDRLEN;
+	    DRAWCURSOR(ADDRLEN);
+	}
+	break;
+
+    case '\033':		/* abort message */
+	BLANKCHAR(0, lcount + 1);
+	mdisplayed = 0;
+	messpend = 0;
+#ifdef NOWARP
+	message_off();
+#else
+	W_WarpPointer(NULL);
+#endif
+	break;
+
+    case '\r':			/* send message */
+	buf[lcount - ADDRLEN] = '\0';
+	messpend = 0;
+	sendCharMessage(buf, addr);
+	BLANKCHAR(0, lcount + 1);
+	mdisplayed = 0;
+	lcount = 0;
+	break;
+
+    default:			/* add character */
+	if (lcount >= 79) {	/* send mesg and continue mesg */
+	     if (addr == 'M')
+		  if ((delim = strchr(buf, '>') + 1) == NULL) {
+		       W_Beep();
+		       break;
+		  }
+		  else {
+		       i = delim - buf;
+		       buf[lcount - ADDRLEN + 1] = '\0';
+		       sendCharMessage(buf, addr);
+		       memset(delim, '\0', sizeof(buf) - i);
+		       BLANKCHAR(i, lcount + 1);
+		       W_WriteText(messagew, M_XOFF, M_YOFF, textColor,
+				   addr_str, strlen(addr_str), W_RegularFont);
+		       W_WriteText(messagew, M_XOFF+(strlen(addr_str) +
+						     1) * W_Textwidth,
+				   M_YOFF, textColor, buf, strlen(buf), W_RegularFont);
+		       lcount = i + ADDRLEN;
+		       DRAWCURSOR(i + ADDRLEN);
+		  }
+	     else {
+		  buf[lcount - ADDRLEN + 1] = '\0';
+		  sendCharMessage(buf, addr);
+		  BLANKCHAR(0, lcount + 1);
+		  W_WriteText(messagew, M_XOFF, M_YOFF, textColor, addr_str,
+			      strlen(addr_str), W_RegularFont);
+		  lcount = ADDRLEN;
+		  DRAWCURSOR(ADDRLEN);
+	     }
+	}
+	if (ichar > 255)
+	    break;
+	twochar[0] = ichar;
+	twochar[1] = cursor;
+	W_WriteText(messagew, M_XOFF + W_Textwidth * lcount, M_YOFF,
+		    textColor, twochar, 2, W_RegularFont);
+	buf[(lcount++) - ADDRLEN] = ichar;
+	break;
+    }
+}
+
+void
+sendCharMessage(buf, ch)
+    char   *buf;
+    int     ch;
+{
+     char tmp[MSGLEN], *delim;
+     int i, count;
+
+/* uses ch to find out what kind of message it is and then sends
+   it there */
+    switch ((char) ch) {
+    case 'A':
+	pmessage(buf, 0, MALL);
+	break;
+    case 'F':
+	pmessage(buf, FEDm, MTEAM);
+	break;
+    case 'R':
+	pmessage(buf, ROMm, MTEAM);
+	break;
+    case 'K':
+	pmessage(buf, KLIm, MTEAM);
+	break;
+    case 'O':
+	pmessage(buf, ORIm, MTEAM);
+	break;
+    case 'G':
+	pmessage(buf, 0, MGOD);
+	break;
+#ifdef TOOLS
+        case '!':
+          pmessage(buf, 0, MTOOLS);
+          break;
+#endif
+    case 'T':
+	pmessage(buf, idx_to_mask(me->p_teami), MTEAM);
+	break;
+   case 'M':
+	/* mcast format: hit M and list of target addresses followed */
+	/* by greater than(>) and message. the entire mesg including */
+	/* addresses will be sent to each address */
+	if((delim = strchr(buf, '>')) != NULL) {
+	     count = delim - buf; /* number of addresses */
+	     strncpy(tmp, buf, count);
+	     if(strchr(tmp, ' ') == NULL)
+		  for(i=0; i < count; i++) { /* dont do tmp[0] is M */
+		       sendCharMessage(buf, tmp[i]);
+		  }
+	}
+	break;
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+	pmessage(buf, ch - '0', MINDIV);
+	break;
+    case 'a':
+    case 'b':
+    case 'c':
+    case 'd':
+    case 'e':
+    case 'f':
+    case 'g':
+    case 'h':
+    case 'i':
+    case 'j':
+    case 'k':
+    case 'l':
+    case 'm':
+    case 'n':
+    case 'o':
+    case 'p':
+    case 'q':
+    case 'r':
+    case 's':
+    case 't':
+    case 'u':
+    case 'v':
+    case 'w':
+    case 'x':
+    case 'y':
+    case 'z':
+	pmessage(buf, ch - 'a' + 10, MINDIV);
+	break;
+    default:
+	{
+	    int     i;
+	    for (i = 0; i < number_of_teams; i++) {
+		if (ch == teaminfo[i].letter)
+		    break;
+	    }
+	    if (i < number_of_teams) {
+		pmessage(buf, idx_to_mask(i), MTEAM);
+		break;
+	    }
+	}
+	warning("Not legal recipient");
+    }
+}
+
+void
+pmessage(str, recip, group)
+    char   *str;
+    int     recip;
+    int     group;
+{
+    char    newbuf[100];
+
+    strcpy(lastMessage, str);
+    switch(group) {
+#ifdef TOOLS
+    case MTOOLS:
+	sendTools(str);
+	break;
+#endif
+    default:
+	sendMessage(str, group, recip);
+    }
+    if ((group == MTEAM && recip != idx_to_mask(me->p_teami)) ||
+	(group == MINDIV && recip != me->p_no)) {
+	sprintf(newbuf, "%s  %s",
+		getaddr2(group, (group == MTEAM) ?
+			 mask_to_idx(recip) : recip),
+		str);
+	newbuf[79] = 0;
+	dmessage(newbuf, group, me->p_no, recip);
+    }
+#ifdef NOWARP
+    message_off();
+#else
+    W_WarpPointer(NULL);
+#endif
+}
+
+/*static */
+char   *
+getaddr(who)
+    char    who;
+{
+    switch (who) {
+    case 'A':
+	return (getaddr2(MALL, 0));
+    case 'F':
+	return (getaddr2(MTEAM, FEDi));
+    case 'R':
+	return (getaddr2(MTEAM, ROMi));
+    case 'K':
+	return (getaddr2(MTEAM, KLIi));
+    case 'O':
+	return (getaddr2(MTEAM, ORIi));
+    case 'G':
+	return (getaddr2(MGOD, 0));
+#ifdef TOOLS
+    case '!':
+      return (getaddr2(MTOOLS, 0));
+#endif
+   case 'M':
+	return (getaddr2(MCAST, 0));;
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+	if (isPlaying(&players[who - '0'])) {
+	    return (getaddr2(MINDIV, who - '0'));
+	} else {
+	    warning("Player is not in game");
+	    return (0);
+	}
+	break;
+    case 'a':
+    case 'b':
+    case 'c':
+    case 'd':
+    case 'e':
+    case 'f':
+    case 'g':
+    case 'h':
+    case 'i':
+    case 'j':
+    case 'k':
+    case 'l':
+    case 'm':
+    case 'n':
+    case 'o':
+    case 'p':
+    case 'q':
+    case 'r':
+    case 's':
+    case 't':
+    case 'u':
+    case 'v':
+    case 'w':
+    case 'x':
+    case 'y':
+    case 'z':
+	if (who - 'a' + 10 > nplayers) {
+	    warning("Invalid player number");
+	    return (0);
+	} else if (isPlaying(&players[who - 'a' + 10])) {
+	    return (getaddr2(MINDIV, who - 'a' + 10));
+	} else {
+	    warning("Player is not in game");
+	    return (0);
+	}
+	break;
+    default:
+	{
+	    int     i;
+	    for (i = 0; i < number_of_teams; i++) {
+		if (addr == teaminfo[i].letter)
+		    break;
+	    }
+	    if (i < number_of_teams) {
+		return getaddr2(MTEAM, i);
+	    }
+	}
+	warning("Not legal recipient");
+	return (0);
+    }
+}
+
+/*static*/
+char   *
+getaddr2(flags, recip)
+    int     flags;
+    int     recip;
+{
+    static char addrmesg[ADDRLEN];
+
+    (void) sprintf(addrmesg, " %c%c->", teaminfo[me->p_teami].letter, shipnos[me->p_no]);
+    switch (flags) {
+    case MALL:
+	(void) sprintf(&addrmesg[5], "ALL");
+	break;
+    case MTEAM:
+	(void) sprintf(&addrmesg[5], teaminfo[recip].shortname);
+	break;
+    case MINDIV:
+	(void) sprintf(&addrmesg[5], "%c%c ",
+		   teaminfo[players[recip].p_teami].letter, shipnos[recip]);
+	break;
+    case MGOD:
+	(void) sprintf(&addrmesg[5], "GOD");
+	break;
+#ifdef TOOLS
+    case MTOOLS:
+	(void) sprintf(addrmesg, "  Shell>");
+	break;
+#endif
+   case MCAST:
+	(void) sprintf(&addrmesg[5], "MCAS");
+    }
+
+    return (addrmesg);
+}
+
+/* Used in NEWMACRO, useful elsewhere also */
+int
+getgroup(addr, recip)
+    char    addr;
+    int    *recip;
+{
+    *recip = 0;
+
+    switch (addr) {
+    case 'A':
+	*recip = 0;
+	return (MALL);
+	break;
+    case 'T':			/* had to add this...why didn't COW-lite need
+				   it?? -JR */
+	*recip = idx_to_mask(me->p_teami);
+	return (MTEAM);
+	break;
+    case 'F':
+	*recip = FEDm;
+	return (MTEAM);
+	break;
+    case 'R':
+	*recip = ROMm;
+	return (MTEAM);
+	break;
+    case 'K':
+	*recip = KLIm;
+	return (MTEAM);
+	break;
+    case 'O':
+	*recip = ORIm;
+	return (MTEAM);
+	break;
+    case 'G':
+	*recip = 0;
+	return (MGOD);
+	break;
+#ifdef TOOLS
+    case '!':
+	*recip = 0;
+	return (MTOOLS);
+	break;
+#endif
+    case 'M':
+	*recip = 0;
+	return (MMOO);
+	break;
+    case '0':
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+	if (players[addr - '0'].p_status == PFREE) {
+	    warning("That player left the game. message not sent.");
+	    return 0;
+	}
+	*recip = addr - '0';
+	return (MINDIV);
+	break;
+    case 'a':
+    case 'b':
+    case 'c':
+    case 'd':
+    case 'e':
+    case 'f':
+    case 'g':
+    case 'h':
+    case 'i':
+    case 'j':
+    case 'k':
+    case 'l':
+    case 'm':
+    case 'n':
+    case 'o':
+    case 'p':
+    case 'q':
+    case 'r':
+    case 's':
+    case 't':
+    case 'u':
+    case 'v':
+    case 'w':
+    case 'x':
+    case 'y':
+    case 'z':
+	if (players[addr - 'a' + 10].p_status == PFREE) {
+	    warning("That player left the game. message not sent.");
+	    return 0;
+	}
+	*recip = addr - 'a' + 10;
+	return (MINDIV);
+	break;
+    default:
+	warning("Not legal recipient");
+    }
+    return 0;
+}
+
+
+
+
+
+/*-------------------------------EMERGENCY--------------------------------*/
+/*  This function sends a distress message out to the player's team.  */
+void
+emergency()
+{
+    char    ebuf[120];		/* to sprintf into */
+    char    buf2[20];
+
+    sprintf(ebuf, "Distress  %c%c",	/* get team and end */
+	    teaminfo[me->p_teami].letter, shipnos[me->p_no]);
+    switch (myship->s_type) {
+    case STARBASE:
+	strcat(ebuf, " (Starbase): ");
+	break;
+    case WARBASE:
+	strcat(ebuf, " (Warbase): ");
+	break;
+    case JUMPSHIP:
+	strcat(ebuf, " (Jumpship): ");
+	break;
+    default:
+	strcat(ebuf, ": ");
+    }
+    if (me->p_damage != 0) {
+	if (me->p_damage > me->p_ship->s_maxdamage - 30)
+	    sprintf(buf2, "DEAD MAN  ");
+	else
+	    sprintf(buf2, "damg: %d%%  ", (100 * me->p_damage) / me->p_ship->s_maxdamage);
+	strcat(ebuf, buf2);
+    }
+    if (me->p_shield < me->p_ship->s_maxshield) {
+	if (me->p_shield < 5)
+	    sprintf(buf2, "NO SHIELDS  ");
+	else
+	    sprintf(buf2, "shld: %d%%  ", (100 * me->p_shield) / me->p_ship->s_maxshield);
+	strcat(ebuf, buf2);
+    }
+    if (me->p_wtemp > 0) {
+	if (me->p_flags & PFWEP)
+	    sprintf(buf2, "WTEMP  ");
+	else
+	    sprintf(buf2, "W %d%%  ", (100 * me->p_wtemp) / me->p_ship->s_maxwpntemp);
+	strcat(ebuf, buf2);
+    }
+    if (me->p_etemp > 0) {
+	if (me->p_flags & PFENG)
+	    sprintf(buf2, "ETEMP  ");
+	else
+	    sprintf(buf2, "E %d%%  ", (100 * me->p_etemp) / me->p_ship->s_maxegntemp);
+	strcat(ebuf, buf2);
+    }
+    if (me->p_fuel < me->p_ship->s_maxfuel) {
+	if (me->p_fuel < 400)
+	    sprintf(buf2, "NO FUEL  ");
+	else
+	    sprintf(buf2, "F %d%%  ", (100 * me->p_fuel) / me->p_ship->s_maxfuel);
+	strcat(ebuf, buf2);
+    }
+    if ((int) strlen(ebuf) < 12)
+	strcat(ebuf, "  perfect health  ");
+    if (me->p_armies > 0) {
+	sprintf(buf2, "%d ARMIES!", me->p_armies);
+	strcat(ebuf, buf2);
+    }
+    pmessage(ebuf, idx_to_mask(me->p_teami), MTEAM);
+}
+
+
+
+void
+carry_report()
+{
+    char    ebuf[MSGLEN], *pntr;
+    double  dist, closedist;
+    struct planet *k, *p = NULL;
+
+    closedist = blk_gwidth;
+
+    for (k = &planets[0]; k < &planets[nplanets]; k++) {
+	dist = hypot((double) (me->p_x - k->pl_x),
+		     (double) (me->p_y - k->pl_y));
+	if (dist < closedist) {
+	    p = k;
+	    closedist = dist;
+	}
+    }
+    if (myship->s_type == STARBASE)
+        sprintf(ebuf, "Your Starbase is carrying %d armies.  ", me->p_armies);
+    else
+        sprintf(ebuf, "I am carrying %d armies.  ", me->p_armies);
+    for (pntr = ebuf; *pntr; pntr++);
+    if (paradise) {
+	sprintf(pntr, "Sector: %d-%d  ", (me->p_x / GRIDSIZE) + 1,
+		(me->p_y / GRIDSIZE) + 1);
+	for (; *pntr; pntr++);
+    }
+    sprintf(pntr, "%sear %s", (me->p_flags & PFCLOAK) ? "Cloaked n" : "N",
+	    p->pl_name);
+    pmessage(ebuf, idx_to_mask(me->p_teami), MTEAM);
+}
+
+#ifdef NOWARP
+void
+message_on()
+{
+    if (warp) {
+	W_WarpPointer(messagew);
+    }
+#ifdef TCURSORS
+    else {
+	messageon = 1;
+	W_DefineTextCursor(w);
+	W_DefineTextCursor(mapw);
+    }
+#endif				/* TCURSORS */
+}
+
+void
+message_off()
+{
+#ifdef TCURSORS
+    if (!warp) {
+	messageon = 0;
+	W_RevertCursor(w);
+	W_RevertCursor(mapw);
+    }
+#endif				/* TCURSORS */
+}
+#endif				/* NOWARP */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/socket.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,3380 @@
+/* $Id: socket.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * Socket.c
+ *
+ * Kevin P. Smith 1/29/89
+ * UDP stuff v1.0 by Andy McFadden  Feb-Apr 1992
+ *
+ * UDP protocol v1.0
+ *
+ * Routines to allow connection to the xtrek server.
+ */
+#include "copyright2.h"
+
+/* to see the packets sent/received: [BDyess] */
+#if 0
+#define SHOW_SEND
+#define SHOW_RECEIVED
+#endif				/* 0 */
+
+#ifndef GATEWAY
+#define USE_PORTSWAP		/* instead of using recvfrom() */
+#endif
+
+#undef USE_PORTSWAP		/* recvfrom is a better scheme */
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#ifdef RS6K
+#include <sys/select.h>
+#endif
+#ifndef DNET
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <netdb.h>
+#else
+#include <devices/timer.h>
+#include <dos/dos.h>
+#endif				/* DNET */
+#include <math.h>
+#include <errno.h>
+#include <zlib.h>		/* for terrain info */
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+#include "gameconf.h"
+#ifdef SOUND
+#include "Slib.h"
+#endif				/* SOUND */
+#include "sound.h"
+
+#define INCLUDE_SCAN		/* include Amdahl scanning beams */
+#define INCLUDE_VISTRACT	/* include visible tractor beams */
+
+#ifdef GATEWAY
+/*
+ * (these values are now defined in "main.c":)
+ * char *gw_mach        = "charon";     |client gateway; strcmp(serverName)
+ * int   gw_serv_port   = 5000;         |what to tell the server to use
+ * int   gw_port        = 5001;         |where we will contact gw
+ * int   gw_local_port  = 5100;         |where we expect gw to contact us
+ *
+ * The client binds to "5100" and sends "5000" to the server (TCP).  The
+ * server sees that and sends a UDP packet to gw on port udp5000, which passes
+ * it through to port udp5100 on the client.  The client-gw gets the server's
+ * host and port from recvfrom.  (The client can't use the same method since
+ * these sockets are one-way only, so it connect()s to gw_port (udp5001)
+ * on the gateway machine regardless of what the server sends.)
+ *
+ * So all we need in .gwrc is:
+ *      udp 5000 5001 tde.uts 5100
+ *
+ * assuming the client is on tde.uts.  Note that a UDP declaration will
+ * work for ANY server, but you need one per player, and the client has to
+ * have the port numbers in advance.
+ *
+ * If we're using a standard server, we're set.  If we're running through a
+ * gatewayed server, we have to do some unpleasant work on the server side...
+ */
+#endif
+
+#ifdef SIZE_LOGGING
+int     send_total = 0;
+int     receive_total = 0;
+#endif				/* SIZE_LOGGING */
+
+/* Prototypes */
+static void resetForce P((void));
+static void checkForce P((void));
+#ifdef nodef
+static void set_tcp_opts P((int s));
+static void set_udp_opts P((int s));
+#endif				/* nodef */
+static int doRead P((int asock));
+static void handleTorp P((struct torp_spacket * packet));
+static void handleTorpInfo P((struct torp_info_spacket * packet));
+static void handleStatus P((struct status_spacket * packet));
+static void handleSelf P((struct you_spacket * packet));
+static void handlePlayer P((struct player_spacket * packet));
+static void handleWarning P((struct warning_spacket * packet));
+void sendServerPacket P((struct player_spacket * packet));
+static void handlePlanet P((struct planet_spacket * packet));
+static void handlePhaser P((struct phaser_spacket * packet));
+void handleMessage P((struct mesg_spacket * packet));
+static void handleQueue P((struct queue_spacket * packet));
+static void handlePickok P((struct pickok_spacket * packet));
+static void handleLogin P((struct login_spacket * packet));
+static void handlePlasmaInfo P((struct plasma_info_spacket * packet));
+static void handlePlasma P((struct plasma_spacket * packet));
+static void handleFlags P((struct flags_spacket * packet));
+static void handleKills P((struct kills_spacket * packet));
+static void handlePStatus P((struct pstatus_spacket * packet));
+static void handleMotd P((struct motd_spacket * packet));
+static void handleMask P((struct mask_spacket * packet));
+static void pickSocket P((int old));
+static void handleBadVersion P((struct badversion_spacket * packet));
+int gwrite P((int fd, char *buf, int bytes));
+static void handleHostile P((struct hostile_spacket * packet));
+static void handlePlyrLogin P((struct plyr_login_spacket * packet));
+static void handleStats P((struct stats_spacket * packet));
+static void handlePlyrInfo P((struct plyr_info_spacket * packet));
+static void handlePlanetLoc P((struct planet_loc_spacket * packet));
+static void handleReserved P((struct reserved_spacket * packet));
+
+static void handleScan P((struct scan_spacket * packet));
+static void handleSequence P((struct sequence_spacket * packet));
+static void handleUdpReply P((struct udp_reply_spacket * packet));
+static void informScan P((int p));
+static int openUdpConn P((void));
+#ifdef USE_PORTSWAP
+static int connUdpConn P((void));
+#endif
+static int recvUdpConn P((void));
+static void printUdpInfo P((void));
+/*static void dumpShip P((struct ship *shipp ));*/
+/*static int swapl P((int in ));*/
+static void handleShipCap P((struct ship_cap_spacket * packet));
+static void handleMotdPic P((struct motd_pic_spacket * packet));
+static void handleStats2 P((struct stats_spacket2 * packet));
+static void handleStatus2 P((struct status_spacket2 * packet));
+static void handlePlanet2 P((struct planet_spacket2 * packet));
+static void handleTerrain2 P((struct terrain_packet2 * pkt));
+static void handleTerrainInfo2 P((struct terrain_info_packet2 *pkt));
+static void handleTempPack P((struct obvious_packet * packet));
+static void handleThingy P((struct thingy_spacket * packet));
+static void handleThingyInfo P((struct thingy_info_spacket * packet));
+static void handleRSAKey P((struct rsa_key_spacket * packet));
+void    handlePing();
+static void handleExtension1 P((struct paradiseext1_spacket *));
+
+static void handleEmpty();
+
+
+#ifdef SHORT_PACKETS
+void    handleShortReply(), handleVPlayer(), handleVTorp(),
+        handleSelfShort(), handleSelfShip(), handleVPlanet(), handleSWarning();
+void    handleVTorpInfo(), handleSMessage();
+#endif
+
+#ifdef FEATURE
+void    handleFeature();	/* feature.c */
+#endif
+
+struct packet_handler handlers[] = {
+    {NULL},			/* record 0 */
+    {handleMessage},		/* SP_MESSAGE */
+    {handlePlyrInfo},		/* SP_PLAYER_INFO */
+    {handleKills},		/* SP_KILLS */
+    {handlePlayer},		/* SP_PLAYER */
+    {handleTorpInfo},		/* SP_TORP_INFO */
+    {handleTorp},		/* SP_TORP */
+    {handlePhaser},		/* SP_PHASER */
+    {handlePlasmaInfo},		/* SP_PLASMA_INFO */
+    {handlePlasma},		/* SP_PLASMA */
+    {handleWarning},		/* SP_WARNING */
+    {handleMotd},		/* SP_MOTD */
+    {handleSelf},		/* SP_YOU */
+    {handleQueue},		/* SP_QUEUE */
+    {handleStatus},		/* SP_STATUS */
+    {handlePlanet},		/* SP_PLANET */
+    {handlePickok},		/* SP_PICKOK */
+    {handleLogin},		/* SP_LOGIN */
+    {handleFlags},		/* SP_FLAGS */
+    {handleMask},		/* SP_MASK */
+    {handlePStatus},		/* SP_PSTATUS */
+    {handleBadVersion},		/* SP_BADVERSION */
+    {handleHostile},		/* SP_HOSTILE */
+    {handleStats},		/* SP_STATS */
+    {handlePlyrLogin},		/* SP_PL_LOGIN */
+    {handleReserved},		/* SP_RESERVED */
+    {handlePlanetLoc},		/* SP_PLANET_LOC */
+    {handleScan},		/* SP_SCAN (ATM) */
+    {handleUdpReply},		/* SP_UDP_STAT */
+    {handleSequence},		/* SP_SEQUENCE */
+    {handleSequence},		/* SP_SC_SEQUENCE */
+    {handleRSAKey},		/* SP_RSA_KEY */
+    {handleMotdPic},		/* SP_MOTD_PIC */
+    {handleStats2},		/* SP_STATS2 */
+    {handleStatus2},		/* SP_STATUS2 */
+    {handlePlanet2},		/* SP_PLANET2 */
+    {handleTempPack},		/* SP_TEMP_5 */
+    {handleThingy},		/* SP_THINGY */
+    {handleThingyInfo},		/* SP_THINGY_INFO */
+    {handleShipCap},		/* SP_SHIP_CAP */
+
+#ifdef SHORT_PACKETS
+    {handleShortReply},		/* SP_S_REPLY */
+    {handleSMessage},		/* SP_S_MESSAGE */
+    {handleSWarning},		/* SP_S_WARNING */
+    {handleSelfShort},		/* SP_S_YOU */
+    {handleSelfShip},		/* SP_S_YOU_SS */
+    {handleVPlayer},		/* SP_S_PLAYER */
+#else
+    {handleEmpty},		/* 40 */
+    {handleEmpty},		/* 41 */
+    {handleEmpty},		/* 42 */
+    {handleEmpty},		/* 43 */
+    {handleEmpty},		/* 44 */
+    {handleEmpty},		/* 45 */
+#endif
+    {handlePing},		/* SP_PING */
+#ifdef SHORT_PACKETS
+    {handleVTorp},		/* SP_S_TORP */
+    {handleVTorpInfo},		/* SP_S_TORP_INFO */
+    {handleVTorp},		/* SP_S_8_TORP */
+    {handleVPlanet},		/* SP_S_PLANET */
+#else
+    {handleEmpty},		/* 47 */
+    {handleEmpty},
+    {handleEmpty},
+    {handleEmpty},		/* 50 */
+#endif
+    {handleGameparams},
+    {handleExtension1},
+    {handleTerrain2},		/* 53 */
+    {handleTerrainInfo2},
+    {handleEmpty},
+    {handleEmpty},
+    {handleEmpty},
+    {handleEmpty},
+    {handleEmpty},		/* 59 */
+#ifdef FEATURE
+    {handleFeature},		/* SP_FEATURE */
+#else
+    {handleEmpty},		/* 60 */
+#endif
+};
+
+#define NUM_HANDLERS	(sizeof(handlers)/sizeof(*handlers))
+
+#define NUM_PACKETS (sizeof(handlers) / sizeof(handlers[0]) - 1)
+
+int     serverDead = 0;
+
+int UdpLocalPort = 0;	/* do we want a specified local UDP port */
+
+#ifdef SIZE_LOGGING
+void
+print_totals()
+/* prints the total number of bytes sent/received.  Called when exiting the
+   client [BDyess] */
+{
+    time_t  timeSpent = time(NULL) - timeStart;
+
+    /*
+       printf("Total bytes sent:     %d\nTotal bytes received: %d\n",
+       send_total, receive_total);
+    */
+    /* ftp format [BDyess] */
+    if (timeSpent < 600 /* 10 minutes */ ) {
+	printf("%8d bytes sent     in %d seconds (%.3f Kbytes/s)\n",
+	       send_total, timeSpent,
+	       (float) send_total / (1024.0 * timeSpent));
+	printf("%8d bytes received in %d seconds (%.3f Kbytes/s)\n",
+	       receive_total, timeSpent,
+	       (float) receive_total / (1024.0 * timeSpent));
+    } else {			/* number too big for seconds, use minutes */
+	printf("%8d bytes sent     in %.1f minutes (%.3f Kbytes/s)\n",
+	       send_total, timeSpent / 60.0,
+	       (float) send_total / (1024.0 * timeSpent));
+	printf("%8d bytes received in %.1f minutes (%.3f Kbytes/s)\n",
+	       receive_total, timeSpent / 60.0,
+	       (float) receive_total / (1024.0 * timeSpent));
+    }
+}
+#else
+#define EXIT exit
+#endif				/* SIZE_LOGGING */
+
+int     udpLocalPort = 0;
+static int udpServerPort = 0;
+static long serveraddr = 0;
+static long sequence = 0;
+static int drop_flag = 0;
+static int chan = -1;		/* tells sequence checker where packet is
+				   from */
+static short fSpeed, fDirection, fShield, fOrbit, fRepair, fBeamup, fBeamdown, fCloak,
+        fBomb, fDockperm, fPhaser, fPlasma, fPlayLock, fPlanLock, fTractor,
+        fRepress;
+
+/* reset all the "force command" variables */
+static void
+resetForce()
+{
+    fSpeed = fDirection = fShield = fOrbit = fRepair = fBeamup = fBeamdown =
+    fCloak = fBomb = fDockperm = fPhaser = fPlasma = fPlayLock = fPlanLock =
+    fTractor = fRepress = -1;
+}
+
+/*
+ * If something we want to happen hasn't yet, send it again.
+ *
+ * The low byte is the request, the high byte is a max count.  When the max
+ * count reaches zero, the client stops trying.  Checking is done with a
+ * macro for speed & clarity.
+ */
+#define FCHECK_FLAGS(flag, force, const) {                      \
+        if (force > 0) {                                        \
+            if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) {  \
+                speedReq.type = const;                          \
+                speedReq.speed = (force & 0xff);                \
+                sendServerPacket((struct player_spacket *)&speedReq);   \
+                V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff));     \
+                force -= 0x100;                                 \
+                if (force < 0x100) force = -1;  /* give up */   \
+            } else                                              \
+                force = -1;                                     \
+        }                                                       \
+}
+#define FCHECK_VAL(value, force, const) {                       \
+        if (force > 0) {                                        \
+            if ((value) != (force & 0xff)) {                    \
+                speedReq.type = const;                          \
+                speedReq.speed = (force & 0xff);                \
+                sendServerPacket((struct player_spacket *)&speedReq);   \
+                V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff));     \
+                force -= 0x100;                                 \
+                if (force < 0x100) force = -1;  /* give up */   \
+            } else                                              \
+                force = -1;                                     \
+        }                                                       \
+}
+#define FCHECK_TRACT(flag, force, const) {                      \
+        if (force > 0) {                                        \
+            if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) {  \
+                tractorReq.type = const;                        \
+                tractorReq.state = ((force & 0xff) >= 0x40);    \
+                tractorReq.pnum = (force & 0xff) & (~0x40);     \
+                sendServerPacket((struct player_spacket *)&tractorReq); \
+                V_UDPDIAG(("Forced %d:%d/%d\n", const,          \
+                        tractorReq.state, tractorReq.pnum));    \
+                force -= 0x100;                                 \
+                if (force < 0x100) force = -1;  /* give up */   \
+            } else                                              \
+                force = -1;                                     \
+        }                                                       \
+}
+
+static void
+checkForce()
+{
+    struct speed_cpacket speedReq;
+    struct tractor_cpacket tractorReq;
+
+    /* upgrading kludge [BDyess] */
+    if (!upgrading)
+	FCHECK_VAL(me->p_speed, fSpeed, CP_SPEED);	/* almost always repeats */
+    FCHECK_VAL(me->p_dir, fDirection, CP_DIRECTION);	/* (ditto) */
+    FCHECK_FLAGS(PFSHIELD, fShield, CP_SHIELD);
+    FCHECK_FLAGS(PFORBIT, fOrbit, CP_ORBIT);
+    FCHECK_FLAGS(PFREPAIR, fRepair, CP_REPAIR);
+    FCHECK_FLAGS(PFBEAMUP, fBeamup, CP_BEAM);
+    FCHECK_FLAGS(PFBEAMDOWN, fBeamdown, CP_BEAM);
+    FCHECK_FLAGS(PFCLOAK, fCloak, CP_CLOAK);
+    FCHECK_FLAGS(PFBOMB, fBomb, CP_BOMB);
+    FCHECK_FLAGS(PFDOCKOK, fDockperm, CP_DOCKPERM);
+    FCHECK_VAL(phasers[me->p_no].ph_status, fPhaser, CP_PHASER);	/* bug: dir 0 */
+    FCHECK_VAL(plasmatorps[me->p_no].pt_status, fPlasma, CP_PLASMA);	/* (ditto) */
+    FCHECK_FLAGS(PFPLOCK, fPlayLock, CP_PLAYLOCK);
+    FCHECK_FLAGS(PFPLLOCK, fPlanLock, CP_PLANLOCK);
+
+#ifdef HOCKEY
+    /* kludge to help prevent self-deflects */
+    if(! (hockey && me->p_tractor == 'g'-'a'+10 /*puck*/)) {
+#endif
+      FCHECK_TRACT(PFTRACT, fTractor, CP_TRACTOR);
+      FCHECK_TRACT(PFPRESS, fRepress, CP_REPRESS);
+#ifdef HOCKEY
+    }
+#endif
+}
+
+
+int
+idx_to_mask(i)
+    int     i;
+{
+    if (i == number_of_teams)
+	return ALLTEAM;
+    return 1 << i;
+}
+
+int
+mask_to_idx(m)
+    int     m;
+{
+    int     i, j;
+    for (i = 1, j = -1; m > 0 && i < 5; i++, m >>= 1)
+	if (m & 1)
+	    j += i;
+    if (j > number_of_teams)
+	j = number_of_teams;
+    return j;
+}
+
+
+void
+connectToServer(port)
+    int     port;
+{
+#ifndef DNET
+    int     s;
+    struct sockaddr_in addr;
+    struct sockaddr_in naddr;
+    int     len;
+    fd_set  readfds;
+    struct timeval timeout;
+    struct hostent *hp;
+
+    serverDead = 0;
+    if (sock != -1) {
+	shutdown(sock, 2);
+	sock = -1;
+    }
+    sleep(3);			/* I think this is necessary for some unknown
+				   reason */
+
+#ifdef RWATCH
+    printf("rwatch: Waiting for connection. \n");
+#else
+    printf("Waiting for connection (port %d). \n", port);
+#endif				/* RWATCH */
+
+    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+#ifdef RWATCH
+	printf("rwatch: I can't create a socket\n");
+#else
+	printf("I can't create a socket\n");
+#endif				/* RWATCH */
+#ifdef AUTOKEY
+	if (autoKey)
+	    W_AutoRepeatOn();
+#endif
+
+	EXIT(2);
+    }
+#ifndef RWATCH
+#ifdef nodef			/* don't use for now */
+    set_tcp_opts(s);
+#endif				/* nodef */
+#endif				/* RWATCH */
+
+    addr.sin_family = AF_INET;
+    addr.sin_addr.s_addr = INADDR_ANY;
+    addr.sin_port = htons(port);
+
+    if (bind(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
+	sleep(10);
+	if (bind(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
+	    sleep(10);
+	    if (bind(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
+#ifdef RWATCH
+		printf("rwatch: I can't bind to port!\n");
+#else
+		printf("I can't bind to port!\n");
+#endif				/* RWATCH */
+#ifdef AUTOKEY
+		if (autoKey)
+		    W_AutoRepeatOn();
+#endif
+
+		EXIT(3);
+	    }
+	}
+    }
+    listen(s, 1);
+
+    len = sizeof(naddr);
+
+tryagain:
+    timeout.tv_sec = 240;	/* four minutes */
+    timeout.tv_usec = 0;
+    FD_ZERO(&readfds);
+    FD_SET(s, &readfds);
+    if (select(32, &readfds, NULL, NULL, &timeout) == 0) {
+#ifdef RWATCH
+	printf("rwatch: server died.\n");
+#else
+	printf("Well, I think the server died!\n");
+#endif				/* RWATCH */
+#ifdef AUTOKEY
+	if (autoKey)
+	    W_AutoRepeatOn();
+#endif
+
+	EXIT(0);
+    }
+    sock = accept(s, (struct sockaddr *) & naddr, &len);
+
+    if (sock == -1) {
+#ifdef RWATCH
+	perror("rwatch: accept");
+#else
+	perror("accept");
+#endif				/* RWATCH */
+	goto tryagain;
+    }
+    close(s);
+    pickSocket(port);		/* new socket != port */
+
+
+    /*
+       This is strictly necessary; it tries to determine who the caller is,
+       and set "serverName" and "serveraddr" appropriately.
+    */
+    len = sizeof(struct sockaddr_in);
+    if (getpeername(sock, (struct sockaddr *) & addr, &len) < 0) {
+	perror("unable to get peername");
+	serverName = "nowhere";
+    } else {
+	serveraddr = addr.sin_addr.s_addr;
+	hp = gethostbyaddr((char *) &addr.sin_addr.s_addr, sizeof(long), AF_INET);
+	if (hp != NULL) {
+	    serverName = (char *) malloc(strlen(hp->h_name) + 1);
+	    strcpy(serverName, hp->h_name);
+	} else {
+	    serverName = (char *) malloc(strlen((char *) inet_ntoa(addr.sin_addr)) + 1);
+	    strcpy(serverName, (char *) inet_ntoa(addr.sin_addr));
+	}
+    }
+    printf("Connection from server %s (0x%x)\n", serverName, serveraddr);
+
+#else				/* DNET */
+    /*
+       unix end DNet server process connects to the server, on specified *
+       port
+    */
+    ConnectToDNetServer(port);
+#endif				/* DNET */
+
+}
+
+
+#ifndef DNET
+#ifdef nodef
+static void
+set_tcp_opts(s)
+    int     s;
+{
+    int     optval = 1;
+    struct protoent *ent;
+
+    ent = getprotobyname("TCP");
+    if (!ent) {
+	fprintf(stderr, "TCP protocol not found.\n");
+	return;
+    }
+    if (setsockopt(s, ent->p_proto, TCP_NODELAY, &optval, sizeof(int)) < 0)
+	perror("setsockopt");
+}
+
+static void
+set_udp_opts(s)
+    int     s;
+{
+    int     optval = BUFSIZ;
+    struct protoent *ent;
+    ent = getprotobyname("UDP");
+    if (!ent) {
+	fprintf(stderr, "UDP protocol not found.\n");
+	return;
+    }
+    if (setsockopt(s, ent->p_proto, SO_RCVBUF, &optval, sizeof(int)) < 0)
+	perror("setsockopt");
+}
+#endif				/* nodef */
+
+#endif				/* DNET */
+
+void
+callServer(port, server)
+    int     port;
+    char   *server;
+{
+#ifndef DNET
+    int     s;
+    struct sockaddr_in addr;
+    struct hostent *hp;
+#endif
+    serverDead = 0;
+
+    printf("Calling %s on port %d.\n", server, port);
+#ifdef DNET
+    CallDNetServer(server, port);
+#else
+    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+	printf("I can't create a socket\n");
+	EXIT(0);
+    }
+#ifndef RWATCH
+#ifdef nodef
+    set_tcp_opts(s);
+#endif				/* nodef */
+#endif				/* RWATCH */
+
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(port);
+
+    if ((addr.sin_addr.s_addr = inet_addr(server)) == -1) {
+	if ((hp = gethostbyname(server)) == NULL) {
+	    printf("Who is %s?\n", server);
+	    EXIT(0);
+	} else {
+	    addr.sin_addr.s_addr = *(long *) hp->h_addr;
+	}
+    }
+    serveraddr = addr.sin_addr.s_addr;
+
+    if (connect(s, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
+	printf("Server not listening!\n");
+	EXIT(0);
+    }
+    printf("Got connection.\n");
+
+    sock = s;
+#endif				/* DNET */
+/* pickSocket is utterly useless with DNet, but the server needs the
+   packet to tell it the client is ready to start. */
+
+#ifdef RECORDER
+    startRecorder();
+#endif
+    pickSocket(port);		/* new socket != port */
+}
+
+int
+isServerDead()
+{
+    return (serverDead);
+}
+
+void
+socketPause(sec, usec)
+    int     sec, usec;
+{
+    struct timeval timeout;
+    fd_set  readfds;
+
+#ifdef RECORDER
+    if (playback)
+	return;
+#endif
+#ifdef DNET
+    (void) DNetServerPause(sec, usec, 0);
+#else
+
+    timeout.tv_sec = sec;
+    timeout.tv_usec = usec;
+    FD_ZERO(&readfds);
+    FD_SET(sock, &readfds);
+    if (udpSock >= 0)		/* new */
+	FD_SET(udpSock, &readfds);
+    select(32, &readfds, 0, 0, &timeout);
+#endif				/* DNET */
+}
+
+int
+readFromServer()
+{
+    struct timeval timeout;
+    fd_set  readfds;
+    int     retval = 0, rs;
+
+#ifdef RECORDER
+    if (playback) {
+	while (!pb_update)
+	    doRead(sock);
+	return 1;
+    }
+#endif
+
+    if (serverDead)
+	return (0);
+    if (commMode == COMM_TCP)
+	drop_flag = 0;		/* just in case */
+
+#ifndef DNET
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 0;
+
+    FD_ZERO(&readfds);
+    FD_SET(sock, &readfds);
+    if (udpSock >= 0)
+	FD_SET(udpSock, &readfds);
+    if ((rs = select(32, &readfds, 0, 0, &timeout)) != 0) {
+	if (rs < 0) {
+	    /* NEW */
+	    perror("select");
+	    return 0;
+	}
+#else
+	/* this should have been done before calling the function.. not sure about this, should maybe be doing
+	   DNetServerPause here? -JR*/
+	/*	sigsPending=Wait(sockMask | udpSockMask | SIGBREAKF_CTRL_C);
+	 */
+	if (sigsPending & SIGBREAKF_CTRL_C) {
+	    printf("readFromServer: Ctrl-C break, exiting\n");
+	    exit(0);
+	}
+	/* note for DNet FD_ISSET is  redefined. */
+#endif				/* DNET */
+	/* Read info from the xtrek server */
+	if (FD_ISSET(sock, &readfds)) {
+	    chan = sock;
+	    retval += doRead(sock);
+	}
+	if (udpSock >= 0 && FD_ISSET(udpSock, &readfds)) {
+	    /* WAS V_ *//* should be! */
+	    V_UDPDIAG(("Activity on UDP socket\n"));
+	    chan = udpSock;
+	    if (commStatus == STAT_VERIFY_UDP) {
+		warning("UDP connection established");
+		sequence = 0;	/* reset sequence #s */
+		resetForce();
+		
+		if (udpDebug)
+		    printUdpInfo();
+		UDPDIAG(("UDP connection established.\n"));
+		
+		commMode = COMM_UDP;
+		commStatus = STAT_CONNECTED;
+		commSwitchTimeout = 0;
+		if (udpClientRecv != MODE_SIMPLE)
+		    sendUdpReq(COMM_MODE + udpClientRecv);
+		if (udpWin) {
+		    udprefresh(UDP_CURRENT);
+		    udprefresh(UDP_STATUS);
+		}
+	    }
+	    retval += doRead(udpSock);
+	}
+#ifndef DNET
+    }
+#endif
+
+    /* if switching comm mode, decrement timeout counter */
+    if (commSwitchTimeout > 0) {
+	if (!(--commSwitchTimeout)) {
+	    /*
+	      timed out; could be initial request to non-UDP server (which won't
+	      be answered), or the verify packet got lost en route to the
+	      server.  Could also be a request for TCP which timed out (weird),
+	      in which case we just reset anyway.
+	      */
+	    commModeReq = commMode = COMM_TCP;
+	    commStatus = STAT_CONNECTED;
+	    if (udpSock >= 0)
+		closeUdpConn();
+	    if (udpWin) {
+		udprefresh(UDP_CURRENT);
+		udprefresh(UDP_STATUS);
+	    }
+	    warning("Timed out waiting for UDP response from server");
+	    UDPDIAG(("Timed out waiting for UDP response from server\n"));
+	}
+    }
+    /* if we're in a UDP "force" mode, check to see if we need to do something */
+    if (commMode == COMM_UDP && udpClientSend > 1)
+	checkForce();
+    
+    return (retval != 0);		/* convert to 1/0 */
+}
+
+
+/* this used to be part of the routine above */
+char    buf[BUFSIZ * 2 + 16];
+
+static int
+doRead(asock)
+    int     asock;
+{
+    char   *bufptr;
+    int     size;
+    int     count;
+    int     temp;
+#ifdef HANDLER_TIMES
+    struct timeval htpre, htpost;
+    extern void log_time(int, struct timeval *, struct timeval *);
+#endif
+
+#ifndef DNET
+    struct timeval timeout;
+    fd_set  readfds;
+    timeout.tv_sec = 0;
+    timeout.tv_usec = 0;
+#endif				/* DNET */
+
+    count = sock_read(asock, buf, 2 * BUFSIZ);
+#ifdef DNET
+    if (count == 0) {		/* yuck. */
+	return 0;
+    }
+#endif
+/* TMP */
+#ifdef nodef
+    if (asock == udpSock)
+	printf("read %d bytes\n", count);
+#endif				/* nodef */
+
+    if (count <= 0) {
+	if (asock == udpSock) {
+#ifndef DNET
+	    if (errno == ECONNREFUSED) {
+		struct sockaddr_in addr;
+
+		UDPDIAG(("asock=%d, sock=%d, udpSock=%d, errno=%d\n",
+			 asock, sock, udpSock, errno));
+		UDPDIAG(("count=%d\n", count));
+		UDPDIAG(("Hiccup(%d)!  Reconnecting\n", errno));
+		addr.sin_addr.s_addr = serveraddr;
+		addr.sin_port = htons(udpServerPort);
+		addr.sin_family = AF_INET;
+		if (connect(udpSock, (struct sockaddr *) & addr, sizeof(addr)) < 0) {
+		    perror("connect");
+		    UDPDIAG(("Unable to reconnect\n"));
+		    /* and fall through to disconnect */
+		} else {
+		    UDPDIAG(("Reconnect successful\n"));
+		    return (0);
+		}
+	    }
+#endif				/* DNET */
+	    UDPDIAG(("*** UDP disconnected (res=%d, err=%d)\n",
+		     count, errno));
+	    warning("UDP link severed");
+	    printUdpInfo();
+	    closeUdpConn();
+	    commMode = commModeReq = COMM_TCP;
+	    commStatus = STAT_CONNECTED;
+	    if (udpWin) {
+		udprefresh(UDP_STATUS);
+		udprefresh(UDP_CURRENT);
+	    }
+	    return (0);
+	}
+#ifndef RWATCH
+	printf("1) Got read() of %d. Server dead\n", count);
+	perror("");
+#endif				/* RWATCH */
+	serverDead = 1;
+	return (0);
+    }
+    bufptr = buf;
+    while (bufptr < buf + count) {
+#ifdef SHORT_PACKETS
+computesize:
+	if ((*bufptr == SP_S_MESSAGE && (buf + count - bufptr <= 4))
+	    || (buf + count - bufptr < 4)) {	/* last part may only be
+						   needed for DNet...I'm not
+						   so sure any more.
+						   certainly doesn't hurt to
+						   have it.-JR */
+	    /*
+	       printf("buf+count-bufptr=%d, *bufptr=%d\n",buf + count -
+	       bufptr,*bufptr);
+	    */
+	    size = 0;		/* problem with reads breaking before size
+				   byte for SP_S_MESSAGE has been read. Only
+				   a problem for messages because reads break
+				   on 4 byte boundaries,  other size bytes
+				   are always in the first 4. -JR */
+	} else
+#endif
+	{
+	    size = size_of_spacket(bufptr);
+	    if (size < 1) {
+#if 1
+		fprintf(stderr, "Unknown packet %d.  Faking it.\n",
+			*bufptr);
+		size = 4;
+#else
+		fprintf(stderr, "Unknown packet %d.  Aborting.\n",
+			*bufptr);
+		return (0);
+#endif
+	    }
+#ifdef SHOW_RECEIVED
+	    printf("recieved packet type %d, size %d\n", *bufptr, size);
+#endif				/* SHOW_RECEIVED */
+#ifdef PACKET_LIGHTS
+	    light_receive();
+#endif				/* PACKET_LIGHTS */
+#ifdef SIZE_LOGGING
+	    receive_total += size;
+#endif				/* SIZE_LOGGING */
+	}
+	while (size > count + (buf - bufptr) || size == 0) {
+	    /*
+	       We wait for up to ten seconds for rest of packet. If we don't
+	       get it, we assume the server died.
+	    */
+	    /*
+	       printf("er, possible packet fragment, waiting for the
+	       rest...\n");
+	    */
+#ifdef RECORDER
+	    if (!playback)
+#endif
+	    {
+#ifdef DNET
+		temp = DNetServerPause(20, 0, asock);
+#else				/* DNET */
+		timeout.tv_sec = 20;
+		timeout.tv_usec = 0;
+		FD_ZERO(&readfds);
+		FD_SET(asock, &readfds);
+		/* readfds=1<<asock; */
+		temp = select(32, &readfds, 0, 0, &timeout);
+#endif
+		if (temp == 0) {
+		    printf("Packet fragment.  Server must be dead\n");
+		    serverDead = 1;
+		    return (0);
+		}
+	    }
+#ifdef SHORT_PACKETS
+	    if (size == 0)
+		/* 84=largest short packet message - the 4 we have */
+		temp = sock_read(asock, buf + count, 84);
+	    else
+#endif
+		temp = sock_read(asock, buf + count, size - (count + (buf - bufptr)));
+	    count += temp;
+#ifdef DNET
+	    if (temp < 0)
+#else
+	    if (temp <= 0)
+#endif				/* DNET */
+	    {
+#ifndef RWATCH
+		printf("2) Got read() of %d.  Server is dead\n", temp);
+#endif				/* RWATCH */
+		serverDead = 1;
+		return (0);
+	    }
+#ifdef SHORT_PACKETS
+	    if (size == 0)	/* for the SP_S_MESSAGE problem */
+		goto computesize;
+#endif
+	}
+#ifdef UPDATE_SIZES
+	totalbytes += size;
+	packetbytes[*bufptr] += size;
+#endif
+#ifdef RECORDER
+	if (playback && (*bufptr == REC_UPDATE)) {
+	    pb_update++;
+	    me->p_tractor = bufptr[1];
+	    if (me->p_flags & PFPLOCK)
+		me->p_playerl = bufptr[2];
+	    else
+		me->p_planet = bufptr[2];
+/*	    printf("Read REC_UPDATE pseudo-packet!\n");*/
+	} else
+#endif
+	    if (*bufptr >= 1 &&
+		*bufptr < NUM_HANDLERS &&
+		handlers[(int) *bufptr].handler != NULL) {
+	    if (asock != udpSock ||
+		(!drop_flag || *bufptr == SP_SEQUENCE || *bufptr == SP_SC_SEQUENCE)) {
+		if (asock == udpSock)
+		    packets_received++;	/* ping stuff */
+#ifdef RECORDER
+		if (recordGame)
+		    recordPacket(bufptr, size);
+#endif
+#ifdef HANDLER_TIMES
+		gettimeofday(&htpre,0);
+#endif
+		(*(handlers[(unsigned char)*bufptr].handler)) (bufptr);
+#ifdef HANDLER_TIMES
+		gettimeofday(&htpost,0);
+		log_time(*bufptr, &htpre, &htpost);
+#endif
+		/* printf("handled packet %d\n", (unsigned char)*bufptr); */
+	    } else
+		UDPDIAG(("Ignored type %d\n", *bufptr));
+	} else {
+	    printf("Handler for packet %d not installed...\n", *bufptr);
+	}
+
+	bufptr += size;
+	if (bufptr > buf + BUFSIZ) {
+	    bcopy(buf + BUFSIZ, buf, BUFSIZ);
+	    if (count == BUFSIZ * 2) {
+#ifdef RECORDER
+		if (playback)
+		    temp = 0;
+		else
+#endif
+		{
+#ifdef DNET
+		    temp = DNetServerPause(3, 0, asock);
+#else
+		    FD_ZERO(&readfds);
+		    FD_SET(asock, &readfds);
+		    /* readfds = 1<<asock; */
+		    temp = select(32, &readfds, 0, 0, &timeout);
+#endif				/* DNET */
+		}
+		if (temp != 0) {
+		    temp = sock_read(asock, buf + BUFSIZ, BUFSIZ);
+		    count = BUFSIZ + temp;
+#ifdef DNET
+		    if (temp < 0)
+#else
+		    if (temp <= 0)
+#endif				/* DNET */
+		    {
+#ifndef RWATCH
+			printf("3) Got read() of %d.  Server is dead\n", temp);
+#endif				/* RWATCH */
+			serverDead = 1;
+			return (0);
+		    }
+		} else {
+		    count = BUFSIZ;
+		}
+	    } else {
+		count -= BUFSIZ;
+	    }
+	    bufptr -= BUFSIZ;
+	}
+    }
+    return (1);
+}
+
+#define SANITY_TORPNUM(idx) \
+	if ( (unsigned)(idx) >= ntorps*nplayers) { \
+	    fprintf(stderr, "torp index %d out of bounds\n", (idx)); \
+	    return; \
+	}
+
+#define SANITY_PNUM(idx) \
+	if ( (unsigned)(idx) >= nplayers) { \
+	    fprintf(stderr, "player number %d out of bounds\n", (idx)); \
+	    return; \
+	}
+
+#define SANITY_PHASNUM(idx) \
+	if ( (unsigned)(idx) >= nplayers*nphasers) { \
+	    fprintf(stderr, "phaser number %d out of bounds\n", (idx)); \
+	    return; \
+	}
+
+#define SANITY_PLASNUM(idx) \
+	if ( (unsigned)(idx) >= nplayers*nplasmas) { \
+	    fprintf(stderr, "plasma number %d out of bounds\n", (idx)); \
+	    return; \
+	}
+
+#define SANITY_THINGYNUM(idx) \
+	if ( (unsigned)(idx) >= npthingies*nplayers + ngthingies) { \
+	    fprintf(stderr, "thingy index %x out of bounds\n", (idx)); \
+	    return; \
+	}
+
+#define SANITY_PLANNUM(idx) \
+	if ( (unsigned)(idx) >= nplanets) { \
+	    fprintf(stderr, "planet index %d out of bounds\n", (idx)); \
+	    return; \
+	}
+
+#define SANITY_SHIPNUM(idx) \
+	if ( (unsigned)(idx) >= nshiptypes) { \
+	    fprintf(stderr, "ship type %d out of bounds\n", (idx)); \
+	    return; \
+	}
+
+
+static void
+handleTorp(packet)
+    struct torp_spacket *packet;
+{
+    struct torp *thetorp;
+
+    SANITY_TORPNUM(ntohs(packet->tnum));
+
+    thetorp = &torps[ntohs(packet->tnum)];
+    thetorp->t_x = ntohl(packet->x);
+    thetorp->t_y = ntohl(packet->y);
+    thetorp->t_dir = packet->dir;
+
+#ifdef ROTATERACE
+    if (rotate) {
+	rotate_gcenter(&thetorp->t_x, &thetorp->t_y);
+	rotate_dir(&thetorp->t_dir, rotate_deg);
+#endif
+#ifdef BORGTEST
+	if (bd)
+	    bd_test_torp(ntohs(packet->tnum), thetorp);
+#endif
+    }
+}
+
+
+static void
+handleTorpInfo(packet)
+    struct torp_info_spacket *packet;
+{
+    struct torp *thetorp;
+
+    SANITY_TORPNUM(ntohs(packet->tnum));
+
+    thetorp = &torps[ntohs(packet->tnum)];
+
+    if (packet->status == TEXPLODE && thetorp->t_status == TFREE) {
+	/* FAT: redundant explosion; don't update p_ntorp */
+	/*
+	   printf("texplode ignored\n");
+	*/
+	return;
+    }
+
+    if (thetorp->t_status == TFREE && packet->status) {
+	players[thetorp->t_owner].p_ntorp++;
+	thetorp->frame = 0;
+#ifdef BORGTEST
+	if (bd)
+	    bd_new_torp(ntohs(packet->tnum), thetorp);
+#endif
+
+    }
+    if (thetorp->t_status && packet->status == TFREE) {
+	players[thetorp->t_owner].p_ntorp--;
+    }
+    thetorp->t_war = packet->war;
+
+    if (packet->status != thetorp->t_status) {
+	/* FAT: prevent explosion reset */
+	thetorp->t_status = packet->status;
+	if (thetorp->t_status == TEXPLODE) {
+	    thetorp->t_fuse = NUMDETFRAMES;
+	}
+    }
+}
+
+static void
+handleStatus(packet)
+    struct status_spacket *packet;
+{
+    status->tourn = packet->tourn;
+    status->armsbomb = ntohl(packet->armsbomb);
+    status->planets = ntohl(packet->planets);
+    status->kills = ntohl(packet->kills);
+    status->losses = ntohl(packet->losses);
+    status->time = ntohl(packet->time);
+    status->timeprod = ntohl(packet->timeprod);
+}
+
+static void
+handleSelf(packet)
+    struct you_spacket *packet;
+{
+    SANITY_PNUM(packet->pnum);
+    me = (ghoststart ? &players[ghost_pno] : &players[packet->pnum]);
+    myship = (me->p_ship);
+    mystats = &(me->p_stats);
+    me->p_hostile = packet->hostile;
+    me->p_swar = packet->swar;
+    me->p_armies = packet->armies;
+    me->p_flags = ntohl(packet->flags);
+    me->p_damage = ntohl(packet->damage);
+    me->p_shield = ntohl(packet->shield);
+    me->p_fuel = ntohl(packet->fuel);
+    me->p_etemp = ntohs(packet->etemp);
+    me->p_wtemp = ntohs(packet->wtemp);
+    me->p_whydead = ntohs(packet->whydead);
+    me->p_whodead = ntohs(packet->whodead);
+    status2->clock = (unsigned long) packet->pad2;
+    status2->clock += ((unsigned long) packet->pad3) << 8;
+#ifdef INCLUDE_VISTRACT
+    if (packet->tractor & 0x40)
+	me->p_tractor = (short) packet->tractor & (~0x40);	/* ATM - visible trac
+								   tors */
+#ifdef nodef			/* tmp */
+    else
+	me->p_tractor = -1;
+#endif				/* nodef */
+#endif
+#ifdef SOUND
+    S_HandlePFlags();
+#endif
+
+}
+
+static void
+handlePlayer(packet)
+    struct player_spacket *packet;
+{
+    register struct player *pl;
+    unsigned char newdir;
+
+    SANITY_PNUM(packet->pnum);
+
+
+    pl = &players[packet->pnum];
+    newdir = packet->dir;
+#ifdef ROTATERACE
+    if (rotate)
+	rotate_dir(&newdir, rotate_deg);
+#endif
+#ifdef CHECK_DROPPED
+    /* Kludge to fix lost uncloak packets! [3/94] -JR */
+    if (pl->p_flags & PFCLOAK && pl->p_cloakphase >= (CLOAK_PHASES - 1)) {
+	if (pl->p_dir != newdir) {	/* always sends the same direction
+					   when cloaked! */
+	    int     i, plocked = 0;
+
+	    /*
+	       nplayers is for paradise, probably want MAX_PLAYERS for other
+	       clients
+	    */
+	    for (i = 0; i < nplayers; i++) {	/* except when someone has
+						   this person phasered :( */
+		if ((phasers[i].ph_status & PHHIT) && (phasers[i].ph_target == packet->pnum)) {
+		    plocked = 1;
+		    break;
+		}
+	    }
+	    if (!plocked) {
+		pl->p_flags &= ~(PFCLOAK);
+		if (reportDroppedPackets)
+		    printf("Uncloak kludge, player %d\n", pl->p_no);
+	    }
+	}
+    }
+#endif
+    pl->p_dir = newdir;
+    pl->p_speed = packet->speed;
+    pl->p_x = ntohl(packet->x);
+    pl->p_y = ntohl(packet->y);
+    if (pl == me) {
+	extern int my_x, my_y;	/* from shortcomm.c */
+	my_x = me->p_x;
+	my_y = me->p_y;
+    }
+    redrawPlayer[packet->pnum] = 1;
+
+    if (me == pl) {
+	extern int my_x, my_y;	/* short packets need unrotated co-ords! */
+	my_x = pl->p_x;
+	my_y = pl->p_y;
+    }
+#ifdef ROTATERACE
+    if (rotate) {
+	rotate_gcenter(&pl->p_x, &pl->p_y);
+    }
+#endif
+
+}
+
+
+static void
+handleWarning(packet)
+    struct warning_spacket *packet;
+{
+    warning((char *) packet->mesg);
+}
+
+static void
+handleThingy(packet)
+    struct thingy_spacket *packet;
+{
+    struct thingy *thetorp;
+
+    SANITY_THINGYNUM(ntohs(packet->tnum));
+
+    thetorp = &thingies[ntohs(packet->tnum)];
+    thetorp->t_x = ntohl(packet->x);
+    thetorp->t_y = ntohl(packet->y);
+    /* printf("drone at %d, %d\n", thetorp->t_x, thetorp->t_y); */
+    thetorp->t_dir = packet->dir;
+
+
+#ifdef ROTATERACE
+    if (rotate) {
+	rotate_gcenter(&thetorp->t_x, &thetorp->t_y);
+	rotate_dir(&thetorp->t_dir, rotate_deg);
+    }
+#endif
+
+    if (thetorp->t_shape == SHP_WARP_BEACON)
+	redrawall = 1;		/* shoot, route has changed */
+
+}
+
+static void
+handleThingyInfo(packet)
+    struct thingy_info_spacket *packet;
+{
+    struct thingy *thetorp;
+
+    SANITY_THINGYNUM(ntohs(packet->tnum));
+
+    thetorp = &thingies[ntohs(packet->tnum)];
+
+#if 1
+    thetorp->t_owner = ntohs(packet->owner);
+#else
+    /* we have the gameparam packet now */
+#endif
+
+    if (thetorp->t_shape == SHP_WARP_BEACON)
+	redrawall = 1;		/* redraw the lines, I guess */
+
+    if (ntohs(packet->shape) == SHP_BOOM && thetorp->t_shape == SHP_BLANK) {
+	/* FAT: redundant explosion; don't update p_ntorp */
+	/*
+	   printf("texplode ignored\n");
+	*/
+	return;
+    }
+
+    if (thetorp->t_shape == SHP_BLANK && ntohs(packet->shape) != SHP_BLANK) {
+	players[thetorp->t_owner].p_ndrone++;	/* TSH */
+    }
+    if (thetorp->t_shape != SHP_BLANK && ntohs(packet->shape) == SHP_BLANK) {
+	players[thetorp->t_owner].p_ndrone--;	/* TSH */
+    }
+    thetorp->t_war = packet->war;
+
+    if (ntohs(packet->shape) != thetorp->t_shape) {
+	/* FAT: prevent explosion reset */
+	thetorp->t_shape = ntohs(packet->shape);
+	if (thetorp->t_shape == SHP_BOOM ||
+	    thetorp->t_shape == SHP_PBOOM) {
+	    thetorp->t_fuse = NUMDETFRAMES;
+	}
+    }
+}
+
+void
+sendShortPacket(type, state)
+    char    type, state;
+{
+    struct speed_cpacket speedReq;
+
+    speedReq.type = type;
+    speedReq.speed = state;
+#ifdef UNIX_SOUND
+    if (type == CP_SHIELD) play_sound (SND_SHIELD); /* Shields */
+#endif
+    sendServerPacket((struct player_spacket *) & speedReq);
+    /* printf("Sending packet #%d\n",type); */
+
+    /* if we're sending in UDP mode, be prepared to force it */
+    if (commMode == COMM_UDP && udpClientSend >= 2) {
+	switch (type) {
+	case CP_SPEED:
+	    fSpeed = state | 0x100;
+	    break;
+	case CP_DIRECTION:
+	    fDirection = state | 0x100;
+	    break;
+	case CP_SHIELD:
+	    fShield = state | 0xa00;
+	    break;
+	case CP_ORBIT:
+	    fOrbit = state | 0xa00;
+	    break;
+	case CP_REPAIR:
+	    fRepair = state | 0xa00;
+	    break;
+	case CP_CLOAK:
+	    fCloak = state | 0xa00;
+	    break;
+	case CP_BOMB:
+	    fBomb = state | 0xa00;
+	    break;
+	case CP_DOCKPERM:
+	    fDockperm = state | 0xa00;
+	    break;
+	case CP_PLAYLOCK:
+	    fPlayLock = state | 0xa00;
+	    break;
+	case CP_PLANLOCK:
+	    fPlanLock = state | 0xa00;
+	    break;
+	case CP_BEAM:
+	    if (state == 1)
+		fBeamup = 1 | 0x500;
+	    else
+		fBeamdown = 2 | 0x500;
+	    break;
+	}
+
+	/* force weapons too? */
+	if (udpClientSend >= 3) {
+	    switch (type) {
+	    case CP_PHASER:
+		fPhaser = state | 0x100;
+		break;
+	    case CP_PLASMA:
+		fPlasma = state | 0x100;
+		break;
+	    }
+	}
+    }
+}
+
+void
+sendServerPacket(packet)
+/* Pick a random type for the packet */
+    struct player_spacket *packet;
+{
+    int     size;
+
+#ifdef RWATCH
+    return;
+#endif				/* RWATCH */
+
+    if (serverDead)
+	return;
+    size = size_of_cpacket(packet);
+    if (size < 1) {
+	printf("Attempt to send strange packet %d!\n", packet->type);
+	return;
+    }
+#ifdef SHOW_SEND
+    printf("sending packet type %d, size %d\n", packet->type,
+	   size);
+#endif				/* SHOW_SEND */
+#ifdef PACKET_LIGHTS
+    light_send();
+#endif				/* PACKET_LIGHTS */
+#ifdef SIZE_LOGGING
+    send_total += size;
+#endif				/* SIZE_LOGGING */
+    if (commMode == COMM_UDP) {
+	/* for now, just sent everything via TCP */
+    }
+    if (commMode == COMM_TCP || !udpClientSend) {
+	/* special case for verify packet */
+	if (packet->type == CP_UDP_REQ) {
+	    if (((struct udp_req_cpacket *) packet)->request == COMM_VERIFY)
+		goto send_udp;
+	}
+	/*
+	   business as usual (or player has turned off UDP transmission)
+	*/
+	if (gwrite(sock, (char *) packet, size) != size) {
+	    printf("gwrite failed.  Server must be dead\n");
+	    serverDead = 1;
+	}
+    } else {
+	/*
+	   UDP stuff
+	*/
+	switch (packet->type) {
+	case CP_SPEED:
+	case CP_DIRECTION:
+	case CP_PHASER:
+	case CP_PLASMA:
+	case CP_TORP:
+	case CP_QUIT:
+	case CP_PRACTR:
+	case CP_REPAIR:
+	case CP_ORBIT:
+	case CP_BOMB:
+	case CP_BEAM:
+	case CP_DET_TORPS:
+	case CP_DET_MYTORP:
+	case CP_TRACTOR:
+	case CP_REPRESS:
+	case CP_COUP:
+	case CP_DOCKPERM:
+	case CP_SCAN:
+	case CP_PING_RESPONSE:
+	case CP_CLOAK:
+	case CP_SHIELD:
+	case CP_PLANLOCK:
+	    /*
+	       these are non-critical but don't expire, send with TCP
+	       [BDyess]
+	    */
+	    /* case CP_REFIT: */
+	    /* case CP_PLAYLOCK: */
+	    /* non-critical stuff, use UDP */
+    send_udp:
+	    packets_sent++;	/* ping stuff */
+
+	    V_UDPDIAG(("Sent %d on UDP port\n", packet->type));
+	    if (gwrite(udpSock, (char *) packet, size) != size) {
+		UDPDIAG(("gwrite on UDP failed.  Closing UDP connection\n"));
+		warning("UDP link severed");
+		/* serverDead=1; */
+		commModeReq = commMode = COMM_TCP;
+		commStatus = STAT_CONNECTED;
+		commSwitchTimeout = 0;
+		if (udpWin) {
+		    udprefresh(UDP_STATUS);
+		    udprefresh(UDP_CURRENT);
+		}
+		if (udpSock >= 0)
+		    closeUdpConn();
+	    }
+	    break;
+
+	default:
+	    /* critical stuff, use TCP */
+	    if (gwrite(sock, (char *) packet, size) != size) {
+		printf("gwrite failed.  Server must be dead\n");
+		serverDead = 1;
+	    }
+	}
+    }
+}
+
+static void
+handlePlanet(packet)
+    struct planet_spacket *packet;
+{
+    struct planet *plan;
+    /* FAT: prevent excessive redraw */
+    int     redraw = 0;
+#ifdef HOCKEY
+    int     hockey_update = 0;
+#endif /*HOCKEY*/
+
+    SANITY_PLANNUM(packet->pnum);
+
+    plan = &planets[packet->pnum];
+    if (plan->pl_owner != packet->owner) {
+	redraw = 1;
+#ifdef HOCKEY
+	hockey_update = 1;
+#endif
+    }
+    plan->pl_owner = packet->owner;
+
+    if (plan->pl_owner < (1 << 0) || plan->pl_owner > (1 << (number_of_teams - 1)))
+	plan->pl_owner = NOBODY;
+
+    if (plan->pl_info != packet->info)
+	redraw = 1;
+    plan->pl_info = packet->info;
+    /* Redraw the planet because it was updated by server */
+
+    if (plan->pl_flags != (int) ntohs(packet->flags))
+	redraw = 1;
+    plan->pl_flags = (unsigned short) ntohs(packet->flags);
+
+    if (plan->pl_armies != ntohl(packet->armies))
+	redraw = 1;
+
+    plan->pl_armies = ntohl(packet->armies);
+    if (plan->pl_info == 0) {
+	plan->pl_owner = NOBODY;
+    }
+    if (redraw) {
+	plan->pl_flags |= PLREDRAW;
+	pl_update[packet->pnum].plu_update = 1;	/* used to mean the planet
+						   had moved, now set as a
+						   sign we need to erase AND
+						   redraw. -JR */
+	pl_update[packet->pnum].plu_x = planets[packet->pnum].pl_x;
+	pl_update[packet->pnum].plu_y = planets[packet->pnum].pl_y;
+	if (infomapped && infotype == PLANETTYPE &&
+	    ((struct planet *) infothing)->pl_no == packet->pnum)
+	    infoupdate = 1;
+#ifdef HOCKEY
+        if(hockey_update && hockey) hockeyInit();
+#endif /*HOCKEY*/
+    }
+}
+
+static void
+handlePhaser(packet)
+    struct phaser_spacket *packet;
+{
+    struct phaser *phas;
+
+    SANITY_PHASNUM(packet->pnum);
+
+    phas = &phasers[packet->pnum];
+#ifdef CHECK_DROPPED
+    /* can't fire weapons cloaked, this guy must be uncloaked.. */
+    /* applying this to torps is trickier... -JR */
+    if (packet->status != PHFREE) {
+	if (reportDroppedPackets && (players[packet->pnum].p_flags & PFCLOAK))
+	    printf("Dropped uncloak, player %d. (fired phaser)\n", packet->pnum);
+	players[packet->pnum].p_flags &= ~(PFCLOAK);
+    } else {
+	if (longest_ph_fuse < phas->ph_fuse)
+	    longest_ph_fuse = phas->ph_fuse;
+    }
+#endif
+    phas->ph_status = packet->status;
+    phas->ph_dir = packet->dir;
+    phas->ph_x = ntohl(packet->x);
+    phas->ph_y = ntohl(packet->y);
+    phas->ph_target = ntohl(packet->target);
+    phas->ph_fuse = 0;
+
+#ifdef ROTATERACE
+    if (rotate) {
+	rotate_gcenter(&phas->ph_x, &phas->ph_y);
+	rotate_dir(&phas->ph_dir, rotate_deg);
+    }
+#endif
+#ifdef SOUND
+    if ((me->p_no == packet->pnum) && (packet->status != PHFREE)) {
+	S_PlaySound(S_PHASER);
+    }
+#endif
+#ifdef UNIX_SOUND
+    if ((me->p_no == packet->pnum) && (packet->status != PHFREE)) {
+        play_sound(SND_PHASER); /* Phasers */
+    }
+#endif
+}
+
+void
+handleMessage(packet)
+    struct mesg_spacket *packet;
+{
+    if ((int) packet->m_from >= nplayers)
+	packet->m_from = 255;
+    dmessage(packet->mesg, packet->m_flags, packet->m_from, packet->m_recpt);
+}
+
+
+static void
+handleQueue(packet)
+    struct queue_spacket *packet;
+{
+    queuePos = ntohs(packet->pos);
+    /* printf("Receiving queue position %d\n",queuePos); */
+}
+
+static void
+handleEmpty(ptr)
+    char   *ptr;
+{
+    printf("Unknown packet type: %d\n", *ptr);
+    return;
+}
+
+void
+sendTeamReq(team, ship)
+    int     team, ship;
+{
+    struct outfit_cpacket outfitReq;
+
+    outfitReq.type = CP_OUTFIT;
+    outfitReq.team = team;
+    outfitReq.ship = ship;
+    sendServerPacket((struct player_spacket *) & outfitReq);
+}
+
+static void
+handlePickok(packet)
+    struct pickok_spacket *packet;
+{
+    pickOk = packet->state;
+#ifdef RECORDER
+    if (playback) {		/* added when the packet is recorded. */
+	extern int lastTeamReq;
+	lastTeamReq = packet->pad2;
+    }
+#endif
+}
+
+void
+sendLoginReq(name, pass, login, query)
+    char   *name, *pass;
+    char   *login;
+    char    query;
+{
+    struct login_cpacket packet;
+
+    strcpy(packet.name, name);
+    strcpy(packet.password, pass);
+    if (strlen(login) > 15)
+	login[15] = 0;
+    strcpy(packet.login, login);
+    packet.type = CP_LOGIN;
+    packet.query = query;
+    packet.pad2 = 0x69;		/* added 1/19/93 KAO */
+    packet.pad3 = 0x43;		/* added 1/19/93 KAO *//* was 0x42 3/2/93 */
+    sendServerPacket((struct player_spacket *) & packet);
+}
+
+static void
+handleLogin(packet)
+    struct login_spacket *packet;
+{
+
+
+    loginAccept = packet->accept;
+    if ((packet->pad2 == 69) && (packet->pad3 == 42))
+	paradise = 1;
+    else {
+	/*nshiptypes = 8;*/
+	nplayers=20;
+	nplanets=40;
+    }
+    if (packet->accept) {
+
+	/* we no longer accept keymaps from the server */
+
+	mystats->st_flags = ntohl(packet->flags);
+	keeppeace = (me->p_stats.st_flags / ST_KEEPPEACE) & 1;
+    }
+}
+
+void
+sendTractorReq(state, pnum)
+    char    state;
+    char    pnum;
+{
+    struct tractor_cpacket tractorReq;
+
+    tractorReq.type = CP_TRACTOR;
+    tractorReq.state = state;
+    tractorReq.pnum = pnum;
+    sendServerPacket((struct player_spacket *) & tractorReq);
+
+    if (state)
+	fTractor = pnum | 0x40;
+    else
+	fTractor = 0;
+}
+
+void
+sendRepressReq(state, pnum)
+    char    state;
+    char    pnum;
+{
+    struct repress_cpacket repressReq;
+
+    repressReq.type = CP_REPRESS;
+    repressReq.state = state;
+    repressReq.pnum = pnum;
+    sendServerPacket((struct player_spacket *) & repressReq);
+
+    if (state)
+	fRepress = pnum | 0x40;
+    else
+	fRepress = 0;
+}
+
+void
+sendDetMineReq(torp)
+    short   torp;
+{
+    struct det_mytorp_cpacket detReq;
+
+    detReq.type = CP_DET_MYTORP;
+    detReq.tnum = htons(torp);
+    sendServerPacket((struct player_spacket *) & detReq);
+}
+
+static void
+handlePlasmaInfo(packet)
+    struct plasma_info_spacket *packet;
+{
+    struct plasmatorp *thetorp;
+
+    SANITY_PLASNUM(ntohs(packet->pnum));
+
+    thetorp = &plasmatorps[ntohs(packet->pnum)];
+    if (packet->status == PTEXPLODE && thetorp->pt_status == PTFREE) {
+	/* FAT: redundant explosion; don't update p_nplasmatorp */
+	return;
+    }
+    if (!thetorp->pt_status && packet->status) {
+	players[thetorp->pt_owner].p_nplasmatorp++;
+#ifdef UNIX_SOUND
+    play_sound (SND_PLASMA); /* Plasma */
+#endif
+    }
+    if (thetorp->pt_status && !packet->status) {
+	players[thetorp->pt_owner].p_nplasmatorp--;
+    }
+    thetorp->pt_war = packet->war;
+    if (thetorp->pt_status != packet->status) {
+	/* FAT: prevent explosion timer from being reset */
+	thetorp->pt_status = packet->status;
+	if (thetorp->pt_status == PTEXPLODE) {
+	    thetorp->pt_fuse = NUMDETFRAMES;
+	}
+    }
+}
+
+static void
+handlePlasma(packet)
+    struct plasma_spacket *packet;
+{
+    struct plasmatorp *thetorp;
+
+    SANITY_PLASNUM(ntohs(packet->pnum));
+
+    thetorp = &plasmatorps[ntohs(packet->pnum)];
+    thetorp->pt_x = ntohl(packet->x);
+    thetorp->pt_y = ntohl(packet->y);
+
+#ifdef ROTATERACE
+    if (rotate) {
+	rotate_gcenter(&thetorp->pt_x, &thetorp->pt_y);
+    }
+#endif
+}
+
+static void
+handleFlags(packet)
+    struct flags_spacket *packet;
+{
+    SANITY_PNUM(packet->pnum);
+
+    if (players[packet->pnum].p_flags != ntohl(packet->flags) ||
+    players[packet->pnum].p_tractor != ((short) packet->tractor & (~0x40))) {
+	/* FAT: prevent redundant player update */
+	redrawPlayer[packet->pnum] = 1;
+    } else
+	return;
+
+#ifdef CHECK_DROPPED
+/* TEST */
+/* For the dropped uncloak kludge, completely ignore uncloaks :-) */
+/*    if(players[packet->pnum].p_flags & PFCLOAK) packet->flags |= htonl(PFCLOAK);*/
+/* TEST */
+    /* when a player cloaks, clear his phaser */
+    if (ntohl(packet->flags) & PFCLOAK) {
+	if (phasers[packet->pnum].ph_status != PFREE) {
+	    if (reportDroppedPackets)
+		printf("Lost phaser free packet, player %d. (cloaked)\n", packet->pnum);
+	    phasers[packet->pnum].ph_status = PHFREE;
+	    phasers[packet->pnum].ph_fuse = 0;
+	}
+    }
+#endif
+
+    players[packet->pnum].p_flags = ntohl(packet->flags);
+#ifdef INCLUDE_VISTRACT
+    if (packet->tractor & 0x40)
+	players[packet->pnum].p_tractor = (short) packet->tractor & (~0x40);	/* ATM - visible
+										   tractors */
+    else
+#endif				/* INCLUDE_VISTRACT */
+	players[packet->pnum].p_tractor = -1;
+}
+
+static void
+handleKills(packet)
+    struct kills_spacket *packet;
+{
+
+    SANITY_PNUM(packet->pnum);
+
+    if (players[packet->pnum].p_kills != ntohl(packet->kills) / 100.0) {
+	players[packet->pnum].p_kills = ntohl(packet->kills) / 100.0;
+	/* FAT: prevent redundant player update */
+	updatePlayer[packet->pnum] |= ALL_UPDATE;
+	if (infomapped && infotype == PLAYERTYPE &&
+	    ((struct player *) infothing)->p_no == packet->pnum)
+	    infoupdate = 1;
+#ifdef PLPROF
+	printf("Got handleKills for %d\n", packet->pnum);
+#endif				/* PLPROF */
+#ifdef ARMY_SLIDER
+	if (me == &players[packet->pnum]) {
+	    calibrate_stats();
+	    redrawStats();
+	}
+#endif				/* ARMY_SLIDER */
+    }
+}
+
+static void
+handlePStatus(packet)
+    struct pstatus_spacket *packet;
+{
+    SANITY_PNUM(packet->pnum);
+
+    if (packet->status == PEXPLODE) {
+	players[packet->pnum].p_explode = 0;
+    }
+    /*
+       Ignore DEAD status. Instead, we treat it as PEXPLODE. This gives us
+       time to animate all the frames necessary for the explosions at our own
+       pace.
+    */
+    if (packet->status == PDEAD) {
+	packet->status = PEXPLODE;
+    }
+    if (players[packet->pnum].p_status != packet->status) {
+	players[packet->pnum].p_status = packet->status;
+	redrawPlayer[packet->pnum] = 1;
+#ifdef PLPROF
+	printf("Got handlePStatus for %d\n", packet->pnum);
+#endif				/* PLPROF */
+	updatePlayer[packet->pnum] |= ALL_UPDATE;
+	if (infomapped && infotype == PLAYERTYPE &&
+	    ((struct player *) infothing)->p_no == packet->pnum)
+	    infoupdate = 1;
+#ifdef CHECK_DROPPED
+	if (players[packet->pnum].p_status == POUTFIT) {
+	    int     i;
+	    /* clear phasers on this guy */
+#if 0
+	    for (i = 0; i < nplayers; i++) {
+		if (phasers[i].ph_target == packet->pnum && phasers[i].ph_status == PHHIT) {
+		    if (reportDroppedPackets)
+			printf("Lost phaser free packet, player %d->player %d (target not alive)\n",
+			       i, packet->pnum);
+		    phasers[i].ph_status = PHFREE;
+		}
+	    }
+#endif
+	    if (phasers[packet->pnum].ph_status != PHFREE) {
+		if (reportDroppedPackets)
+		    printf("Lost phaser free packet, player %d (outfitting)\n", packet->pnum);
+		phasers[packet->pnum].ph_status = PHFREE;	/* and his own */
+	    }
+	    if (reportDroppedPackets && players[packet->pnum].p_ntorp > 1)
+		/* only report it on 2 or more left, always clear it. */
+		printf("Lost torp free packet, (%d torps) player %d (outfitting)\n",
+		       players[packet->pnum].p_ntorp, packet->pnum);
+	    players[packet->pnum].p_ntorp = 0;
+	    for (i = packet->pnum * ntorps; i < (packet->pnum + 1) * ntorps; i++) {
+		torps[i].t_status = TFREE;
+	    }
+	}
+#endif
+    }
+}
+
+static void
+handleMotd(packet)
+    struct motd_spacket *packet;
+{
+    newMotdLine((char *) packet->line);
+}
+
+void
+sendMessage(mes, group, indiv)
+    char   *mes;
+    int     group, indiv;
+{
+    struct mesg_cpacket mesPacket;
+
+#ifdef SHORT_PACKETS
+    if (recv_short) {
+	int     size;
+	size = strlen(mes);
+	size += 5;		/* 1 for '\0', 4 packetheader */
+	if ((size % 4) != 0)
+	    size += (4 - (size % 4));
+	mesPacket.pad1 = (char) size;
+
+	/*
+	   OH SHIT!!!! sizes[CP_S_MESSAGE] = size;
+	*/
+
+	mesPacket.type = CP_S_MESSAGE;
+    } else
+#endif
+	mesPacket.type = CP_MESSAGE;
+    mesPacket.group = group;
+    mesPacket.indiv = indiv;
+    strcpy(mesPacket.mesg, mes);
+    sendServerPacket((struct player_spacket *) & mesPacket);
+}
+
+static void
+handleMask(packet)
+    struct mask_spacket *packet;
+{
+    tournMask = packet->mask;
+}
+
+void
+sendOptionsPacket()
+{
+    struct options_cpacket optPacket;
+    register int i;
+    long    flags;
+
+    optPacket.type = CP_OPTIONS;
+    flags = (
+	     ST_NOBITMAPS * (!sendmotdbitmaps) +
+	     ST_KEEPPEACE * keeppeace +
+	     0
+	);
+    optPacket.flags = htonl(flags);
+    /* copy the keymap and make sure no ctrl chars are sent [BDyess] */
+    for (i = 32; i < 128; i++) {
+	optPacket.keymap[i - 32] =
+	    (myship->s_keymap[i] & 128) ? i : myship->s_keymap[i];
+    }
+    /* bcopy(mystats->st_keymap+32, optPacket.keymap,96); */
+    sendServerPacket((struct player_spacket *) & optPacket);
+}
+
+static void
+pickSocket(old)
+    int     old;
+{
+    int     newsocket;
+    struct socket_cpacket sockPack;
+#ifdef RWATCH
+    nextSocket = old;
+#else
+    newsocket = (getpid() & 32767);
+    if (ghoststart)
+	nextSocket = old;
+    while (newsocket < 2048 || newsocket == old) {
+	newsocket = (newsocket + 10687) & 32767;
+    }
+    sockPack.type = CP_SOCKET;
+    sockPack.socket = htonl(newsocket);
+    sockPack.version = (char) SOCKVERSION;
+    sockPack.udp_version = (char) UDPVERSION;
+    sendServerPacket((struct player_spacket *) & sockPack);
+    /* Did we get new socket # sent? */
+    if (serverDead)
+	return;
+    nextSocket = newsocket;
+#endif				/* RWATCH */
+}
+
+static void
+handleBadVersion(packet)
+    struct badversion_spacket *packet;
+{
+    switch (packet->why) {
+    case 0:
+	printf("Sorry, this is an invalid client version.\n");
+	printf("You need a new version of the client code.\n");
+	break;
+    default:
+	printf("Sorry, but you cannot play xtrek now.\n");
+	printf("Try again later.\n");
+	break;
+    }
+    EXIT(1);
+}
+
+int
+gwrite(fd, buf, bytes)
+    int     fd;
+    char   *buf;
+    register int bytes;
+{
+    long    orig = bytes;
+    register long n;
+#ifdef RECORDER
+    if (playback)		/* pretend all is well */
+	return (bytes);
+#endif
+    while (bytes) {
+	n = sock_write(fd, buf, bytes);
+	if (n < 0) {
+	    if (fd == udpSock) {
+		fprintf(stderr, "Tried to write %d, 0x%x, %d\n",
+			fd, (unsigned int) buf, bytes);
+		perror("write");
+		printUdpInfo();
+	    }
+	    return (-1);
+	}
+	bytes -= n;
+	buf += n;
+    }
+    return (orig);
+}
+
+int
+sock_read(sock, data, size)
+    int     sock, size;
+    char   *data;
+{
+#ifdef RECORDER
+    if (playback)
+	return readRecorded(sock, data, size);
+#endif
+
+#ifndef AMIGA
+    return read(sock, data, size);
+#else
+#ifdef DNET
+    return DNet_Read(sock, data, size);
+#else
+    /* NET_SOCKETS code here */
+    /* No idea if this works, old version had it: */
+    return recv(sock, data, size, 0);
+#endif				/* DNET  */
+#endif				/* AMIGA */
+}
+
+static void
+handleHostile(packet)
+    struct hostile_spacket *packet;
+{
+    register struct player *pl;
+
+    SANITY_PNUM(packet->pnum);
+
+    pl = &players[packet->pnum];
+    if (pl->p_swar != packet->war ||
+	pl->p_hostile != packet->hostile) {
+	/* FAT: prevent redundant player update & redraw */
+	pl->p_swar = packet->war;
+	pl->p_hostile = packet->hostile;
+	/* updatePlayer[packet->pnum]=1; why? */
+	redrawPlayer[packet->pnum] = 1;
+    }
+}
+
+static void
+handlePlyrLogin(packet)
+    struct plyr_login_spacket *packet;
+{
+    register struct player *pl;
+
+    SANITY_PNUM(packet->pnum);
+
+#ifdef PLPROF
+    printf("Got handlPlyrLogin for %d\n", packet->pnum);
+#endif				/* PLPROF */
+    updatePlayer[packet->pnum] |= ALL_UPDATE;
+    pl = &players[packet->pnum];
+
+    strcpy(pl->p_name, packet->name);
+    strcpy(pl->p_monitor, packet->monitor);
+    strcpy(pl->p_login, packet->login);
+    pl->p_stats.st_rank = packet->rank;
+    if (packet->pnum == me->p_no) {
+	/* This is me.  Set some stats */
+	if (lastRank == -1) {
+	    if (loggedIn) {
+		lastRank = packet->rank;
+	    }
+	} else {
+	    if (lastRank != packet->rank) {
+		lastRank = packet->rank;
+		promoted = 1;
+	    }
+	}
+    }
+}
+
+static void
+handleStats(packet)
+    struct stats_spacket *packet;
+{
+    register struct player *pl;
+
+    SANITY_PNUM(packet->pnum);
+
+#ifdef PLPROF
+    printf("Got handleStats for %d\n", packet->pnum);
+#endif				/* PLPROF */
+    updatePlayer[packet->pnum] |= LARGE_UPDATE;
+    if (infomapped && infotype == PLAYERTYPE &&
+	((struct player *) infothing)->p_no == packet->pnum)
+	infoupdate = 1;
+    pl = &players[packet->pnum];
+    pl->p_stats.st_tkills = ntohl(packet->tkills);
+    pl->p_stats.st_tlosses = ntohl(packet->tlosses);
+    pl->p_stats.st_kills = ntohl(packet->kills);
+    pl->p_stats.st_losses = ntohl(packet->losses);
+    pl->p_stats.st_tticks = ntohl(packet->tticks);
+    pl->p_stats.st_tplanets = ntohl(packet->tplanets);
+    pl->p_stats.st_tarmsbomb = ntohl(packet->tarmies);
+    pl->p_stats.st_sbkills = ntohl(packet->sbkills);
+    pl->p_stats.st_sblosses = ntohl(packet->sblosses);
+    pl->p_stats.st_armsbomb = ntohl(packet->armies);
+    pl->p_stats.st_planets = ntohl(packet->planets);
+    pl->p_stats.st_maxkills = ntohl(packet->maxkills) / 100.0;
+    pl->p_stats.st_sbmaxkills = ntohl(packet->sbmaxkills) / 100.0;
+}
+
+static void
+handlePlyrInfo(packet)
+    struct plyr_info_spacket *packet;
+{
+    register struct player *pl;
+    static int lastship = -1;
+
+    SANITY_PNUM(packet->pnum);
+
+#ifdef PLPROF
+    printf("Got PlyrInfo for %d\n", packet->pnum);
+#endif				/* PLPROF */
+    updatePlayer[packet->pnum] |= ALL_UPDATE;
+    if (infomapped && infotype == PLAYERTYPE &&
+	((struct player *) infothing)->p_no == packet->pnum)
+	infoupdate = 1;
+    pl = &players[packet->pnum];
+    pl->p_ship = getship(packet->shiptype);
+    if (packet->pnum == me->p_no && currentship != packet->shiptype) {
+	currentship = packet->shiptype;
+	/* sendOptionsPacket(); */
+    }
+    pl->p_teami = mask_to_idx(packet->team);
+    pl->p_mapchars[0] = teaminfo[pl->p_teami].letter;
+    /* printf("team: %d, letter: %c\n",pl->p_teami,pl->p_mapchars[0]); */
+    pl->p_mapchars[1] = shipnos[pl->p_no];
+    if (me == pl && lastship != currentship) {
+	lastship = currentship;
+	redrawTstats();
+	calibrate_stats();
+	redrawStats();		/* tsh */
+    }
+    redrawPlayer[packet->pnum] = 1;
+}
+
+void
+sendUpdatePacket(speed)
+    long    speed;
+{
+    struct updates_cpacket packet;
+
+    packet.type = CP_UPDATES;
+    timerDelay = speed;
+    packet.usecs = htonl(speed);
+    sendServerPacket((struct player_spacket *) & packet);
+#ifdef DEBUG
+    printf("sent request for an update every %d microseconds (%d/sec)\n",speed,1000000/speed);
+#endif
+}
+
+static void
+handlePlanetLoc(packet)
+    struct planet_loc_spacket *packet;
+{
+    struct planet *pl;
+
+    SANITY_PLANNUM(packet->pnum);
+
+    pl = &planets[packet->pnum];
+    pl_update[packet->pnum].plu_x = pl->pl_x;
+    pl_update[packet->pnum].plu_y = pl->pl_y;
+
+    if (pl_update[packet->pnum].plu_update != -1) {
+	pl_update[packet->pnum].plu_update = 1;
+	/*
+	   printf("update: %s, old (%d,%d) new (%d,%d)\n", pl->pl_name,
+	   pl->pl_x, pl->pl_y, ntohl(packet->x),ntohl(packet->y));
+	*/
+    } else {
+	pl_update[packet->pnum].plu_update = 0;
+	pl_update[packet->pnum].plu_x = ntohl(packet->x);
+	pl_update[packet->pnum].plu_y = ntohl(packet->y);
+    }
+    pl->pl_x = ntohl(packet->x);
+    pl->pl_y = ntohl(packet->y);
+    strcpy(pl->pl_name, packet->name);
+    pl->pl_namelen = strlen(packet->name);
+    pl->pl_flags |= PLREDRAW;
+    if (infomapped && infotype == PLANETTYPE &&
+	((struct planet *) infothing)->pl_no == packet->pnum)
+	infoupdate = 1;
+    reinitPlanets = 1;
+    if (pl->pl_x > blk_gwidth) {
+	blk_gwidth = 200000;
+	blk_windgwidth = ((float) WINSIDE) / blk_gwidth;
+    }
+#ifdef ROTATERACE
+    if (rotate) {
+	rotate_gcenter(&pl->pl_x, &pl->pl_y);
+    }
+#endif
+}
+
+#if 0
+
+static void
+handleReserved(packet)
+    struct reserved_spacket *packet;
+{
+    struct reserved_cpacket response;
+
+#ifndef RWATCH
+    encryptReservedPacket(packet, &response, serverName, me->p_no);
+    sendServerPacket((struct player_spacket *) & response);
+#endif				/* RWATCH */
+}
+
+#else
+
+
+static void
+handleReserved(packet)
+    struct reserved_spacket *packet;
+{
+#ifdef AUTHORIZE
+    struct reserved_cpacket response;
+
+    response.type = CP_RESERVED;
+    if (RSA_Client) {		/* can use -o option for old blessing */
+	warning(RSA_VERSION);
+	strncpy((char *)response.resp, RSA_VERSION, RESERVED_SIZE);
+	memcpy(response.data, packet->data, RESERVED_SIZE);
+    } else {
+#if 0
+	/*
+	   if we ever go back to reserved.c checking, we'll reactivate this
+	   code.  However, our reserved.c module hasn't done any real
+	   computation since paradise 1.
+	*/
+	encryptReservedPacket(packet, &response, serverName, me->p_no);
+#else
+	memcpy(response.data, packet->data, 16);
+	memcpy(response.resp, packet->data, 16);
+#endif
+    }
+    sendServerPacket((struct player_spacket *) & response);
+#endif
+}
+
+static void
+handleRSAKey(packet)
+    struct rsa_key_spacket *packet;
+{
+#ifdef AUTHORIZE
+    struct rsa_key_cpacket response;
+#ifndef DNET
+    struct sockaddr_in saddr;
+#endif
+    unsigned char *data;
+    int     len;
+
+#ifdef GATEWAY
+    extern unsigned long netaddr;
+    extern int serv_port;
+#endif
+
+#ifndef DNET
+#ifdef GATEWAY
+    /* if we didn't get it from -H, go ahead and query the socket */
+    if (netaddr == 0) {
+	len = sizeof(saddr);
+	if (getpeername(sock, (struct sockaddr *) & saddr, &len) < 0) {
+	    perror("getpeername(sock)");
+	    exit(1);
+	}
+    } else {
+	saddr.sin_addr.s_addr = netaddr;
+	saddr.sin_port = htons(serv_port);
+    }
+#else				/* GATEWAY */
+    /* query the socket to determine the remote host (ATM) */
+    len = sizeof(saddr);
+    if (getpeername(sock, (struct sockaddr *) & saddr, &len) < 0) {
+	perror("getpeername(sock)");
+	exit(1);
+    }
+#endif				/* GATEWAY */
+
+    data = packet->data;
+    bcopy(&saddr.sin_addr.s_addr, data, sizeof(saddr.sin_addr.s_addr));
+    data += sizeof(saddr.sin_addr.s_addr);
+    bcopy(&saddr.sin_port, data, sizeof(saddr.sin_port));
+#else				/* DNET */
+    {
+	extern long netrek_server_addr;
+	extern unsigned short netrek_server_port;
+
+	data = packet->data;
+	bcopy(&netrek_server_addr, data, sizeof(netrek_server_addr));
+	data += sizeof(netrek_server_addr);
+	bcopy(&netrek_server_port, data, sizeof(netrek_server_port));
+    }
+#endif				/* DNET */
+
+#ifdef DEBUG
+    {
+	struct timeval start, end;
+	gettimeofday(&start, NULL);
+#endif
+	rsa_black_box(response.resp, packet->data,
+		      response.public, response.global);
+#ifdef DEBUG
+	gettimeofday(&end, NULL);
+	printf("rsa_black_box took %d ms.\n",
+	       (1000 * (end.tv_sec - start.tv_sec) +
+		(end.tv_usec - start.tv_usec) / 1000));
+    }
+#endif
+    response.type = CP_RSA_KEY;
+
+    sendServerPacket((struct player_spacket *) & response);
+#ifdef DEBUG
+    printf("RSA verification requested.\n");
+#endif
+#endif				/* AUTHORIZE */
+}
+
+#endif
+
+#ifdef INCLUDE_SCAN
+static void
+handleScan(packet)
+    struct scan_spacket *packet;
+{
+    struct player *pp;
+
+    SANITY_PNUM(packet->pnum);
+
+    if (packet->success) {
+	pp = &players[packet->pnum];
+	pp->p_fuel = ntohl(packet->p_fuel);
+	pp->p_armies = ntohl(packet->p_armies);
+	pp->p_shield = ntohl(packet->p_shield);
+	pp->p_damage = ntohl(packet->p_damage);
+	pp->p_etemp = ntohl(packet->p_etemp);
+	pp->p_wtemp = ntohl(packet->p_wtemp);
+	informScan(packet->pnum);
+    }
+}
+
+static void
+informScan(p)
+    int     p;
+{
+}
+
+#endif				/* INCLUDE_SCAN */
+
+/*
+ * UDP stuff
+ */
+void
+sendUdpReq(req)
+    int     req;
+{
+    struct udp_req_cpacket packet;
+#ifdef RWATCH
+    return;
+#endif				/* RWATCH */
+
+    packet.type = CP_UDP_REQ;
+    packet.request = req;
+
+    if (req >= COMM_MODE) {
+	packet.request = COMM_MODE;
+	packet.connmode = req - COMM_MODE;
+	sendServerPacket((struct player_spacket *) & packet);
+	return;
+    }
+    if (req == COMM_UPDATE) {
+#ifdef SHORT_PACKETS
+	if (recv_short) {	/* not necessary */
+/* Let the client do the work, and not the network :-) */
+	    register int i;
+	    for (i = 0; i < nplayers * ntorps; i++)
+		torps[i].t_status = TFREE;
+
+	    for (i = 0; i < nplayers * nplasmas; i++)
+		plasmatorps[i].pt_status = PTFREE;
+
+	    for (i = 0; i < nplayers; i++) {
+		players[i].p_ntorp = 0;
+		players[i].p_nplasmatorp = 0;
+		phasers[i].ph_status = PHFREE;
+	    }
+	}
+#endif
+	sendServerPacket((struct player_spacket *) & packet);
+	warning("Sent request for full update");
+	return;
+    }
+    if (req == commModeReq) {
+	warning("Request is in progress, do not disturb");
+	return;
+    }
+    if (req == COMM_UDP) {
+	/* open UDP port */
+	if (openUdpConn() >= 0) {
+	    UDPDIAG(("Bound to local port %d on fd %d\n", udpLocalPort, udpSock));
+	} else {
+	    UDPDIAG(("Bind to local port %d failed\n", udpLocalPort));
+	    commModeReq = COMM_TCP;
+	    commStatus = STAT_CONNECTED;
+	    commSwitchTimeout = 0;
+	    if (udpWin)
+		udprefresh(UDP_STATUS);
+	    warning("Unable to establish UDP connection");
+
+	    return;
+	}
+    }
+    /* send the request */
+    packet.type = CP_UDP_REQ;
+    packet.request = req;
+    packet.port = htonl(udpLocalPort);
+#ifdef GATEWAY
+    if (!strcmp(serverName, gw_mach)) {
+	packet.port = htons(gw_serv_port);	/* gw port that server should
+						   call */
+	UDPDIAG(("+ Telling server to contact us on %d\n", gw_serv_port));
+    }
+#endif
+#ifdef USE_PORTSWAP
+    packet.connmode = CONNMODE_PORT;	/* have him send his port */
+#else
+    packet.connmode = CONNMODE_PACKET;	/* we get addr from packet */
+#endif
+    sendServerPacket((struct player_spacket *) & packet);
+
+    /* update internal state stuff */
+    commModeReq = req;
+    if (req == COMM_TCP)
+	commStatus = STAT_SWITCH_TCP;
+    else
+	commStatus = STAT_SWITCH_UDP;
+    commSwitchTimeout = 25;	/* wait 25 updates (about five seconds) */
+
+    UDPDIAG(("Sent request for %s mode\n", (req == COMM_TCP) ?
+	     "TCP" : "UDP"));
+
+#ifndef USE_PORTSWAP
+    if ((req == COMM_UDP) && recvUdpConn() < 0) {
+	UDPDIAG(("Sending TCP reset message\n"));
+	packet.request = COMM_TCP;
+	packet.port = 0;
+	commModeReq = COMM_TCP;
+	sendServerPacket((struct player_spacket *) & packet);
+	/* we will likely get a SWITCH_UDP_OK later; better ignore it */
+	commModeReq = COMM_TCP;
+	commStatus = STAT_CONNECTED;
+	commSwitchTimeout = 0;
+	closeUdpConn();
+    }
+#endif
+
+    if (udpWin)
+	udprefresh(UDP_STATUS);
+}
+
+static void
+handleUdpReply(packet)
+    struct udp_reply_spacket *packet;
+{
+    struct udp_req_cpacket response;
+
+    UDPDIAG(("Received UDP reply %d\n", packet->reply));
+    commSwitchTimeout = 0;
+
+    response.type = CP_UDP_REQ;
+
+    switch (packet->reply) {
+    case SWITCH_TCP_OK:
+	if (commMode == COMM_TCP) {
+	    UDPDIAG(("Got SWITCH_TCP_OK while in TCP mode; ignoring\n"));
+	} else {
+	    commMode = COMM_TCP;
+	    commStatus = STAT_CONNECTED;
+	    warning("Switched to TCP-only connection");
+	    closeUdpConn();
+	    UDPDIAG(("UDP port closed\n"));
+	    if (udpWin) {
+		udprefresh(UDP_STATUS);
+		udprefresh(UDP_CURRENT);
+	    }
+	}
+	break;
+    case SWITCH_UDP_OK:
+	if (commMode == COMM_UDP) {
+	    UDPDIAG(("Got SWITCH_UDP_OK while in UDP mode; ignoring\n"));
+	} else {
+	    /* the server is forcing UDP down our throat? */
+	    if (commModeReq != COMM_UDP) {
+		UDPDIAG(("Got unsolicited SWITCH_UDP_OK; ignoring\n"));
+	    } else {
+#ifdef USE_PORTSWAP
+		udpServerPort = ntohl(packet->port);
+#ifdef nodef			/* simulate calvin error */
+		/* XXX TMP */
+		udpServerPort = 3333;
+#endif
+		if (connUdpConn() < 0) {
+		    UDPDIAG(("Unable to connect, resetting\n"));
+		    warning("Connection attempt failed");
+		    commModeReq = COMM_TCP;
+		    commStatus = STAT_CONNECTED;
+		    if (udpSock >= 0)
+			closeUdpConn();
+		    if (udpWin) {
+			udprefresh(UDP_STATUS);
+			udprefresh(UDP_CURRENT);
+		    }
+		    response.request = COMM_TCP;
+		    response.port = 0;
+		    goto send;
+		}
+#else
+		/* this came down UDP, so we MUST be connected */
+		/* (do the verify thing anyway just for kicks) */
+#endif
+		UDPDIAG(("Connected to server's UDP port\n"));
+		commStatus = STAT_VERIFY_UDP;
+		if (udpWin)
+		    udprefresh(UDP_STATUS);
+		response.request = COMM_VERIFY;	/* send verify request on UDP */
+		response.port = 0;
+		commSwitchTimeout = 25;	/* wait 25 updates */
+#ifdef USE_PORTSWAP
+	send:
+#endif				/* USE_PORTSWAP */
+		sendServerPacket((struct player_spacket *) & response);
+	    }
+	}
+	break;
+    case SWITCH_DENIED:
+	if (ntohs(packet->port)) {
+	    UDPDIAG(("Switch to UDP failed (different version)\n"));
+	    warning("UDP protocol request failed (bad version)");
+	} else {
+	    UDPDIAG(("Switch to UDP denied\n"));
+	    warning("UDP protocol request denied");
+	}
+	commModeReq = commMode;
+	commStatus = STAT_CONNECTED;
+	commSwitchTimeout = 0;
+	if (udpWin)
+	    udprefresh(UDP_STATUS);
+	if (udpSock >= 0)
+	    closeUdpConn();
+	break;
+    case SWITCH_VERIFY:
+	UDPDIAG(("Received UDP verification\n"));
+	break;
+    default:
+	fprintf(stderr, "netrek: Got funny reply (%d) in UDP_REPLY packet\n",
+		packet->reply);
+	break;
+    }
+}
+
+#define MAX_PORT_RETRY  10
+static int
+openUdpConn()
+{
+#ifndef DNET
+    struct sockaddr_in addr;
+    struct hostent *hp;
+    int     attempts;
+
+#ifdef RECORDER
+    if (playback)
+	return 0;
+#endif
+    if (udpSock >= 0) {
+	fprintf(stderr, "netrek: tried to open udpSock twice\n");
+	return (0);		/* pretend we succeeded (this could be bad) */
+    }
+    if ((udpSock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+	perror("netrek: unable to create DGRAM socket");
+	return (-1);
+    }
+#ifdef nodef
+    set_udp_opts(udpSock);
+#endif				/* nodef */
+
+    if(UdpLocalPort == 0) {
+	UdpLocalPort = intDefault("baseUdpLocalPort", 0);
+	UDPDIAG(("using base port %d\n", UdpLocalPort));
+    }
+
+    addr.sin_addr.s_addr = INADDR_ANY;
+    addr.sin_family = AF_INET;
+
+    errno = 0;
+    udpLocalPort = (getpid() & 32767) + (random() % 256);
+    for (attempts = 0; attempts < MAX_PORT_RETRY; attempts++) {
+	if(UdpLocalPort){
+	    /* force UDP to be starting at a base address */
+	    udpLocalPort = UdpLocalPort + attempts;
+	} else while (udpLocalPort < 2048) {
+	    udpLocalPort = (udpLocalPort + 10687) & 32767;
+	}
+#ifdef GATEWAY
+	/* we need the gateway to know where to find us */
+	if (!strcmp(serverName, gw_mach)) {
+	    UDPDIAG(("+ gateway test: binding to %d\n", gw_local_port));
+	    udpLocalPort = gw_local_port;
+	}
+#endif
+	addr.sin_port = htons(udpLocalPort);
+	if (bind(udpSock, (struct sockaddr *) & addr, sizeof(addr)) >= 0)
+	    break;
+    }
+    if (attempts == MAX_PORT_RETRY) {
+	perror("netrek: bind");
+	UDPDIAG(("Unable to find a local port to bind to\n"));
+	close(udpSock);
+	udpSock = -1;
+	return (-1);
+    }
+    UDPDIAG(("Local port is %d\n", udpLocalPort));
+    if(UdpLocalPort) {
+	fprintf(stdout, "Local UDP port is %d\n", udpLocalPort);
+    }
+
+    /* determine the address of the server */
+    if (!serveraddr) {
+	if ((addr.sin_addr.s_addr = inet_addr(serverName)) == -1) {
+	    if ((hp = gethostbyname(serverName)) == NULL) {
+		printf("Who is %s?\n", serverName);
+#ifdef AUTOKEY
+		if (autoKey)
+		    W_AutoRepeatOn();
+#endif
+
+		EXIT(0);
+	    } else {
+		addr.sin_addr.s_addr = *(long *) hp->h_addr;
+	    }
+	}
+	serveraddr = addr.sin_addr.s_addr;
+	UDPDIAG(("Found serveraddr == 0x%x\n", (unsigned int) serveraddr));
+    }
+    return (0);
+#else				/* DNET */
+#ifdef RECORDER
+    if (playback)
+	return 0;
+#endif
+    return DNetOpenUDPConn(serverName);
+#endif				/* DNET */
+}
+
+#ifdef USE_PORTSWAP
+static int
+connUdpConn()
+{
+#ifndef DNET
+    struct sockaddr_in addr;
+    int     len;
+
+#ifdef RECORDER
+    if (playback)
+	return 0;
+#endif
+    addr.sin_addr.s_addr = serveraddr;
+    addr.sin_family = AF_INET;
+    addr.sin_port = htons(udpServerPort);
+
+    UDPDIAG(("Connecting to host 0x%x on port %d\n", serveraddr, udpServerPort));
+    if (connect(udpSock, &addr, sizeof(addr)) < 0) {
+	fprintf(stderr, "Error %d: ");
+	perror("netrek: unable to connect UDP socket");
+	printUdpInfo();		/* debug */
+	return (-1);
+    }
+#ifdef nodef
+    len = sizeof(addr);
+    if (getsockname(udpSock, &addr, &len) < 0) {
+	perror("netrek: unable to getsockname(UDP)");
+	UDPDIAG(("Can't get our own socket; connection failed\n"));
+	close(udpSock);
+	udpSock = -1;
+	return -1;
+    }
+    printf("udpLocalPort %d, getsockname port %d\n",
+	   udpLocalPort, addr.sin_port);
+#endif
+
+    return (0);
+#endif				/* DNET */
+}
+#endif
+
+#ifndef USE_PORTSWAP
+static int
+recvUdpConn()
+{
+#ifndef DNET
+    fd_set  readfds;
+    struct timeval to;
+    struct sockaddr_in from;
+    int     fromlen, res;
+
+#ifdef RECORDER
+    if (playback)
+	return 0;
+#endif
+    bzero(&from, sizeof(from));	/* don't get garbage if really broken */
+
+    /* we patiently wait until the server sends a packet to us */
+    /* (note that we silently eat the first one) */
+    UDPDIAG(("Issuing recvfrom() call\n"));
+    printUdpInfo();
+    fromlen = sizeof(from);
+    FD_ZERO(&readfds);
+    FD_SET(udpSock, &readfds);
+    to.tv_sec = 6;		/* wait 3 seconds, then abort */
+    to.tv_usec = 0;
+    if ((res = select(32, &readfds, 0, 0, &to)) <= 0) {
+	if (!res) {
+	    UDPDIAG(("timed out waiting for response"));
+	    warning("UDP connection request timed out");
+	    return (-1);
+	} else {
+	    perror("select() before recvfrom()");
+	    return (-1);
+	}
+    }
+    if (recvfrom(udpSock, buf, BUFSIZ, 0, (struct sockaddr *) & from, &fromlen) < 0) {
+	perror("recvfrom");
+	UDPDIAG(("recvfrom failed, aborting UDP attempt"));
+	return (-1);
+    }
+    if (from.sin_addr.s_addr != serveraddr) {
+	/* safe? */
+	serveraddr = from.sin_addr.s_addr;
+	UDPDIAG(("Warning: from 0x%x, but server is 0x%x\n",
+	   (unsigned int) from.sin_addr.s_addr, (unsigned int) serveraddr));
+    }
+    if (from.sin_family != AF_INET) {
+	UDPDIAG(("Warning: not AF_INET (%d)\n", from.sin_family));
+    }
+    udpServerPort = ntohs(from.sin_port);
+    UDPDIAG(("recvfrom() succeeded; will use server port %d\n", udpServerPort));
+#ifdef GATEWAY
+    if (!strcmp(serverName, gw_mach)) {
+	UDPDIAG(("+ actually, I'm going to use %d\n", gw_port));
+	udpServerPort = gw_port;
+	from.sin_port = htons(udpServerPort);
+    }
+#endif
+
+    if (connect(udpSock, (struct sockaddr *) & from, sizeof(from)) < 0) {
+	perror("netrek: unable to connect UDP socket after recvfrom()");
+	close(udpSock);
+	udpSock = -1;
+	return (-1);
+    }
+    return (0);
+#else				/* DNET */
+#ifdef RECORDER
+    if (playback)
+	return 0;
+#endif
+    return DNetRecvUDPConn();
+#endif				/* DNET */
+}
+#endif
+
+int
+closeUdpConn()
+{
+    V_UDPDIAG(("Closing UDP socket\n"));
+#ifdef RECORDER
+    if (playback)
+	return 0;
+#endif
+
+#ifdef DNET
+    DNetCloseUDP();
+    return 0;
+#else
+    if (udpSock < 0) {
+	fprintf(stderr, "netrek: tried to close a closed UDP socket\n");
+	return (-1);
+    }
+    shutdown(udpSock, 2);
+    close(udpSock);
+    udpSock = -1;
+    return 0;
+#endif				/* DNET */
+}
+
+static void
+printUdpInfo()
+{
+#ifndef DNET
+    struct sockaddr_in addr;
+    int     len;
+
+    len = sizeof(addr);
+    if (getsockname(udpSock, (struct sockaddr *) & addr, &len) < 0) {
+/*      perror("printUdpInfo: getsockname");*/
+	return;
+    }
+    UDPDIAG(("LOCAL: addr=0x%x, family=%d, port=%d\n",
+	     (unsigned int) addr.sin_addr.s_addr,
+	     addr.sin_family, ntohs(addr.sin_port)));
+
+    if (getpeername(udpSock, (struct sockaddr *) & addr, &len) < 0) {
+/*      perror("printUdpInfo: getpeername");*/
+	return;
+    }
+    UDPDIAG(("PEER : addr=0x%x, family=%d, port=%d\n",
+	     (unsigned int) addr.sin_addr.s_addr,
+	     addr.sin_family, ntohs(addr.sin_port)));
+#endif
+}
+
+static void
+handleSequence(packet)
+    struct sequence_spacket *packet;
+{
+    static int recent_count = 0, recent_dropped = 0;
+    long    newseq;
+
+    drop_flag = 0;
+    if (chan != udpSock)
+	return;			/* don't pay attention to TCP sequence #s */
+    udpTotal++;
+    recent_count++;
+
+    /* update percent display every 256 updates (~50 seconds usually) */
+    if (!(udpTotal & 0xff))
+	if (udpWin)
+	    udprefresh(UDP_DROPPED);
+
+    newseq = (long) ntohs(packet->sequence);
+/*    printf("read %d - ", newseq);*/
+
+    if (((unsigned short) sequence) > 65000 &&
+	((unsigned short) newseq) < 1000) {
+	/* we rolled, set newseq = 65536+sequence and accept it */
+	sequence = ((sequence + 65536) & 0xffff0000) | newseq;
+    } else {
+	/* adjust newseq and do compare */
+	newseq |= (sequence & 0xffff0000);
+
+	if (!udpSequenceChk) {	/* put this here so that turning seq check */
+	    sequence = newseq;	/* on and off doesn't make us think we lost */
+	    return;		/* a whole bunch of packets. */
+	}
+	if (newseq > sequence) {
+	    /* accept */
+	    if (newseq != sequence + 1) {
+		udpDropped += (newseq - sequence) - 1;
+		udpTotal += (newseq - sequence) - 1;	/* want TOTAL packets */
+		recent_dropped += (newseq - sequence) - 1;
+		recent_count += (newseq - sequence) - 1;
+		if (udpWin)
+		    udprefresh(UDP_DROPPED);
+		UDPDIAG(("sequence=%ld, newseq=%ld, we lost some\n",
+			 sequence, newseq));
+	    }
+	    sequence = newseq;
+	} else {
+	    /* reject */
+	    if (packet->type == SP_SC_SEQUENCE) {
+		V_UDPDIAG(("(ignoring repeat %ld)\n", newseq));
+	    } else {
+		UDPDIAG(("sequence=%ld, newseq=%ld, ignoring transmission\n",
+			 sequence, newseq));
+	    }
+	    /*
+	       the remaining packets will be dropped and we shouldn't count
+	       the SP_SEQUENCE packet either
+	    */
+	    packets_received--;
+	    drop_flag = 1;
+	}
+    }
+/*    printf("newseq %d, sequence %d\n", newseq, sequence);*/
+    if (recent_count > UDP_RECENT_INTR) {
+	/* once a minute (at 5 upd/sec), report on how many were dropped */
+	/* during the last UDP_RECENT_INTR updates                       */
+	udpRecentDropped = recent_dropped;
+	recent_count = recent_dropped = 0;
+	if (udpWin)
+	    udprefresh(UDP_DROPPED);
+    }
+}
+
+
+/*
+static void dumpShip(shipp)
+struct ship *shipp;
+{
+  printf("ship stats:\n");
+  printf("phaser range = %d\n", shipp->s_phaserrange);
+  printf("max speed = %d\n", shipp->s_maxspeed);
+  printf("max shield = %d\n", shipp->s_maxshield);
+  printf("max damage = %d\n", shipp->s_maxdamage);
+  printf("max egntemp = %d\n", shipp->s_maxegntemp);
+  printf("max wpntemp = %d\n", shipp->s_maxwpntemp);
+  printf("max armies = %d\n", shipp->s_maxarmies);
+  printf("type = %d\n", shipp->s_type);
+  printf("torp speed = %d\n", shipp->s_torpspeed);
+  printf("letter = %c\n", shipp->s_letter);
+  printf("desig = %2.2s\n", shipp->s_desig);
+  printf("bitmap = %d\n\n", shipp->s_bitmap);
+}
+*/
+
+static void
+handleShipCap(packet)		/* SP_SHIP_CAP */
+    struct ship_cap_spacket *packet;
+{
+    struct shiplist *temp;
+
+    /*
+       What are we supposed to do?
+    */
+
+    SANITY_SHIPNUM(ntohs(packet->s_type));
+
+    if (packet->operation) {	/* remove ship from list */
+	temp = shiptypes;
+	if (temp->ship->s_type == (int) ntohs(packet->s_type)) {
+	    shiptypes = temp->next;
+	    shiptypes->prev = NULL;
+	}
+	while (temp->next != NULL) {
+	    if (temp->next->ship->s_type == (int) ntohs(packet->s_type)) {
+		temp = temp->next;
+		temp->prev->next = temp->next;
+		if (temp->next)
+		    temp->next->prev = temp->prev;
+		free(temp->ship);
+		free(temp);
+		return;
+	    } else {
+		temp = temp->next;
+	    }
+	}
+    }
+    /*
+       Since we're adding the ship, we need to find out if we already have
+       that ship, and if so, replace it.
+    */
+
+    temp = shiptypes;
+    while (temp != NULL) {
+	if (temp->ship->s_type == (int) ntohs(packet->s_type)) {
+	    temp->ship->s_type = ntohs(packet->s_type);
+	    temp->ship->s_torpspeed = ntohs(packet->s_torpspeed);
+	    temp->ship->s_phaserrange = ntohs(packet->s_phaserrange);
+	    if (temp->ship->s_phaserrange < 200)	/* backward
+							   compatibility */
+		temp->ship->s_phaserrange *= PHASEDIST / 100;
+	    temp->ship->s_maxspeed = ntohl(packet->s_maxspeed);
+	    temp->ship->s_maxfuel = ntohl(packet->s_maxfuel);
+	    temp->ship->s_maxshield = ntohl(packet->s_maxshield);
+	    temp->ship->s_maxdamage = ntohl(packet->s_maxdamage);
+	    temp->ship->s_maxwpntemp = ntohl(packet->s_maxwpntemp);
+	    temp->ship->s_maxegntemp = ntohl(packet->s_maxegntemp);
+	    temp->ship->s_maxarmies = ntohs(packet->s_maxarmies);
+	    temp->ship->s_letter = packet->s_letter;
+	    temp->ship->s_desig[0] = packet->s_desig1;
+	    temp->ship->s_desig[1] = packet->s_desig2;
+	    temp->ship->s_bitmap = ntohs(packet->s_bitmap);
+	    buildShipKeymap(temp->ship);
+/*dumpShip(temp->ship);*/
+	    return;
+	}
+	temp = temp->next;
+    }
+
+    /*
+       Not there, so we need to make a new entry in the list for it.
+    */
+    temp = (struct shiplist *) malloc(sizeof(struct shiplist));
+    temp->next = shiptypes;
+    temp->prev = NULL;
+    if (shiptypes)
+	shiptypes->prev = temp;
+    shiptypes = temp;
+    temp->ship = (struct ship *) malloc(sizeof(struct ship));
+    temp->ship->s_type = ntohs(packet->s_type);
+    temp->ship->s_torpspeed = ntohs(packet->s_torpspeed);
+    temp->ship->s_phaserrange = ntohs(packet->s_phaserrange);
+    temp->ship->s_maxspeed = ntohl(packet->s_maxspeed);
+    temp->ship->s_maxfuel = ntohl(packet->s_maxfuel);
+    temp->ship->s_maxshield = ntohl(packet->s_maxshield);
+    temp->ship->s_maxdamage = ntohl(packet->s_maxdamage);
+    temp->ship->s_maxwpntemp = ntohl(packet->s_maxwpntemp);
+    temp->ship->s_maxegntemp = ntohl(packet->s_maxegntemp);
+    temp->ship->s_maxarmies = ntohs(packet->s_maxarmies);
+    temp->ship->s_letter = packet->s_letter;
+    temp->ship->s_desig[0] = packet->s_desig1;
+    temp->ship->s_desig[1] = packet->s_desig2;
+    temp->ship->s_bitmap = ntohs(packet->s_bitmap);
+    buildShipKeymap(temp->ship);
+/*  dumpShip(temp->ship);*/
+}
+
+static void
+handleMotdPic(packet)		/* SP_SHIP_CAP */
+    struct motd_pic_spacket *packet;
+{
+    int     x, y, page, width, height;
+
+    x = ntohs(packet->x);
+    y = ntohs(packet->y);
+    width = ntohs(packet->width);
+    height = ntohs(packet->height);
+    page = ntohs(packet->page);
+
+    newMotdPic(x, y, width, height, (char *) packet->bits, page);
+}
+
+static void
+handleStats2(packet)
+    struct stats_spacket2 *packet;
+{
+    struct stats2 *p;		/* to hold packet's player's stats2 struct */
+
+    SANITY_PNUM(packet->pnum);
+
+    updatePlayer[packet->pnum] |= LARGE_UPDATE;
+    if (infomapped && infotype == PLAYERTYPE &&
+	((struct player *) infothing)->p_no == packet->pnum)
+	infoupdate = 1;
+    p = &(players[packet->pnum].p_stats2);	/* get player's stats2 struct */
+    p->st_genocides = ntohl(packet->genocides);
+    p->st_tmaxkills = (float) ntohl(packet->maxkills) / 100.0;
+    p->st_di = (float) ntohl(packet->di) / 100.0;
+    p->st_tkills = (int) ntohl(packet->kills);
+    p->st_tlosses = (int) ntohl(packet->losses);
+    p->st_tarmsbomb = (int) ntohl(packet->armsbomb);
+    p->st_tresbomb = (int) ntohl(packet->resbomb);
+    p->st_tdooshes = (int) ntohl(packet->dooshes);
+    p->st_tplanets = (int) ntohl(packet->planets);
+    p->st_tticks = (int) ntohl(packet->tticks);
+    p->st_sbkills = (int) ntohl(packet->sbkills);
+    p->st_sblosses = (int) ntohl(packet->sblosses);
+    p->st_sbticks = (int) ntohl(packet->sbticks);
+    p->st_sbmaxkills = (float) ntohl(packet->sbmaxkills) / 100.0;
+    p->st_wbkills = (int) ntohl(packet->wbkills);
+    p->st_wblosses = (int) ntohl(packet->wblosses);
+    p->st_wbticks = (int) ntohl(packet->wbticks);
+    p->st_wbmaxkills = (float) ntohl(packet->wbmaxkills) / 100.0;
+    p->st_jsplanets = (int) ntohl(packet->jsplanets);
+    p->st_jsticks = (int) ntohl(packet->jsticks);
+    if (p->st_rank != (int) ntohl(packet->rank) ||
+	p->st_royal != (int) ntohl(packet->royal)) {
+	p->st_rank = (int) ntohl(packet->rank);
+	p->st_royal = (int) ntohl(packet->royal);
+	updatePlayer[packet->pnum] |= ALL_UPDATE;
+    }
+}
+
+static void
+handleStatus2(packet)
+    struct status_spacket2 *packet;
+{
+    updatePlayer[me->p_no] |= LARGE_UPDATE;
+    if (infomapped && infotype == PLAYERTYPE &&
+	((struct player *) infothing)->p_no == me->p_no)
+	infoupdate = 1;
+    status2->tourn = packet->tourn;
+    status2->dooshes = ntohl(packet->dooshes);
+    status2->armsbomb = ntohl(packet->armsbomb);
+    status2->resbomb = ntohl(packet->resbomb);
+    status2->planets = ntohl(packet->planets);
+    status2->kills = ntohl(packet->kills);
+    status2->losses = ntohl(packet->losses);
+    status2->sbkills = ntohl(packet->sbkills);
+    status2->sblosses = ntohl(packet->sblosses);
+    status2->sbtime = ntohl(packet->sbtime);
+    status2->wbkills = ntohl(packet->wbkills);
+    status2->wblosses = ntohl(packet->wblosses);
+    status2->wbtime = ntohl(packet->wbtime);
+    status2->jsplanets = ntohl(packet->jsplanets);
+    status2->jstime = ntohl(packet->jstime);
+    status2->time = ntohl(packet->time);
+    status2->timeprod = ntohl(packet->timeprod);
+}
+
+static void
+handlePlanet2(packet)
+    struct planet_spacket2 *packet;
+{
+    SANITY_PLANNUM(packet->pnum);
+
+    planets[packet->pnum].pl_owner = packet->owner;
+    planets[packet->pnum].pl_info = packet->info;
+    planets[packet->pnum].pl_flags = ntohl(packet->flags);
+    planets[packet->pnum].pl_timestamp = ntohl(packet->timestamp);
+    planets[packet->pnum].pl_armies = ntohl(packet->armies);
+    planets[packet->pnum].pl_flags |= PLREDRAW;
+    pl_update[packet->pnum].plu_update = 1;
+    pl_update[packet->pnum].plu_x = planets[packet->pnum].pl_x;
+    pl_update[packet->pnum].plu_y = planets[packet->pnum].pl_y;
+    if (infomapped && infotype == PLANETTYPE &&
+	((struct planet *) infothing)->pl_no == packet->pnum)
+	infoupdate = 1;
+}
+
+static void 
+handleTerrainInfo2(pkt)
+  struct terrain_info_packet2 *pkt;
+{
+#ifdef ZDIAG2
+    fprintf( stderr, "Receiving terrain info packet\n" );
+    fprintf( stderr, "Terrain dims: %d x %d\n", ntohs(pkt->xdim), ntohs(pkt->ydim) );
+#endif
+    received_terrain_info = TERRAIN_STARTED;
+    terrain_x = ntohs(pkt->xdim);
+    terrain_y = ntohs(pkt->ydim);
+} 
+
+static void
+handleTerrain2(pkt)
+    struct terrain_packet2 *pkt;
+{
+    static int curseq = 0, totbytes = 0, done = 0;
+    int i, status;
+    unsigned long dlen;
+#ifdef ZDIAG2
+    static unsigned char sum = 0;
+    static unsigned numnz = 0;
+#endif
+    static unsigned char *gzipTerrain = NULL, *orgTerrain = NULL;
+    
+#ifdef ZDIAG2
+    fprintf( stderr, "Receiving Terrain packet.  This should be %d.\n", curseq+1 );
+#endif
+
+    if( (done == TERRAIN_DONE) && (received_terrain_info == TERRAIN_STARTED ) ){
+      /* receiving new terrain info */
+      free( gzipTerrain );
+      free( orgTerrain );
+      free( terrainInfo );
+      gzipTerrain = orgTerrain = NULL;
+      terrainInfo = NULL;
+      curseq = done = totbytes = 0;
+    }
+      
+    curseq++;
+    if( (curseq != pkt->sequence) || !(received_terrain_info) ){
+      /* Should fill in a list of all packets missed */
+      /* or request header packet from server */
+      fprintf( stderr, "Blech!  Received terrain packet before terrain_info\n" );
+      return;
+    }
+#ifdef ZDIAG2
+    fprintf( stderr, "Receiving packet %d out of %d\n", curseq, pkt->total_pkts );
+#endif
+    if( !gzipTerrain ){
+      gzipTerrain = (unsigned char *)malloc( pkt->total_pkts << 7 );
+#if defined(ZDIAG) || defined(ZDIAG2)
+      fprintf( stderr, "Allocating %d bytes for gzipTerrain.\n", pkt->total_pkts << 7 );
+#endif
+		/* another yukko constant */
+    }
+    if( !orgTerrain ){
+      orgTerrain = (unsigned char *)malloc( terrain_x*terrain_y );
+      dlen = terrain_x * terrain_y;
+#if defined(ZDIAG) || defined(ZDIAG2)
+      fprintf( stderr, "Allocating %d bytes for orgTerrain.\n", dlen );
+#endif
+    }
+    for( i = 0; i < pkt->length; i++ ){
+#ifdef ZDIAG2
+      if( !(i%10) ){
+        fprintf( stderr, "Params: %d, %d\n", ((curseq-1)<<7)+i, i );
+      }
+#endif
+      gzipTerrain[((curseq-1)<<7)+i] = pkt->terrain_type[i];
+    }
+    totbytes += pkt->length;
+    if( curseq == pkt->total_pkts ){
+#if defined(ZDIAG) || defined(ZDIAG2)
+      status = uncompress( orgTerrain, &dlen, gzipTerrain, totbytes );
+      if( status != Z_OK ){
+        if( status == Z_BUF_ERROR ){
+          fprintf( stderr, "Unable to uncompress -- Z_BUF_ERROR.\n" );
+        }
+        if( status == Z_MEM_ERROR ){
+          fprintf( stderr, "Unable to uncompress -- Z_MEM_ERROR.\n" );
+        }
+        if( status = Z_DATA_ERROR ){
+          fprintf( stderr, "Unable to uncompress -- Z_DATA_ERROR!\n" );
+        }
+      }
+      else{
+        fprintf( stderr, "Total zipped terrain received: %d bytes\n", totbytes );
+      }
+#else
+      uncompress( orgTerrain, &dlen, gzipTerrain, totbytes );
+#endif
+      terrainInfo = (struct t_unit *)malloc( dlen * sizeof( struct t_unit ) );
+      for( i = 0; i < dlen; i++ ){
+        terrainInfo[i].types = orgTerrain[i];
+#ifdef ZDIAG2
+	sum |= orgTerrain[i];
+        if( orgTerrain[i] != 0 ){
+          numnz++;
+        }
+#endif
+      }
+      done = received_terrain_info = TERRAIN_DONE;
+#ifdef ZDIAG2
+      fprintf( stderr, "Sum = %d, numnz = %d\n", sum, numnz );
+#endif
+    }
+}    
+
+static void
+handleTempPack(packet)		/* SP_SHIP_CAP */
+    struct obvious_packet *packet;
+{
+    struct obvious_packet reply;
+    /* printf("New MOTD info available\n"); */
+    erase_motd();
+    reply.type = CP_ASK_MOTD;
+    sendServerPacket((struct player_spacket *) & reply);
+}
+
+/* handlers for the extension1 packet */
+
+int
+compute_extension1_size(pkt)
+    char   *pkt;
+{
+    if (pkt[0] != SP_PARADISE_EXT1)
+	return -1;
+
+    switch (pkt[1]) {
+    case SP_PE1_MISSING_BITMAP:
+	return sizeof(struct pe1_missing_bitmap_spacket);
+    case SP_PE1_NUM_MISSILES:
+	return sizeof(struct pe1_num_missiles_spacket);
+    default:
+	return -1;
+    }
+}
+
+static void
+handleExtension1(packet)
+    struct paradiseext1_spacket *packet;
+{
+    switch (packet->subtype) {
+    case SP_PE1_MISSING_BITMAP:
+	{
+	    struct pe1_missing_bitmap_spacket *pkt =
+	    (struct pe1_missing_bitmap_spacket *) packet;
+
+	    newMotdPic(ntohs(pkt->x),
+		       ntohs(pkt->y),
+		       ntohs(pkt->width),
+		       ntohs(pkt->height),
+		       0,
+		       ntohs(pkt->page));
+	}
+	break;
+    case SP_PE1_NUM_MISSILES:
+	me->p_totmissiles = ntohs(((struct pe1_num_missiles_spacket *) packet)->num);
+	/* printf("updated totmissiles to %d\n",me->p_totmissiles); */
+	if (me->p_totmissiles < 0)
+	    me->p_totmissiles = 0;	/* SB/WB have -1 */
+	break;
+    default:
+	printf("unknown paradise extension packet 1 subtype = %d\n",
+	       packet->subtype);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sound.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,156 @@
+/*
+ * sound.c - Platform Independant Sound Support - July 1996
+ * Sujal M. Patel (smpatel@umiacs.umd.edu)
+ *
+ *
+ * Copyright (c) 1994-1996, Sujal M. Patel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      $Id: sound.c,v 1.1.1.1 1997/12/06 05:41:30 darius Exp $
+ */
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <unistd.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include "data.h"
+
+
+
+static int soundfd;
+static char audioOK = 1;
+static char sound_flags[20]; /* Sound Flag for sound 1-19 */
+
+
+
+void init_sound ()
+{
+  int i, pid, child,fd[2];
+  char *argv[4];
+  char filename[512];
+#ifdef linux
+  char *arch = "linux";
+#else
+#ifdef __FreeBSD__
+  char *arch = "freebsd";
+#else
+#ifdef __NetBSD__
+  char *arch = "netbsd";
+#else
+#ifdef sun
+  char *arch = "sun";
+#else
+#ifdef foo
+  char *arch = "foobar";
+#else
+  char *arch = "generic";
+#endif
+#endif
+#endif
+#endif
+#endif
+
+  signal(SIGCHLD, SIG_IGN);
+
+  if(unixSoundPath[0] == '?')  {
+      audioOK = 0;
+      return;
+  };
+
+  /*  Create a pipe, set the write end to close when we exec the sound server,
+      and set both (is the write end necessary?) ends to non-blocking   */
+  pipe(fd);
+  soundfd=fd[1];
+
+  if( !(child=fork()) )  {
+      close(fd[1]);
+      dup2(fd[0],STDIN_FILENO);
+      close(fd[0]);
+      sprintf (filename, "paradise.sndsrv.%s", arch);
+      argv[0] = filename;
+      argv[1] = unixSoundPath;
+      argv[2] = unixSoundDev;
+      argv[3] = NULL;
+      execvp(filename, argv);
+      fprintf (stderr, "Couldn't Execute Sound Server (paradise.sndsrv.%s)!\n", arch);
+      exit (0);
+  };
+  close(fd[0]);
+
+  sleep(1);
+
+  if (kill(child, 0))  {
+      audioOK = 0;  
+      close(soundfd);
+  };
+
+  for (i = 0; i < 19; i++) sound_flags[i] = 0;
+} 
+
+void play_sound (k)
+int k;
+{
+  char c;
+
+  c = k;
+  if ((playSounds) && (audioOK)) write (soundfd, &c, sizeof (c));
+}
+
+
+
+void maybe_play_sound (k)
+int k;
+{
+  char c;
+
+  if (sound_flags[k] & 1) return;
+
+  sound_flags[k] |= 1;
+
+  c = (unsigned char)(k);
+  if ((playSounds) && (audioOK)) write (soundfd, &c, sizeof (c));
+}
+
+
+
+void sound_completed (k)
+int k;
+{
+  sound_flags[k] &= ~1;
+}
+
+
+
+void kill_sound ()
+{ 
+  char c;
+
+  c = -1;               
+  if ((playSounds) && (audioOK)) write (soundfd, &c, sizeof (c));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sound.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,52 @@
+/*
+ * sound.h - Platform Independant Sound Support - July 1996
+ * Sujal M. Patel (smpatel@umiacs.umd.edu)
+ *
+ *
+ * Copyright (c) 1994-1996, Sujal M. Patel
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      $Id: sound.h,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $
+ */
+
+
+#define SND_EXPLOSION 0
+#define SND_CLOAK     1
+#define SND_FIRETORP  2
+#define SND_PHASER    3
+#define SND_PLASMA    4
+#define SND_SHIELD    5
+#define SND_TORPHIT   6
+#define SND_EXP_SB    7
+#define SND_PARADISE  8
+#define SND_THERMAL   9
+#define SND_REDALERT  10
+
+#ifdef __STDC__
+void init_sound ();             /* Init Sound System                          */
+void play_sound (int k);        /* Play a Sound                               */
+void maybe_play_sound (int k);  /* Play sound if the last 'k' sound_completed */
+void sound_completed (int k);   /* Complete a sound 'k'                       */
+void kill_sound ();             /* Terminate a sound unpredictably :)         */
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/spopt.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,177 @@
+/* $Id: spopt.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+#ifdef SHORT_PACKETS
+/*
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+
+/*
+ * Refresh item i
+ */
+
+void
+sprefresh(i)
+    int     i;
+{
+    char    buf[BUFSIZ];
+
+    switch (i) {
+
+    case SPK_VFIELD:
+	sprintf(buf, "%seceive variable and short packets",
+		recv_short ? "R" : "Don't r");
+	break;
+    case SPK_MFIELD:
+	sprintf(buf, "%seceive messages", recv_mesg ? "R" : "Don't r");
+	break;
+    case SPK_KFIELD:
+	sprintf(buf, "%seceive kill messages", recv_kmesg ? "R" : "Don't r");
+	break;
+    case SPK_WFIELD:
+	sprintf(buf, "%seceive warning messages", recv_warn ? "R" : "Don't r");
+	break;
+    case SPK_TFIELD:
+	sprintf(buf, "Receive threshold: %s_", recv_threshold_s);
+	break;
+    case SPK_WHYFIELD:
+	sprintf(buf, "%sdd why dead messages", why_dead ? "A" : "Don't a");
+	break;
+    case SPK_DONE:
+	sprintf(buf, "Done");
+	break;
+    }
+
+    W_WriteText(spWin, 0, i, textColor, buf, strlen(buf), 0);
+}
+
+void
+spwindow()
+{
+    register int i;
+
+    for (i = 0; i < SPK_NUMFIELDS; i++)
+	sprefresh(i);
+
+    /* Map window */
+    W_MapWindow(spWin);
+}
+
+void
+spdone()
+{
+    /* Unmap window */
+    W_UnmapWindow(spWin);
+}
+
+void
+spaction(data)
+    W_Event *data;
+{
+    int     v;
+    register int i;
+    register char *cp;
+
+    switch (data->y) {
+
+    case SPK_VFIELD:
+	if (data->type == W_EV_BUTTON) {
+	    if (recv_short)
+		sendShortReq(SPK_VOFF);
+	    else
+		sendShortReq(SPK_VON);
+	}
+	break;
+
+    case SPK_MFIELD:
+	if (data->type == W_EV_BUTTON) {
+	    if (recv_mesg)
+		sendShortReq(SPK_MOFF);
+	    else
+		sendShortReq(SPK_MON);
+	}
+	break;
+
+    case SPK_KFIELD:
+	if (data->type == W_EV_BUTTON) {
+	    if (recv_kmesg)
+		sendShortReq(SPK_M_NOKILLS);
+	    else
+		sendShortReq(SPK_M_KILLS);
+	}
+	break;
+
+    case SPK_WFIELD:
+	if (data->type == W_EV_BUTTON) {
+	    if (recv_warn)
+		sendShortReq(SPK_M_NOWARN);
+	    else
+		sendShortReq(SPK_M_WARN);
+	}
+	break;
+
+    case SPK_TFIELD:
+	if (data->type == W_EV_KEY) {
+	    switch (data->key) {
+	    case '\b':
+	    case '\177':
+		cp = recv_threshold_s;
+		i = strlen(cp);
+		if (i > 0) {
+		    cp += i - 1;
+		    *cp = '\0';
+		}
+		break;
+	    case '\025':
+	    case '\030':
+		recv_threshold_s[0] = '\0';
+		break;
+
+	    default:
+		if (data->key >= '0' && data->key <= '9') {
+		    cp = recv_threshold_s;
+		    i = strlen(cp);
+		    if (i < 4) {
+			cp += i;
+			cp[1] = '\0';
+			cp[0] = data->key;
+		    }
+		}
+		break;
+	    }
+	    sprefresh(SPK_TFIELD);
+	}
+	break;
+
+    case SPK_WHYFIELD:
+	if (F_feature_packets && data->type == W_EV_BUTTON) {
+	    if (why_dead)
+		sendFeature("WHY_DEAD", 'S', 0, 0, 0);
+	    else
+		sendFeature("WHY_DEAD", 'S', 1, 0, 0);
+	}
+	break;
+    case SPK_DONE:
+
+	if (data->type == W_EV_BUTTON) {
+	    if (sscanf(recv_threshold_s, "%d", &v) != 1)
+		strcpy(recv_threshold_s, "0");
+	    else if (recv_threshold != v) {
+		recv_threshold = v;
+		sendThreshold(recv_threshold);
+	    }
+	    spdone();
+	}
+	break;
+
+    }
+}
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/starbitmaps.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,795 @@
+/* $Id: starbitmaps.h,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+#define star_width 30
+#define star_height 30
+static unsigned char star_bitarray[][120] = {
+    {
+	0x00, 0x20, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+	0x00, 0x10, 0x02, 0x00, 0x40, 0x30, 0x03, 0x00, 0x00, 0xfc, 0x0f, 0x00,
+	0x00, 0x07, 0x1c, 0x00, 0x00, 0x0b, 0x30, 0x00, 0xf8, 0x09, 0x22, 0x00,
+	0xc0, 0x18, 0x64, 0x1c, 0x40, 0x11, 0xcc, 0x17, 0x60, 0x03, 0x8c, 0x03,
+	0x60, 0x00, 0x86, 0x00, 0x20, 0x04, 0x80, 0x00, 0x20, 0x18, 0xb8, 0x00,
+	0x3c, 0x1e, 0xa0, 0x14, 0x7e, 0x00, 0x80, 0x06, 0x72, 0x02, 0xc4, 0x03,
+	0x60, 0x40, 0xc8, 0x01, 0x40, 0x40, 0x70, 0x00, 0xc0, 0x40, 0xf0, 0x00,
+	0xc0, 0x03, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x03, 0x80, 0xfc, 0x07, 0x06,
+	0xc0, 0x40, 0x00, 0x04, 0xc0, 0x60, 0x00, 0x00, 0x40, 0x10, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x04, 0x00,
+	0x00, 0x10, 0x02, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0xf8, 0x1f, 0x00,
+	0x00, 0x06, 0x1c, 0x00, 0x18, 0x0f, 0x30, 0x00, 0xf8, 0x09, 0x26, 0x02,
+	0xc0, 0x18, 0x66, 0x1d, 0x40, 0x11, 0xc8, 0x17, 0x60, 0x03, 0x88, 0x13,
+	0x60, 0x00, 0x80, 0x00, 0x20, 0x00, 0x80, 0x00, 0x20, 0x0c, 0xb8, 0x00,
+	0x3c, 0x1e, 0xa0, 0x10, 0x7e, 0x10, 0x80, 0x06, 0x72, 0x00, 0xc4, 0x03,
+	0x62, 0x80, 0xc8, 0x01, 0x44, 0x80, 0x70, 0x00, 0xc0, 0x80, 0xf0, 0x00,
+	0xc0, 0x03, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x03, 0x80, 0xfc, 0x07, 0x02,
+	0xc0, 0x40, 0x00, 0x00, 0x40, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+	0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x10, 0x04, 0x00,
+	0x00, 0x10, 0x02, 0x00, 0x00, 0x30, 0x03, 0x00, 0x00, 0xfc, 0x1f, 0x00,
+	0x00, 0x06, 0x3c, 0x04, 0x1c, 0x0f, 0x30, 0x02, 0xf8, 0x09, 0x26, 0x02,
+	0xc0, 0x18, 0x66, 0x1d, 0x40, 0x11, 0xc0, 0x17, 0x60, 0x03, 0x80, 0x11,
+	0x60, 0x00, 0x80, 0x08, 0x20, 0x00, 0x80, 0x00, 0x20, 0x1c, 0xb8, 0x00,
+	0x2c, 0x16, 0xa0, 0x10, 0x6e, 0x88, 0x80, 0x02, 0x72, 0x80, 0xc4, 0x03,
+	0x62, 0x80, 0xc8, 0x01, 0x46, 0x00, 0x50, 0x00, 0xc4, 0x00, 0xf0, 0x00,
+	0xc0, 0x03, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x03, 0x80, 0xfc, 0x07, 0x06,
+	0x80, 0x40, 0x00, 0x00, 0x40, 0x60, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+	0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10, 0x04, 0x00,
+	0x00, 0x10, 0x02, 0x00, 0x00, 0x30, 0x43, 0x00, 0x00, 0xf8, 0x1f, 0x08,
+	0x00, 0x06, 0x38, 0x04, 0x08, 0x0f, 0x32, 0x02, 0xf8, 0x09, 0x25, 0x02,
+	0xc0, 0x18, 0x62, 0x19, 0x40, 0x11, 0xc0, 0x13, 0x60, 0x03, 0x80, 0x11,
+	0x60, 0x00, 0x80, 0x08, 0x20, 0x00, 0x80, 0x04, 0x20, 0x00, 0xb8, 0x00,
+	0x24, 0x1e, 0xa0, 0x18, 0x6e, 0x9c, 0x80, 0x00, 0x62, 0x80, 0xc4, 0x03,
+	0x62, 0x82, 0xc8, 0x01, 0x46, 0xc0, 0x70, 0x00, 0xcc, 0x60, 0xf0, 0x00,
+	0xd0, 0x23, 0xd8, 0x00, 0x80, 0x77, 0xce, 0x01, 0x80, 0xfc, 0x07, 0x06,
+	0x80, 0x40, 0x02, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x04, 0x00,
+	0x00, 0x10, 0x02, 0x00, 0x00, 0x30, 0x03, 0x08, 0x00, 0xf8, 0x1f, 0x00,
+	0x00, 0x06, 0x38, 0x00, 0x00, 0x0f, 0x30, 0x00, 0xe0, 0x09, 0x20, 0x02,
+	0xc0, 0x18, 0x60, 0x01, 0x40, 0x11, 0xc0, 0x13, 0x60, 0x03, 0x80, 0x11,
+	0x60, 0x00, 0x80, 0x0c, 0x20, 0x00, 0x80, 0x06, 0x20, 0x00, 0xb8, 0x00,
+	0x20, 0x1e, 0xa0, 0x0c, 0x66, 0x9e, 0x80, 0x00, 0x62, 0x80, 0xc0, 0x03,
+	0x62, 0x80, 0xc0, 0x01, 0x46, 0xc0, 0x70, 0x00, 0xdc, 0x40, 0xf0, 0x00,
+	0xf0, 0x03, 0xd8, 0x00, 0x80, 0x77, 0x8e, 0x01, 0x80, 0xfd, 0x07, 0x00,
+	0x00, 0x00, 0x06, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x25, 0x00,
+	0x00, 0x00, 0x04, 0x08, 0x00, 0x30, 0x01, 0x00, 0x00, 0xfc, 0x1f, 0x00,
+	0x00, 0x07, 0x3c, 0x00, 0x00, 0x0f, 0x30, 0x00, 0xc0, 0x09, 0x66, 0x00,
+	0xe0, 0x18, 0xe2, 0x01, 0x40, 0x11, 0xc0, 0x01, 0x60, 0x03, 0x80, 0x11,
+	0x60, 0x00, 0x80, 0x16, 0x20, 0x00, 0x80, 0x07, 0x20, 0x10, 0xb8, 0x00,
+	0x20, 0x1e, 0xa0, 0x06, 0x62, 0x9c, 0x80, 0x00, 0x60, 0x84, 0xc4, 0x03,
+	0x62, 0x80, 0xc8, 0x01, 0x46, 0xc0, 0xf0, 0x00, 0xfc, 0x60, 0x70, 0x00,
+	0xf0, 0x23, 0xd8, 0x00, 0x80, 0x77, 0x8e, 0x01, 0x00, 0xfd, 0x07, 0x00,
+	0x00, 0x00, 0x06, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x25, 0x10,
+	0x00, 0x00, 0x21, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00,
+	0x00, 0x06, 0x3c, 0x00, 0x00, 0x0f, 0x30, 0x00, 0xe0, 0x09, 0x60, 0x00,
+	0xe0, 0x18, 0xe0, 0x01, 0x60, 0x11, 0xc0, 0x01, 0x60, 0x03, 0x80, 0x09,
+	0x60, 0x00, 0x80, 0x13, 0x20, 0x00, 0x80, 0x03, 0x20, 0x38, 0xb8, 0x00,
+	0x30, 0x3e, 0xa0, 0x03, 0x70, 0x38, 0x80, 0x01, 0x61, 0x02, 0xc1, 0x01,
+	0x60, 0x00, 0xc2, 0x01, 0x44, 0x02, 0xe0, 0x00, 0xfc, 0x02, 0x70, 0x00,
+	0xf0, 0x43, 0x58, 0x00, 0x40, 0xf7, 0x8e, 0x01, 0x00, 0xfe, 0x0f, 0x00,
+	0x00, 0x10, 0x02, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x21, 0x00,
+	0x00, 0x80, 0x20, 0x00, 0x00, 0xbc, 0x20, 0x00, 0x00, 0xfe, 0x1f, 0x00,
+	0x00, 0x07, 0x3c, 0x00, 0x80, 0x0f, 0x34, 0x00, 0xf8, 0x09, 0x60, 0x00,
+	0xe0, 0x18, 0xe0, 0x01, 0x60, 0x11, 0xc0, 0x01, 0x60, 0x03, 0x80, 0x01,
+	0x60, 0x00, 0x80, 0x01, 0x30, 0x60, 0x80, 0x01, 0x38, 0x7c, 0xb8, 0x00,
+	0x30, 0x3e, 0xa0, 0x03, 0x60, 0x10, 0x80, 0x01, 0x60, 0x02, 0xc1, 0x01,
+	0x60, 0x00, 0xc2, 0x01, 0x40, 0x00, 0xe0, 0x00, 0xf8, 0x00, 0x70, 0x00,
+	0xf0, 0x03, 0xd8, 0x00, 0x40, 0xf7, 0x9f, 0x00, 0x00, 0xfe, 0x0f, 0x00,
+	0x00, 0x90, 0x06, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+	0x00, 0x90, 0x04, 0x00, 0x00, 0xb0, 0x26, 0x00, 0x00, 0xfe, 0x27, 0x00,
+	0x00, 0x07, 0x3c, 0x00, 0x80, 0x0f, 0x30, 0x00, 0xf0, 0x09, 0x60, 0x00,
+	0xe0, 0x18, 0xe0, 0x06, 0x60, 0x11, 0xc0, 0x06, 0x60, 0x03, 0x80, 0x00,
+	0x60, 0x00, 0x83, 0x01, 0x20, 0xc0, 0x81, 0x00, 0x38, 0xdc, 0xb8, 0x00,
+	0x3c, 0x1e, 0xa0, 0x02, 0x70, 0x10, 0x80, 0x03, 0x60, 0x02, 0xc4, 0x01,
+	0x60, 0x00, 0xc8, 0x01, 0x60, 0x04, 0xe0, 0x00, 0xf0, 0x04, 0x70, 0x00,
+	0xc0, 0x07, 0xd8, 0x00, 0xc0, 0x77, 0x8e, 0x01, 0x40, 0xfc, 0x07, 0x00,
+	0xc0, 0xc0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }, {
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00,
+	0x00, 0x10, 0x04, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00, 0xfc, 0x07, 0x00,
+	0x00, 0x07, 0x1c, 0x00, 0x80, 0x0f, 0x30, 0x00, 0xf0, 0x09, 0x20, 0x00,
+	0xc0, 0x18, 0x60, 0x1a, 0x60, 0x11, 0xc4, 0x06, 0x60, 0x03, 0x8c, 0x00,
+	0x20, 0x00, 0x86, 0x01, 0x20, 0x00, 0x83, 0x00, 0x3c, 0x18, 0xb8, 0x00,
+	0x3e, 0x1e, 0xa0, 0x1c, 0x70, 0x10, 0x80, 0x06, 0x60, 0x02, 0xc4, 0x03,
+	0x60, 0x20, 0xc8, 0x01, 0x40, 0x20, 0x60, 0x00, 0xc0, 0x20, 0xf0, 0x00,
+	0x80, 0x03, 0xd8, 0x00, 0x80, 0x77, 0x9c, 0x03, 0xc0, 0xfc, 0x07, 0x00,
+	0xc0, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+    }
+};
+
+#define wormhole_width 80
+#define wormhole_height 80
+static unsigned char wormhole_bitarray[][867] = {{
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+   0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x20, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0x84, 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x80, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x90,
+   0x00, 0xa7, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x96,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xe0, 0x10, 0x22, 0x07, 0x90,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x1c, 0x06, 0x00, 0x00, 0xc0, 0x30, 0x08, 0x00, 0x00, 0x04,
+   0x84, 0xc1, 0x00, 0x00, 0x00, 0x73, 0x04, 0x00, 0x20, 0x00, 0x43, 0x52,
+   0x25, 0x00, 0x40, 0x06, 0x00, 0x00, 0x00, 0x00, 0x30, 0x8b, 0x14, 0x02,
+   0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x20, 0x01, 0x00, 0x72,
+   0x00, 0x00, 0x80, 0x10, 0x48, 0x63, 0xe4, 0x51, 0x00, 0x5c, 0x00, 0x04,
+   0x00, 0x00, 0x06, 0x00, 0x05, 0x0e, 0x00, 0xa4, 0x00, 0x00, 0x10, 0x00,
+   0xc1, 0x55, 0x41, 0x01, 0x25, 0x28, 0x81, 0x04, 0x00, 0x40, 0x3e, 0x2d,
+   0xf4, 0x47, 0x01, 0x70, 0x03, 0x00, 0x00, 0x80, 0x90, 0x04, 0x7e, 0x71,
+   0x28, 0x60, 0x03, 0x00, 0x00, 0x50, 0x01, 0x10, 0x33, 0x18, 0x41, 0x70,
+   0x0c, 0x00, 0x00, 0xa2, 0x00, 0xc0, 0x84, 0x10, 0x5a, 0x60, 0x0a, 0x00,
+   0x00, 0x60, 0x00, 0x20, 0x20, 0x02, 0x08, 0x60, 0x08, 0x28, 0x00, 0x50,
+   0x10, 0x0f, 0x00, 0xa2, 0x60, 0x60, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x04,
+   0x00, 0xc8, 0x40, 0x50, 0x20, 0x00, 0x00, 0x08, 0x50, 0x0a, 0x00, 0x40,
+   0xa3, 0x20, 0x20, 0x40, 0x00, 0x20, 0x50, 0x09, 0x20, 0xc0, 0x04, 0xe1,
+   0x00, 0x00, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x83, 0x01, 0x40, 0x40, 0x10,
+   0x04, 0x0c, 0xca, 0x04, 0x98, 0x00, 0x03, 0xc8, 0xa5, 0x00, 0x00, 0x00,
+   0xa2, 0x00, 0xd7, 0x03, 0x02, 0x60, 0x02, 0x04, 0x00, 0x02, 0x05, 0xcd,
+   0xef, 0x0f, 0x04, 0x24, 0xc0, 0x00, 0x00, 0x01, 0x68, 0x06, 0xfa, 0x03,
+   0x04, 0x04, 0x84, 0x40, 0x00, 0x02, 0x62, 0xa0, 0x1c, 0x20, 0x04, 0x7c,
+   0x80, 0x40, 0x40, 0xc4, 0x78, 0xe8, 0x06, 0x40, 0x00, 0x08, 0x86, 0x00,
+   0x00, 0x06, 0xf4, 0x74, 0x03, 0x80, 0x06, 0x38, 0x80, 0x00, 0x00, 0x41,
+   0xa0, 0x88, 0x00, 0x00, 0x84, 0x48, 0x40, 0x03, 0x80, 0xa3, 0x14, 0x83,
+   0x01, 0x00, 0x03, 0x30, 0x02, 0x01, 0x80, 0x80, 0x70, 0x40, 0x01, 0x00,
+   0x06, 0x18, 0x06, 0x09, 0x50, 0x20, 0x35, 0x20, 0x00, 0x00, 0x01, 0x18,
+   0x12, 0x01, 0x00, 0x41, 0x1c, 0x80, 0x01, 0x00, 0x05, 0x1c, 0x01, 0x03,
+   0x00, 0x80, 0x17, 0x20, 0x01, 0x00, 0x43, 0x16, 0x03, 0x0b, 0x00, 0x51,
+   0x11, 0xa2, 0x02, 0x80, 0x42, 0x0d, 0x03, 0x03, 0x90, 0xab, 0x23, 0xa0,
+   0x03, 0x80, 0x80, 0x0d, 0x80, 0x00, 0x90, 0xc2, 0x09, 0x00, 0x07, 0x00,
+   0xb8, 0x88, 0x82, 0x04, 0x00, 0x61, 0x20, 0xa0, 0x05, 0x80, 0x70, 0x4c,
+   0xc0, 0x00, 0x80, 0x73, 0x21, 0x60, 0x37, 0x50, 0x0e, 0x0c, 0x00, 0x02,
+   0xc0, 0xa2, 0x28, 0x60, 0x47, 0x6f, 0x01, 0x60, 0x04, 0x00, 0x80, 0xc4,
+   0x08, 0x40, 0x0e, 0x60, 0x82, 0x02, 0x00, 0x01, 0x20, 0x34, 0xc0, 0x04,
+   0x2e, 0x26, 0x00, 0x3a, 0x48, 0x01, 0x44, 0xd6, 0x84, 0x00, 0x12, 0x00,
+   0x00, 0x20, 0x00, 0x20, 0x80, 0xe8, 0x09, 0x01, 0x74, 0x01, 0x01, 0x00,
+   0x20, 0x00, 0x10, 0x68, 0x02, 0x03, 0x58, 0x00, 0x00, 0x15, 0x00, 0x84,
+   0x00, 0xb0, 0x04, 0x05, 0xa0, 0x01, 0x40, 0x06, 0x18, 0x04, 0x00, 0x10,
+   0x10, 0x02, 0x50, 0x02, 0x20, 0x03, 0x04, 0x00, 0x00, 0xa0, 0x04, 0x34,
+   0x81, 0x09, 0x30, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x0f, 0x40, 0x01, 0x11,
+   0x02, 0x08, 0x00, 0x01, 0x08, 0x00, 0x83, 0x68, 0x03, 0xa5, 0x03, 0x00,
+   0x04, 0x80, 0x00, 0x10, 0x00, 0x60, 0x3c, 0x7c, 0x00, 0x00, 0x02, 0x00,
+   0x10, 0x80, 0x00, 0xc0, 0x91, 0x5d, 0x06, 0x00, 0x48, 0x00, 0x48, 0x50,
+   0x06, 0x04, 0x01, 0x80, 0x3f, 0x00, 0x05, 0x08, 0x00, 0x00, 0x02, 0x00,
+   0x2f, 0x00, 0xe8, 0x0f, 0x02, 0x02, 0x00, 0x00, 0x82, 0x00, 0x24, 0x00,
+   0x00, 0xbc, 0x02, 0x00, 0x00, 0x80, 0x98, 0x00, 0x60, 0x0a, 0x00, 0x28,
+   0x00, 0x00, 0x00, 0x10, 0x60, 0x20, 0xc1, 0xe5, 0x06, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x48, 0x00, 0xa0, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00,
+   0x80, 0x05, 0x00, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x42, 0x01, 0x25,
+   0x00, 0x58, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x40,
+   0x30, 0x09, 0x02, 0x00, 0x00, 0x00, 0x00, 0x68, 0x02, 0x00, 0x0c, 0x01,
+   0x20, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1d, 0x71, 0x21, 0x00, 0x00, 0x00,
+   0x00, 0x80, 0x00, 0xa0, 0xe0, 0x1b, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x40, 0xb0, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x80, 0x02, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x60,
+   0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x58, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x08, 0xc8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x14, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x00, 0x00,
+   0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40, 0x00, 0x80, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x04, 0xa0, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x01,
+   0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x3f, 0xca,
+   0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0xe1, 0xa0, 0x01, 0x84, 0x2d, 0x00,
+   0x40, 0x00, 0x00, 0x10, 0x00, 0x18, 0x00, 0x80, 0x64, 0x60, 0x01, 0x00,
+   0x00, 0x00, 0x02, 0x67, 0x1a, 0x00, 0xc8, 0x00, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x41, 0xa9, 0x00, 0x80, 0x01, 0x04, 0x00, 0x00, 0x00, 0xc0, 0x28,
+   0x90, 0x04, 0x80, 0x07, 0x00, 0x00, 0x40, 0x00, 0x14, 0x40, 0x04, 0x02,
+   0x00, 0x08, 0x12, 0x00, 0x00, 0x00, 0xe8, 0x1c, 0x80, 0x44, 0x00, 0x10,
+   0x80, 0x00, 0x00, 0x20, 0x0d, 0x53, 0x51, 0x1e, 0x00, 0x68, 0x04, 0x00,
+   0x00, 0x00, 0x16, 0xc9, 0x16, 0x00, 0x01, 0xe0, 0x0a, 0x01, 0x00, 0x00,
+   0x0e, 0x40, 0x40, 0xf4, 0x04, 0xb0, 0x81, 0x00, 0x00, 0x80, 0x02, 0x00,
+   0x61, 0x1f, 0x00, 0x20, 0x03, 0x00, 0x00, 0x00, 0x80, 0x00, 0xb2, 0x7f,
+   0x50, 0xc0, 0x07, 0x00, 0x00, 0x40, 0x00, 0x18, 0xa5, 0x01, 0x17, 0x42,
+   0x04, 0x00, 0x20, 0x00, 0x81, 0x60, 0x00, 0xc4, 0x03, 0x80, 0x0a, 0x01,
+   0x00, 0x10, 0x80, 0x32, 0x00, 0x81, 0x48, 0x81, 0x13, 0x50, 0x00, 0x20,
+   0xe0, 0x4a, 0x00, 0x10, 0x10, 0x02, 0x1b, 0x00, 0x00, 0x08, 0x68, 0x27,
+   0x00, 0x10, 0xc1, 0x82, 0x1b, 0x20, 0x00, 0x04, 0x08, 0x03, 0x00, 0x40,
+   0x46, 0x00, 0x03, 0x00, 0x00, 0x08, 0x94, 0x12, 0x80, 0x00, 0x03, 0x03,
+   0x73, 0x80, 0x00, 0x00, 0x20, 0x04, 0x20, 0x0c, 0x0f, 0x81, 0x43, 0x80,
+   0x00, 0x8c, 0x85, 0x39, 0x5f, 0x0a, 0x92, 0x42, 0x21, 0x00, 0x00, 0x02,
+   0xf0, 0x00, 0xfe, 0x07, 0x06, 0x84, 0xa1, 0x22, 0x00, 0x87, 0xe8, 0x40,
+   0xf5, 0x0f, 0x0c, 0x80, 0x80, 0x80, 0xa0, 0x41, 0xc1, 0xd9, 0xf9, 0x1f,
+   0x04, 0x80, 0x83, 0x00, 0x00, 0x00, 0x29, 0xe9, 0x0c, 0x00, 0x08, 0x10,
+   0x01, 0x00, 0x00, 0x21, 0x61, 0x16, 0x07, 0x40, 0x08, 0xc0, 0x8b, 0x01,
+   0x00, 0x40, 0x74, 0x00, 0x01, 0x80, 0x08, 0xc8, 0x44, 0x21, 0x10, 0x81,
+   0x1d, 0x40, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x90, 0x5b, 0x17, 0x20,
+   0x01, 0x00, 0x0e, 0x78, 0x88, 0x09, 0x80, 0xa3, 0x11, 0x80, 0x00, 0x00,
+   0x04, 0x88, 0x00, 0x01, 0xc0, 0xe0, 0x01, 0xa2, 0x01, 0x00, 0x83, 0x38,
+   0x06, 0x01, 0xe0, 0x39, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x48, 0x80, 0x40,
+   0x40, 0xb1, 0x10, 0xd0, 0x01, 0x00, 0x01, 0x30, 0x80, 0x40, 0x10, 0x52,
+   0x10, 0x80, 0x01, 0x80, 0x07, 0x18, 0x42, 0x01, 0x10, 0x62, 0x14, 0xd0,
+   0x03, 0xc0, 0x01, 0x1c, 0x06, 0x83, 0xa0, 0x0d, 0x04, 0xb0, 0x02, 0x40,
+   0x21, 0x0f, 0x01, 0x01, 0x04, 0x32, 0x10, 0xb0, 0x1b, 0x00, 0xa0, 0x8a,
+   0x80, 0x04, 0x00, 0x7a, 0x21, 0x91, 0x11, 0x40, 0xcc, 0x86, 0x81, 0x01,
+   0x00, 0x9c, 0x22, 0x80, 0xc3, 0x17, 0x5c, 0x86, 0x81, 0x01, 0x00, 0x2c,
+   0x40, 0x80, 0x0b, 0x98, 0x17, 0x07, 0x80, 0x05, 0x01, 0x04, 0xc1, 0x80,
+   0x84, 0x19, 0x00, 0x93, 0x40, 0x00, 0x40, 0x94, 0xa2, 0x00, 0x0d, 0x88,
+   0x00, 0x02, 0x20, 0x00, 0x00, 0xf0, 0x40, 0x00, 0x4f, 0x00, 0xa0, 0x18,
+   0x30, 0x01, 0x00, 0x62, 0x81, 0x02, 0x04, 0x20, 0x80, 0x00, 0x81, 0x00,
+   0x10, 0x00, 0x10, 0x24, 0x3a, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x09,
+   0x00, 0x2d, 0x40, 0x00, 0x00, 0x04, 0x41, 0x00, 0x00, 0x64, 0x00, 0x6c,
+   0x30, 0x01, 0xa0, 0x00, 0x28, 0x00, 0x00, 0x20, 0x00, 0x46, 0x20, 0x00,
+   0xcc, 0x02, 0x00, 0x00, 0x00, 0x20, 0x40, 0xdc, 0x53, 0x20, 0x66, 0x00,
+   0x04, 0x04, 0x80, 0x09, 0x08, 0x10, 0xc9, 0x3b, 0x00, 0x00, 0x03, 0x20,
+   0x00, 0x80, 0x09, 0x30, 0xd8, 0x07, 0x80, 0x40, 0x80, 0x00, 0x10, 0x40,
+   0x07, 0xe0, 0x02, 0x25, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01,
+   0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0c, 0x08, 0x03, 0xe0,
+   0x03, 0x40, 0x10, 0x00, 0x04, 0x00, 0x28, 0x00, 0x56, 0x40, 0x03, 0x20,
+   0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x2d, 0x00, 0x7c, 0x48, 0x00, 0x08,
+   0x00, 0x00, 0xe8, 0x00, 0x00, 0x17, 0x60, 0x20, 0x00, 0x00, 0x00, 0x02,
+   0xa0, 0x08, 0x00, 0x20, 0xc0, 0x15, 0x40, 0x00, 0x80, 0x00, 0x00, 0x09,
+   0x60, 0x00, 0x00, 0x11, 0x10, 0x00, 0x00, 0x08, 0x80, 0x15, 0x00, 0x05,
+   0xc8, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x62, 0x00, 0x01, 0x0d, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x47, 0xd0, 0x00, 0x08, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0xee, 0x35, 0x24, 0x00, 0x20, 0x00, 0x00, 0x00,
+   0x04, 0x08, 0x01, 0x80, 0x04, 0x08, 0x04, 0x00, 0x00, 0x08, 0x00, 0x40,
+   0x04, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x20, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0x80, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00},
+  {0x00, 0x80, 0x01, 0x81, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x20, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02,
+   0x21, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x20, 0x00,
+   0x00, 0x00, 0xc4, 0xc0, 0x18, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
+   0x00, 0x78, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+   0xe0, 0x12, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x6e, 0x0d,
+   0x20, 0x24, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x11, 0x80, 0x02, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x1c, 0x82, 0x71, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0x00, 0x21, 0x06, 0x70, 0x04, 0x80, 0x04, 0x00, 0x00,
+   0x24, 0x0d, 0x0c, 0x04, 0x90, 0x08, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xf0,
+   0x01, 0x12, 0x00, 0x0d, 0x08, 0x00, 0x00, 0x00, 0xe0, 0x20, 0xca, 0x90,
+   0x00, 0x08, 0x04, 0x10, 0x20, 0x00, 0x50, 0x80, 0x28, 0x00, 0x00, 0x38,
+   0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0xec, 0x4a, 0x04, 0x30, 0x20, 0x09,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x02, 0xe0, 0x80, 0x40, 0x00, 0x00,
+   0x09, 0x08, 0x10, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x84,
+   0x80, 0x57, 0x12, 0x80, 0x41, 0x00, 0x00, 0x60, 0x00, 0x14, 0x77, 0xfd,
+   0x4d, 0x00, 0x02, 0x0a, 0x00, 0x24, 0x40, 0x96, 0x01, 0xba, 0x03, 0x00,
+   0x66, 0x00, 0x00, 0x20, 0x40, 0x79, 0x02, 0x80, 0x00, 0x00, 0x67, 0x00,
+   0x04, 0x40, 0x20, 0x38, 0x01, 0x28, 0xa8, 0x00, 0x0a, 0x00, 0x00, 0x68,
+   0x00, 0x14, 0x00, 0x00, 0xbe, 0x02, 0x1a, 0x04, 0x00, 0x1c, 0xac, 0x82,
+   0x00, 0x80, 0x04, 0x10, 0x3e, 0x00, 0x00, 0x15, 0x42, 0x56, 0x00, 0x40,
+   0x40, 0x02, 0x2a, 0x40, 0x00, 0x00, 0xa3, 0xe3, 0x00, 0x04, 0x85, 0x08,
+   0x1a, 0x00, 0x00, 0x04, 0x82, 0x03, 0xbc, 0x01, 0x10, 0x13, 0x0c, 0x00,
+   0x20, 0x80, 0x92, 0x07, 0x79, 0x31, 0x1c, 0x09, 0x5c, 0x00, 0x20, 0x83,
+   0x44, 0x52, 0x55, 0x0e, 0x14, 0x04, 0xee, 0x40, 0x80, 0x27, 0xe9, 0xe5,
+   0xe3, 0x1f, 0x2c, 0x04, 0x6c, 0x00, 0x00, 0xab, 0x7f, 0x08, 0xfd, 0x1f,
+   0x4c, 0x06, 0x0e, 0x00, 0xe0, 0x81, 0x29, 0x00, 0x0a, 0x7c, 0x18, 0x08,
+   0xa6, 0x81, 0x40, 0xe1, 0x13, 0x80, 0x03, 0x00, 0x10, 0x08, 0x87, 0x00,
+   0x51, 0x39, 0x01, 0x40, 0x02, 0x00, 0x00, 0x00, 0x81, 0x00, 0x10, 0xb2,
+   0x24, 0x02, 0x00, 0x80, 0x10, 0x00, 0x01, 0x01, 0x80, 0xf1, 0x10, 0xa0,
+   0x01, 0x80, 0x18, 0x20, 0x07, 0x05, 0xa0, 0x2d, 0x12, 0x50, 0x01, 0x00,
+   0x01, 0x00, 0x01, 0x41, 0x02, 0x05, 0x0a, 0x50, 0x01, 0x00, 0x0c, 0x88,
+   0x07, 0x00, 0x00, 0x1d, 0x02, 0xc8, 0x01, 0x00, 0x05, 0x48, 0x14, 0x00,
+   0x08, 0xbe, 0x08, 0xe8, 0x01, 0x00, 0x03, 0x38, 0x40, 0x01, 0x00, 0x0b,
+   0x11, 0x58, 0x01, 0x80, 0x83, 0x48, 0x00, 0x01, 0x2c, 0x00, 0x90, 0xe8,
+   0x01, 0x80, 0x00, 0x18, 0x80, 0x20, 0x00, 0x43, 0x10, 0xc8, 0x06, 0xc0,
+   0x02, 0x20, 0x82, 0x08, 0x00, 0x2c, 0x30, 0xc0, 0x00, 0xa0, 0x00, 0x38,
+   0x84, 0x00, 0x84, 0x38, 0x10, 0xe0, 0x09, 0x20, 0x10, 0x0e, 0xc0, 0x00,
+   0x00, 0x78, 0x30, 0x20, 0xe2, 0x12, 0x10, 0x07, 0x41, 0x40, 0x40, 0x02,
+   0x00, 0x40, 0x81, 0x0e, 0xa3, 0x87, 0x21, 0x20, 0x00, 0x01, 0xa2, 0xc0,
+   0x63, 0x66, 0xb6, 0xc1, 0xc0, 0x00, 0x10, 0x0c, 0x80, 0x80, 0x0a, 0x96,
+   0x96, 0x61, 0x44, 0x20, 0x00, 0x04, 0x20, 0x45, 0x01, 0x20, 0x80, 0x60,
+   0x60, 0x00, 0x88, 0x04, 0x80, 0x05, 0x07, 0x00, 0xc0, 0x48, 0x20, 0x00,
+   0x00, 0x08, 0x88, 0x06, 0x08, 0x08, 0xc4, 0x2c, 0x60, 0x00, 0x00, 0x90,
+   0x80, 0x09, 0x06, 0x00, 0x10, 0x01, 0xb0, 0x00, 0x28, 0xe4, 0x00, 0x33,
+   0x12, 0x00, 0x10, 0x03, 0x28, 0x00, 0x90, 0x20, 0x00, 0x71, 0x22, 0x00,
+   0xc0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x86, 0x08, 0x80, 0x84, 0x20,
+   0x24, 0x00, 0x80, 0xc2, 0x10, 0x2e, 0xbd, 0x44, 0x08, 0x00, 0x10, 0x00,
+   0x00, 0x40, 0x81, 0x10, 0x78, 0x63, 0x2e, 0x20, 0x00, 0x00, 0x14, 0x80,
+   0x01, 0x10, 0x40, 0x00, 0x04, 0x00, 0x05, 0x00, 0x40, 0x00, 0x0e, 0x30,
+   0x40, 0x03, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x01, 0xe8, 0x80, 0x03,
+   0x08, 0x08, 0x00, 0x00, 0x08, 0x00, 0x4c, 0x20, 0x01, 0x0e, 0x00, 0x14,
+   0x00, 0x00, 0x00, 0x10, 0x48, 0x00, 0x08, 0x1a, 0x00, 0x08, 0x04, 0x02,
+   0x00, 0x00, 0x18, 0x00, 0x30, 0x30, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
+   0x84, 0x01, 0xc1, 0xc1, 0x01, 0x03, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
+   0x0a, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x10, 0x80, 0x1f, 0x34, 0x00,
+   0x47, 0x02, 0x00, 0x00, 0x00, 0x10, 0x20, 0x3c, 0x01, 0x00, 0xd5, 0x11,
+   0x40, 0x00, 0x00, 0x00, 0x00, 0xc5, 0x07, 0x34, 0x42, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x40, 0x10, 0xe8, 0x23, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x1c, 0x49, 0x00, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+   0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x80,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x03, 0x30, 0x08, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x30, 0x00, 0xc4, 0x00, 0x00, 0x00},
+  {0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x2f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x20, 0xc8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xa0, 0x18, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x80, 0x20, 0xca, 0xfa,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x05, 0x07, 0x00,
+   0x00, 0x00, 0x00, 0x40, 0x00, 0x18, 0x61, 0x02, 0x00, 0x0a, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x5e, 0x86, 0x58, 0x20, 0x0c, 0x20, 0x00, 0x00, 0x00,
+   0x80, 0x0c, 0x3c, 0xc1, 0x60, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x40, 0xc0, 0x00, 0x44, 0x08, 0x00, 0x00, 0x00, 0x10, 0x01, 0x10, 0x19,
+   0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x80, 0x13, 0x03, 0x82,
+   0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x28, 0x1c, 0x90, 0x00, 0x00,
+   0x00, 0x00, 0x02, 0x40, 0x00, 0xa0, 0x00, 0xb0, 0x00, 0x08, 0x00, 0x00,
+   0x00, 0x54, 0x09, 0x80, 0x04, 0x80, 0x01, 0x00, 0x00, 0xe4, 0x03, 0xb7,
+   0x31, 0x40, 0x6c, 0x80, 0x01, 0x00, 0x00, 0xe8, 0x00, 0x84, 0x9e, 0x7e,
+   0x30, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x60, 0xe1, 0x13, 0xc0, 0x03, 0x00,
+   0x83, 0x00, 0x00, 0x20, 0x10, 0x84, 0x18, 0xd0, 0x6f, 0x01, 0x0c, 0x02,
+   0x84, 0x00, 0x00, 0x12, 0x04, 0x80, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x0c,
+   0x12, 0x9e, 0x00, 0x40, 0x11, 0x00, 0x18, 0x84, 0x00, 0x1e, 0x00, 0x9e,
+   0x03, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0xa8, 0x10, 0x0f, 0x01, 0x00,
+   0xf0, 0x05, 0x30, 0x02, 0x84, 0x87, 0x25, 0x09, 0x50, 0x00, 0xb2, 0x16,
+   0x38, 0x19, 0xa0, 0x85, 0xbc, 0xc3, 0xe5, 0x12, 0x00, 0x00, 0xb8, 0x01,
+   0x20, 0xc0, 0xd7, 0x11, 0xdf, 0x05, 0x14, 0x41, 0x68, 0x42, 0x0c, 0xe4,
+   0x47, 0x00, 0x8e, 0x51, 0x10, 0x02, 0x58, 0x00, 0x40, 0x63, 0x00, 0x00,
+   0xf8, 0x1f, 0x70, 0x24, 0xf8, 0x70, 0x00, 0x68, 0x69, 0x00, 0xb4, 0x3f,
+   0x10, 0x2c, 0x88, 0x00, 0x00, 0x46, 0x00, 0xc0, 0x05, 0x38, 0x70, 0x20,
+   0xa0, 0x00, 0x00, 0x19, 0x14, 0x00, 0x06, 0xf0, 0x18, 0x08, 0xb8, 0x00,
+   0x00, 0x3e, 0x1a, 0x20, 0x01, 0x00, 0x90, 0x08, 0xbc, 0x00, 0x30, 0xaf,
+   0x00, 0x30, 0x01, 0x00, 0x30, 0x04, 0x98, 0x00, 0x00, 0x28, 0x08, 0x40,
+   0x01, 0x80, 0x10, 0x08, 0xdc, 0x00, 0x01, 0x01, 0x18, 0xc8, 0x01, 0x00,
+   0x30, 0x10, 0x0c, 0x80, 0x42, 0x04, 0x08, 0xec, 0x00, 0x00, 0x10, 0x00,
+   0xc5, 0x21, 0x00, 0x0c, 0x50, 0xec, 0x01, 0x00, 0x09, 0x00, 0x85, 0x01,
+   0x20, 0x1c, 0x08, 0xec, 0x00, 0x00, 0x06, 0x20, 0x81, 0x00, 0x40, 0x21,
+   0x1c, 0xe0, 0x00, 0x80, 0x05, 0x28, 0x47, 0x00, 0x00, 0x00, 0x18, 0x60,
+   0x03, 0x00, 0x01, 0xc8, 0x01, 0x01, 0x04, 0x02, 0x00, 0xf0, 0x00, 0x40,
+   0x03, 0xc4, 0x83, 0x04, 0x40, 0x01, 0x08, 0x40, 0x00, 0x60, 0x40, 0x1c,
+   0x88, 0x40, 0x00, 0x01, 0x20, 0xd0, 0x19, 0x58, 0x00, 0x34, 0x00, 0x80,
+   0x00, 0x02, 0x08, 0x70, 0xa0, 0x00, 0x00, 0x0e, 0xe0, 0x00, 0x0c, 0x06,
+   0x70, 0xa1, 0x88, 0x06, 0x00, 0x00, 0x82, 0x00, 0x10, 0x25, 0xb1, 0xf1,
+   0x92, 0x41, 0x04, 0x9f, 0x21, 0x00, 0x00, 0x1c, 0xb0, 0x91, 0xc0, 0xdd,
+   0xe0, 0x03, 0x61, 0x10, 0x00, 0x04, 0x60, 0x01, 0x01, 0xf4, 0xec, 0x01,
+   0x20, 0x82, 0x02, 0x08, 0x60, 0x43, 0x01, 0x04, 0xe3, 0x20, 0x10, 0x40,
+   0x00, 0x08, 0x20, 0xce, 0x00, 0x00, 0x20, 0x78, 0x14, 0x00, 0x00, 0x28,
+   0xc2, 0x42, 0x02, 0x00, 0x38, 0x08, 0x10, 0x08, 0x04, 0x18, 0xc8, 0x90,
+   0x00, 0x80, 0x18, 0x8c, 0x38, 0x08, 0x80, 0xa0, 0x08, 0xb2, 0x00, 0x00,
+   0x02, 0x09, 0x08, 0x00, 0x00, 0xb0, 0x00, 0xc1, 0x07, 0x00, 0x01, 0x04,
+   0x04, 0x00, 0x00, 0x40, 0x00, 0x83, 0x5f, 0x00, 0x64, 0x00, 0x26, 0x00,
+   0x00, 0x40, 0x80, 0x03, 0x34, 0x46, 0x18, 0x00, 0x06, 0x00, 0x00, 0x60,
+   0x02, 0x0f, 0x04, 0xc0, 0x08, 0x82, 0x16, 0x00, 0x00, 0x60, 0x01, 0x38,
+   0x3c, 0xe0, 0x02, 0x60, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x30, 0x00,
+   0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x08, 0xc0, 0x60, 0x00, 0x00, 0x80,
+   0x00, 0x00, 0x00, 0x00, 0x1c, 0x88, 0xc1, 0x40, 0x00, 0x28, 0x00, 0x00,
+   0x00, 0x80, 0x7c, 0x08, 0xc6, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00,
+   0xf0, 0x20, 0x04, 0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x10, 0x15, 0x84,
+   0x00, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0e, 0x00, 0x0c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x0c, 0x0c, 0x20,
+   0x01, 0x00, 0x00, 0x00, 0x10, 0x80, 0xd7, 0x14, 0x01, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x10, 0x13, 0xc0, 0x5e, 0x0f, 0x02, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x23, 0x22, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x80, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x20, 0x00, 0x10, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00},
+  {0x00, 0x00, 0x00, 0x20, 0x20, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x18, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0x10, 0x40, 0x00, 0x28, 0xc0, 0x12, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x02, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x88, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0xfb,
+   0x46, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x50, 0x65, 0x80, 0x0e, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xc5, 0xc8, 0x38, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x08, 0x06, 0x80, 0xc1, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00,
+   0xc8, 0x24, 0x80, 0x25, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+   0x00, 0x08, 0x19, 0x00, 0x00, 0x00, 0x00, 0x40, 0x48, 0x00, 0x10, 0x06,
+   0x18, 0x44, 0x01, 0x02, 0x00, 0x80, 0x2e, 0x00, 0x10, 0x10, 0x19, 0x8c,
+   0x01, 0x00, 0x00, 0x00, 0x08, 0x40, 0x0c, 0x78, 0x02, 0x40, 0x00, 0x00,
+   0x00, 0x08, 0x01, 0x12, 0x97, 0xc0, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x66, 0x88, 0x11, 0x06, 0xc0, 0x0d, 0x00, 0x00, 0xe0, 0xc0, 0x00,
+   0x4c, 0x03, 0x4a, 0x81, 0x80, 0x00, 0x20, 0xc0, 0x90, 0x00, 0x5c, 0x3a,
+   0x40, 0x00, 0x0d, 0x00, 0x00, 0x7c, 0xc1, 0xb8, 0x84, 0xa1, 0x43, 0x00,
+   0x08, 0x20, 0x00, 0x34, 0x01, 0xf2, 0xa4, 0x00, 0x8a, 0x05, 0x0c, 0x20,
+   0x20, 0x11, 0x3e, 0x70, 0x00, 0x80, 0x3c, 0x01, 0x08, 0x00, 0x00, 0x91,
+   0xe9, 0x5d, 0x1c, 0x00, 0x7c, 0x01, 0x08, 0x00, 0x00, 0x8c, 0xdf, 0x6f,
+   0x10, 0x00, 0x60, 0x03, 0x18, 0x08, 0x02, 0x80, 0x19, 0x0f, 0x44, 0x00,
+   0xea, 0x0a, 0x18, 0x00, 0x20, 0xbc, 0x85, 0x41, 0xd4, 0x01, 0x80, 0x10,
+   0x30, 0x04, 0x01, 0x94, 0x21, 0x00, 0x9f, 0x0b, 0x00, 0x00, 0x20, 0x00,
+   0x10, 0x7c, 0x80, 0x00, 0x38, 0x5b, 0x88, 0x05, 0x20, 0x08, 0x01, 0x7e,
+   0x48, 0x00, 0x00, 0x0e, 0xc0, 0x12, 0x40, 0xc0, 0x00, 0x52, 0x25, 0x08,
+   0xea, 0xcb, 0x00, 0x08, 0x50, 0x10, 0x04, 0x53, 0x00, 0x00, 0x0a, 0x7e,
+   0x41, 0x04, 0xc0, 0x08, 0x40, 0x4c, 0x01, 0x40, 0x0c, 0x78, 0x80, 0x04,
+   0x70, 0x00, 0x21, 0x44, 0x10, 0x20, 0x02, 0x70, 0xe0, 0x04, 0x20, 0x26,
+   0x00, 0x3c, 0x10, 0x80, 0x03, 0xe0, 0x30, 0x58, 0xc0, 0x86, 0x40, 0x91,
+   0x10, 0xc8, 0x00, 0x80, 0xf0, 0x50, 0xb0, 0x04, 0x02, 0x00, 0x08, 0xfc,
+   0x01, 0x00, 0xa0, 0x60, 0xc0, 0x00, 0x20, 0x03, 0x1c, 0xec, 0x00, 0x00,
+   0xb0, 0x18, 0x50, 0x21, 0xa0, 0x02, 0x14, 0xf4, 0x00, 0x00, 0x30, 0x1c,
+   0x70, 0x20, 0x00, 0x80, 0x00, 0x70, 0x00, 0x80, 0x00, 0x00, 0xb0, 0x00,
+   0x01, 0x01, 0x04, 0x30, 0x01, 0x80, 0x10, 0x08, 0xb8, 0x00, 0x08, 0x03,
+   0x10, 0x78, 0x03, 0x00, 0x08, 0x08, 0xdc, 0x00, 0x40, 0x08, 0x14, 0x28,
+   0x00, 0x00, 0x02, 0x00, 0xce, 0x00, 0x04, 0x8e, 0x18, 0x60, 0x00, 0x80,
+   0x02, 0x00, 0x06, 0x00, 0x10, 0x01, 0xdc, 0x38, 0x04, 0xa0, 0x00, 0x90,
+   0xa3, 0x20, 0x00, 0x01, 0x6c, 0x60, 0x08, 0x14, 0x00, 0x94, 0x80, 0x10,
+   0x01, 0x02, 0x48, 0x3c, 0x72, 0x76, 0x00, 0x82, 0x41, 0x00, 0x01, 0x01,
+   0x58, 0xa0, 0x84, 0x11, 0x10, 0xf2, 0x20, 0x00, 0x00, 0x45, 0xcc, 0x60,
+   0x60, 0x00, 0x00, 0x97, 0x81, 0x00, 0x80, 0x00, 0x88, 0x19, 0x30, 0x02,
+   0x81, 0x09, 0x42, 0x01, 0x00, 0x16, 0x19, 0x11, 0x00, 0x96, 0x81, 0x02,
+   0x22, 0x41, 0x00, 0x00, 0x00, 0x08, 0x80, 0x35, 0xe0, 0x00, 0x00, 0x20,
+   0x00, 0x08, 0x60, 0x52, 0x20, 0xa0, 0x7f, 0xa3, 0x08, 0x20, 0x00, 0x0e,
+   0x30, 0x58, 0x00, 0x00, 0x3d, 0x60, 0x30, 0x20, 0x00, 0x52, 0x28, 0x38,
+   0x00, 0x00, 0x1e, 0x00, 0x0c, 0x00, 0x00, 0x12, 0x28, 0x70, 0x00, 0x10,
+   0x07, 0x04, 0x0c, 0x00, 0x08, 0x60, 0xf0, 0x40, 0x01, 0x80, 0x83, 0x0f,
+   0x46, 0x1a, 0x00, 0xc0, 0x80, 0x02, 0x06, 0x20, 0xc1, 0x81, 0x03, 0x00,
+   0x00, 0x00, 0x00, 0x60, 0xf0, 0x01, 0x98, 0x18, 0x00, 0x08, 0x00, 0xe0,
+   0x00, 0xc0, 0x21, 0x44, 0x02, 0x00, 0x03, 0x04, 0x00, 0x40, 0x47, 0x84,
+   0x01, 0x8f, 0x00, 0x80, 0x82, 0x00, 0x10, 0xa8, 0xc3, 0x08, 0x03, 0x86,
+   0x00, 0x40, 0x80, 0x00, 0x00, 0x80, 0x00, 0x11, 0x06, 0x00, 0x10, 0x60,
+   0x02, 0x00, 0x00, 0x00, 0xb9, 0x20, 0x06, 0x00, 0x00, 0x7c, 0x40, 0x00,
+   0x00, 0x00, 0x70, 0x02, 0x04, 0x02, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x40,
+   0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00,
+   0x10, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x0c, 0x30, 0x80,
+   0x12, 0x05, 0x01, 0x00, 0x00, 0x02, 0xc0, 0x70, 0x30, 0x00, 0x86, 0x80,
+   0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x53, 0xb0, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xb0, 0x40, 0x7c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x00, 0x40, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x03,
+   0x01, 0x0a, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x40, 0x24, 0x00, 0x00,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x41, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x20, 0x82, 0x00, 0x01, 0x00, 0x00},
+  {0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x04,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x80, 0x00, 0x0f, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x54, 0x23,
+   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa0, 0x60, 0xcb, 0x02, 0x30,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x10, 0x18, 0xc0, 0x04, 0x00,
+   0x00, 0x00, 0xf1, 0x0f, 0x00, 0x30, 0xe0, 0x01, 0x04, 0x00, 0x00, 0x80,
+   0x81, 0x05, 0x00, 0x30, 0xb8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
+   0x00, 0x80, 0x14, 0x86, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x00, 0x08, 0x82,
+   0x25, 0x28, 0x00, 0x00, 0x00, 0x40, 0x0e, 0x20, 0x8e, 0x80, 0x60, 0x28,
+   0x00, 0x00, 0x00, 0xc0, 0x0f, 0x1c, 0x74, 0x00, 0x03, 0x01, 0x08, 0x00,
+   0x00, 0x48, 0x11, 0x09, 0x05, 0x89, 0x13, 0x02, 0x00, 0x00, 0x10, 0x88,
+   0x21, 0x05, 0xd4, 0x08, 0xa4, 0x43, 0x00, 0x00, 0x00, 0xa8, 0x60, 0x05,
+   0xc1, 0x17, 0x0d, 0x40, 0x00, 0x00, 0x0a, 0x60, 0x3c, 0x21, 0x6f, 0x39,
+   0x20, 0x06, 0x10, 0x00, 0x00, 0x00, 0xfc, 0x4b, 0x2f, 0x88, 0xb1, 0x00,
+   0x04, 0x00, 0x08, 0xf0, 0xc9, 0xee, 0x23, 0x05, 0xc5, 0x0c, 0x04, 0x00,
+   0x00, 0x01, 0x1c, 0x78, 0x62, 0x00, 0x3c, 0x04, 0x0e, 0x01, 0x10, 0xf8,
+   0x05, 0x4c, 0xc0, 0x00, 0x10, 0x02, 0x44, 0x00, 0x00, 0xc0, 0x01, 0x00,
+   0x09, 0x00, 0x64, 0x06, 0x08, 0x20, 0x00, 0x4d, 0x21, 0x00, 0x12, 0x00,
+   0xf0, 0x3d, 0x60, 0x00, 0x00, 0x11, 0x95, 0x01, 0x78, 0x02, 0xe0, 0x00,
+   0x48, 0x00, 0x00, 0x18, 0x44, 0x00, 0x60, 0x0e, 0x08, 0x07, 0x20, 0x00,
+   0x8c, 0x18, 0x00, 0x00, 0xe0, 0x3c, 0xa0, 0x0b, 0x20, 0x00, 0x08, 0x7a,
+   0x20, 0x00, 0x6a, 0x28, 0x01, 0x22, 0x20, 0x00, 0x00, 0x60, 0x21, 0x80,
+   0x91, 0x2f, 0x20, 0x40, 0x60, 0x00, 0x40, 0x03, 0x00, 0xc0, 0x10, 0x1c,
+   0x10, 0x07, 0x60, 0x20, 0x84, 0x01, 0x98, 0x10, 0x05, 0xfc, 0x03, 0x0d,
+   0x40, 0x08, 0x00, 0x00, 0x18, 0x98, 0x02, 0xf0, 0x22, 0x20, 0x80, 0x18,
+   0x08, 0x81, 0x1c, 0xf8, 0x03, 0xe0, 0xc0, 0x00, 0x40, 0x00, 0x40, 0x01,
+   0x00, 0xec, 0x01, 0xc0, 0x00, 0x48, 0xa0, 0x30, 0x00, 0x01, 0x00, 0xf0,
+   0x01, 0x80, 0xe1, 0x05, 0x00, 0x00, 0x00, 0x0f, 0x0a, 0xf0, 0x00, 0x00,
+   0xa0, 0x20, 0x81, 0x20, 0x00, 0x41, 0x10, 0x38, 0x00, 0x00, 0xb0, 0x18,
+   0xe0, 0x08, 0x80, 0x01, 0x1c, 0xb0, 0x01, 0x80, 0xb0, 0x10, 0xa0, 0x04,
+   0x80, 0x01, 0x0c, 0x14, 0x01, 0x80, 0xb0, 0x60, 0x80, 0x06, 0x80, 0x00,
+   0x36, 0x34, 0x01, 0x80, 0x10, 0x08, 0xb0, 0x24, 0x90, 0x03, 0x14, 0x1c,
+   0x00, 0x80, 0x18, 0x0a, 0xe8, 0x04, 0x00, 0x31, 0x06, 0x16, 0x02, 0x00,
+   0x0c, 0x00, 0x80, 0x81, 0x80, 0x05, 0x12, 0x04, 0x04, 0x40, 0x01, 0x00,
+   0xb8, 0x00, 0x00, 0x44, 0x26, 0x2c, 0x15, 0xf8, 0x01, 0x04, 0x5e, 0x70,
+   0x00, 0x03, 0x76, 0x12, 0x00, 0x4f, 0x00, 0x00, 0x5e, 0x00, 0x80, 0x03,
+   0x00, 0x04, 0x78, 0x1c, 0x00, 0x40, 0x67, 0x00, 0x41, 0x01, 0x58, 0x03,
+   0x1c, 0x00, 0x00, 0x44, 0x63, 0x40, 0x00, 0x0e, 0xc4, 0x00, 0x20, 0x00,
+   0x84, 0xe1, 0x20, 0x00, 0x00, 0x04, 0x05, 0x06, 0xa0, 0x02, 0xc0, 0x60,
+   0x20, 0x00, 0x00, 0x08, 0x04, 0x1b, 0xa4, 0x67, 0xc0, 0x5c, 0x30, 0x00,
+   0x00, 0x08, 0x1e, 0x0f, 0x00, 0x06, 0x70, 0x29, 0x18, 0x14, 0x80, 0x0c,
+   0x00, 0x0e, 0x00, 0xf4, 0x48, 0x23, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x1c,
+   0x00, 0xa0, 0x5f, 0x60, 0x10, 0x20, 0x80, 0x13, 0x00, 0x60, 0x00, 0xc0,
+   0x4e, 0x00, 0x0c, 0x10, 0x00, 0x38, 0x24, 0x04, 0x00, 0xc1, 0x03, 0x12,
+   0x20, 0x00, 0x00, 0x20, 0x44, 0x18, 0x06, 0x7a, 0x00, 0x04, 0x03, 0x40,
+   0x00, 0x10, 0xc0, 0x18, 0x06, 0x13, 0xc0, 0x00, 0x02, 0x09, 0x00, 0x80,
+   0x09, 0x18, 0x00, 0x00, 0xf8, 0x80, 0x00, 0x00, 0x00, 0x02, 0x02, 0x39,
+   0x30, 0x94, 0x1d, 0xc0, 0x00, 0x02, 0x00, 0x00, 0x00, 0x30, 0x70, 0x2c,
+   0x88, 0x20, 0x04, 0x00, 0x00, 0x30, 0x04, 0x20, 0x00, 0x05, 0x82, 0x10,
+   0x30, 0x00, 0x00, 0x00, 0x11, 0x60, 0x10, 0x00, 0x00, 0x18, 0x80, 0x00,
+   0x00, 0x00, 0x72, 0x40, 0x00, 0x80, 0x00, 0x1c, 0x80, 0x00, 0x00, 0x40,
+   0xc0, 0x81, 0x00, 0x00, 0x00, 0x03, 0x60, 0x00, 0x00, 0x00, 0x22, 0xc4,
+   0x01, 0x40, 0xa8, 0x03, 0x04, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x00, 0x00,
+   0x98, 0x11, 0x00, 0x00, 0x00, 0x80, 0x82, 0x41, 0x01, 0x0a, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x80, 0x00, 0xc0, 0x00, 0x6a, 0x51, 0x00, 0x00, 0x00,
+   0x40, 0x00, 0x00, 0x04, 0x8a, 0x02, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x80, 0x88, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+   0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x88, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x86, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x40, 0x00,
+   0x0e, 0x01, 0x41, 0x00, 0x43, 0x00, 0x00, 0x00, 0x20, 0x7c, 0x22, 0x70,
+   0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x98, 0x0e, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0xa4, 0x01, 0x81, 0x0a, 0x06, 0x01, 0x00,
+   0x00, 0x40, 0xda, 0x01, 0x00, 0x00, 0xb2, 0x00, 0x40, 0x00, 0x00, 0x11,
+   0xfd, 0x01, 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x00, 0x80, 0x30, 0x80,
+   0x04, 0x00, 0x06, 0x05, 0x02, 0x00, 0x80, 0x00, 0x10, 0x27, 0xe5, 0x01,
+   0x54, 0x14, 0x28, 0x00, 0x00, 0x10, 0x1e, 0x80, 0x00, 0x60, 0x10, 0x3b,
+   0x18, 0x00, 0x80, 0x04, 0x44, 0x86, 0x50, 0x1f, 0xd4, 0x22, 0x01, 0x00,
+   0x00, 0x10, 0xeb, 0x53, 0x44, 0x00, 0x10, 0xa0, 0x00, 0x00, 0x0c, 0x00,
+   0x98, 0x1e, 0x12, 0x1d, 0x20, 0x8a, 0x08, 0x00, 0x20, 0x80, 0x6f, 0xee,
+   0x78, 0x8c, 0x38, 0x80, 0x02, 0x00, 0x00, 0x48, 0x0f, 0x61, 0xff, 0xbe,
+   0x41, 0x39, 0x02, 0x00, 0x40, 0x2a, 0x0a, 0xc0, 0x33, 0x81, 0x09, 0x0a,
+   0x00, 0x00, 0x50, 0x80, 0x08, 0x28, 0x1b, 0x48, 0x80, 0x10, 0x80, 0x00,
+   0x00, 0x44, 0xac, 0x11, 0x00, 0x23, 0x0c, 0x00, 0x04, 0x00, 0x04, 0xe8,
+   0x14, 0x06, 0x08, 0x07, 0x08, 0x31, 0x4a, 0x00, 0x84, 0xc0, 0x01, 0x02,
+   0xc8, 0x00, 0x60, 0x06, 0x00, 0x00, 0x08, 0x8c, 0x84, 0x80, 0x20, 0x00,
+   0xe0, 0x60, 0x80, 0x01, 0x00, 0x0a, 0x80, 0x00, 0xc0, 0x0b, 0xa0, 0x50,
+   0x20, 0x00, 0x10, 0x00, 0x80, 0x00, 0x80, 0x19, 0x80, 0x19, 0x30, 0x00,
+   0x08, 0x02, 0x60, 0x00, 0x08, 0x33, 0xc0, 0x17, 0x78, 0x00, 0x80, 0x02,
+   0x31, 0x02, 0xd3, 0x39, 0x20, 0xb3, 0x00, 0x05, 0x11, 0x02, 0x10, 0xa0,
+   0x68, 0xb7, 0x00, 0x0e, 0xa0, 0x00, 0x00, 0x0a, 0x28, 0x30, 0x0b, 0xdc,
+   0x82, 0x16, 0x20, 0x01, 0x00, 0x01, 0x00, 0x78, 0x05, 0x38, 0x00, 0x34,
+   0x00, 0x00, 0x02, 0x41, 0x14, 0xc0, 0x07, 0xe0, 0x61, 0x40, 0x80, 0x40,
+   0x80, 0x01, 0x10, 0x60, 0x01, 0xe0, 0x03, 0x02, 0xc0, 0x00, 0x88, 0x02,
+   0x1e, 0xf0, 0x01, 0xe0, 0x05, 0x8f, 0x40, 0x00, 0x00, 0x03, 0x0e, 0x7c,
+   0x00, 0xc0, 0x21, 0x18, 0xc0, 0x00, 0x80, 0x10, 0x32, 0xb4, 0x00, 0x80,
+   0x80, 0x40, 0x40, 0x00, 0x80, 0x11, 0x16, 0x00, 0x01, 0x00, 0x41, 0x20,
+   0x80, 0x00, 0x00, 0x02, 0x13, 0xbe, 0x00, 0x00, 0xe0, 0x09, 0x80, 0x20,
+   0xa0, 0x21, 0x09, 0x09, 0x00, 0x80, 0x30, 0x04, 0x00, 0x10, 0xa0, 0x00,
+   0x13, 0x0e, 0x01, 0x00, 0xd0, 0x20, 0xa0, 0x00, 0x60, 0x00, 0x1a, 0x02,
+   0x01, 0x40, 0x10, 0x0c, 0x01, 0x30, 0x18, 0x06, 0x00, 0x55, 0x02, 0x40,
+   0x58, 0x50, 0xc0, 0x00, 0x00, 0x00, 0x07, 0x85, 0x02, 0x00, 0x04, 0x24,
+   0x70, 0x00, 0x00, 0x43, 0x91, 0x05, 0x04, 0x50, 0x06, 0x15, 0x50, 0x08,
+   0x20, 0x82, 0x21, 0x00, 0xce, 0xf7, 0x00, 0x04, 0x48, 0x03, 0x80, 0x80,
+   0xc1, 0x04, 0x17, 0x13, 0x00, 0x02, 0x70, 0x03, 0x10, 0x03, 0xc3, 0x02,
+   0x00, 0x05, 0x00, 0x01, 0x34, 0x13, 0x40, 0x02, 0xc2, 0x00, 0x18, 0x00,
+   0x00, 0x00, 0x7e, 0x20, 0x80, 0x0f, 0xc6, 0x83, 0xa4, 0x00, 0x00, 0x00,
+   0x27, 0x00, 0x00, 0x04, 0x80, 0x01, 0xa0, 0x00, 0x01, 0xd0, 0x17, 0x00,
+   0x00, 0x81, 0x04, 0x06, 0xc0, 0x0d, 0x70, 0xe1, 0x11, 0x04, 0x20, 0x88,
+   0x84, 0x0c, 0x80, 0x00, 0x10, 0x7c, 0x0c, 0xc0, 0x00, 0x18, 0x89, 0x01,
+   0x00, 0x0f, 0x9c, 0x0d, 0x0c, 0x00, 0x00, 0xa0, 0x80, 0x23, 0x20, 0xb0,
+   0x2e, 0x0b, 0x06, 0x00, 0x00, 0x23, 0x11, 0x61, 0x01, 0xfc, 0x2b, 0x02,
+   0x04, 0x10, 0x00, 0x43, 0x90, 0x01, 0x20, 0xff, 0x06, 0x80, 0x83, 0x10,
+   0x00, 0x10, 0x00, 0x03, 0x22, 0x07, 0x00, 0x06, 0x40, 0x00, 0x00, 0x92,
+   0x00, 0x01, 0x03, 0x00, 0x20, 0x00, 0x81, 0x12, 0x00, 0x02, 0x03, 0x03,
+   0x27, 0x00, 0x40, 0xc0, 0x00, 0x01, 0x00, 0x10, 0x02, 0x02, 0x40, 0xcd,
+   0x07, 0x18, 0x02, 0x04, 0x00, 0x00, 0x09, 0x82, 0x28, 0xc1, 0x04, 0x20,
+   0x00, 0x00, 0x00, 0x16, 0x10, 0x06, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00,
+   0x00, 0x30, 0x6c, 0x06, 0x00, 0x00, 0x04, 0x0e, 0x88, 0x00, 0x00, 0x44,
+   0x00, 0x07, 0x00, 0x04, 0xc0, 0x01, 0x20, 0x00, 0x00, 0x00, 0x81, 0x05,
+   0x00, 0x00, 0x00, 0x30, 0x10, 0x00, 0x00, 0x40, 0x10, 0x02, 0x00, 0x01,
+   0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x08, 0xa0, 0x1c, 0x00,
+   0x24, 0x00, 0x00, 0x00, 0x01, 0x80, 0x2b, 0xe0, 0x0e, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x78, 0x80, 0x04, 0x62, 0x80, 0x00, 0x00, 0x00, 0x20,
+   0x04, 0x80, 0x00, 0x28, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01,
+   0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x00, 0x00, 0x00,
+   0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04, 0x51, 0x00, 0x01, 0x80,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x01, 0x80, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00},
+  {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x04, 0x20, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x04, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+   0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x18, 0x20, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x08, 0x00, 0x0e, 0x01, 0x00, 0x84, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02,
+   0x9c, 0x02, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, 0x40, 0x77, 0xa9, 0x48,
+   0x08, 0x00, 0x10, 0x00, 0x00, 0x00, 0x20, 0x2c, 0x60, 0x08, 0x05, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x36, 0x00, 0x40, 0x5e, 0x10, 0x00, 0x00,
+   0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xaa, 0x10, 0x04, 0x00, 0x00, 0x10,
+   0xc1, 0x81, 0x10, 0x00, 0x10, 0x61, 0x00, 0x00, 0x00, 0x00, 0x60, 0x48,
+   0xa4, 0x00, 0x40, 0x41, 0x00, 0x00, 0x00, 0x00, 0x90, 0x9d, 0x9a, 0x04,
+   0xc0, 0x8c, 0x00, 0x08, 0x00, 0x82, 0x78, 0x7b, 0x01, 0x19, 0xc0, 0x10,
+   0x00, 0x00, 0x00, 0x22, 0xe6, 0xe6, 0x01, 0x68, 0xc0, 0x30, 0x20, 0x00,
+   0x00, 0x02, 0xd0, 0xd0, 0xa2, 0xe5, 0x85, 0x45, 0x02, 0x00, 0x00, 0xe0,
+   0x8c, 0x00, 0x06, 0x01, 0x00, 0x41, 0x00, 0x00, 0x80, 0x08, 0x46, 0x40,
+   0xb4, 0xf7, 0x41, 0x6b, 0xc3, 0x00, 0x00, 0x00, 0x26, 0x0d, 0xdf, 0xe7,
+   0x08, 0x08, 0x83, 0x02, 0x88, 0x70, 0x8c, 0x80, 0x30, 0xe1, 0x09, 0x23,
+   0x92, 0x01, 0x00, 0x40, 0x14, 0x70, 0x80, 0x11, 0x8a, 0x41, 0x06, 0x00,
+   0x02, 0x08, 0x00, 0x04, 0x40, 0x48, 0x0c, 0x02, 0x0c, 0x08, 0x00, 0x10,
+   0x00, 0x04, 0x40, 0x18, 0x43, 0x92, 0xa9, 0x00, 0x00, 0x08, 0x00, 0x02,
+   0x02, 0x13, 0x20, 0x54, 0x11, 0x00, 0x00, 0x08, 0xc4, 0x01, 0x00, 0x03,
+   0x40, 0x80, 0x00, 0x00, 0x08, 0x34, 0xa0, 0x08, 0x00, 0x0e, 0x40, 0x0c,
+   0x00, 0x00, 0x00, 0x02, 0xe0, 0x00, 0x20, 0x26, 0x80, 0xc1, 0x30, 0x04,
+   0x00, 0x06, 0x01, 0x80, 0x4e, 0x6e, 0x80, 0x37, 0x10, 0x00, 0x00, 0x01,
+   0x28, 0xe0, 0x80, 0x63, 0x80, 0x82, 0x20, 0x01, 0x00, 0x06, 0x20, 0xf0,
+   0x96, 0xed, 0x00, 0x46, 0x01, 0x01, 0x81, 0x01, 0x1c, 0x80, 0x17, 0x58,
+   0x01, 0x67, 0x00, 0x02, 0x00, 0x11, 0x3c, 0xc0, 0x0e, 0xf0, 0x41, 0x2f,
+   0x80, 0x00, 0x80, 0x01, 0x44, 0xf8, 0x03, 0x30, 0x04, 0xc4, 0xe0, 0x00,
+   0xc0, 0x01, 0x36, 0xf0, 0x00, 0xe0, 0x00, 0x5d, 0xc1, 0x00, 0x60, 0x20,
+   0x11, 0x34, 0x00, 0xc0, 0x03, 0x28, 0x00, 0x02, 0xc0, 0x00, 0x09, 0x0e,
+   0x01, 0xc0, 0xc5, 0x28, 0x40, 0x08, 0x00, 0x83, 0x11, 0xbd, 0x00, 0xc0,
+   0x05, 0x20, 0x20, 0x01, 0x00, 0x00, 0x18, 0x8a, 0x00, 0xc0, 0x21, 0x06,
+   0x00, 0x00, 0x10, 0x01, 0x12, 0x05, 0x00, 0x80, 0x00, 0x8e, 0x80, 0x21,
+   0x00, 0xa1, 0x81, 0x8a, 0x00, 0x00, 0x80, 0x18, 0xc0, 0x00, 0xc8, 0xc0,
+   0xc8, 0x62, 0x01, 0x00, 0x60, 0x00, 0x40, 0x00, 0xd0, 0x60, 0x58, 0x42,
+   0x01, 0x40, 0xd0, 0x34, 0x40, 0x00, 0x80, 0x80, 0x00, 0x00, 0x03, 0x20,
+   0x38, 0x00, 0x40, 0x00, 0xc0, 0x03, 0x71, 0x01, 0x00, 0x10, 0x4c, 0x44,
+   0x40, 0x00, 0x00, 0x81, 0xb0, 0xc0, 0x03, 0x00, 0x0c, 0x10, 0x40, 0x00,
+   0x48, 0x00, 0x71, 0x80, 0xe9, 0x2f, 0x22, 0x06, 0x20, 0x14, 0x00, 0x11,
+   0x60, 0x00, 0xc0, 0xb4, 0x01, 0x54, 0x28, 0x08, 0x00, 0x03, 0xe1, 0x20,
+   0x04, 0x05, 0x40, 0x09, 0x20, 0x00, 0x00, 0x24, 0x91, 0x00, 0x05, 0x00,
+   0x80, 0x03, 0x38, 0x0c, 0x60, 0x14, 0x91, 0x01, 0x14, 0x00, 0x80, 0x00,
+   0x1c, 0x04, 0x40, 0x20, 0x30, 0x00, 0x30, 0x00, 0x40, 0x00, 0x13, 0x00,
+   0x00, 0x05, 0x31, 0x00, 0xb0, 0x21, 0x00, 0x00, 0x4a, 0x01, 0x20, 0x01,
+   0x32, 0x04, 0x10, 0x00, 0x00, 0x80, 0xdc, 0x00, 0x40, 0x10, 0x20, 0x0c,
+   0xe0, 0x00, 0x06, 0xa0, 0x4a, 0x00, 0x00, 0x11, 0x30, 0x10, 0x42, 0x01,
+   0x23, 0xf2, 0x0d, 0x42, 0x20, 0x21, 0x10, 0x20, 0x84, 0xc7, 0x83, 0xfd,
+   0x02, 0x00, 0xa0, 0x48, 0x10, 0x30, 0xf2, 0xbd, 0x9a, 0x0e, 0x00, 0x00,
+   0x80, 0x00, 0x20, 0x70, 0x70, 0xbe, 0xf2, 0xc0, 0x81, 0x04, 0x40, 0x40,
+   0x21, 0x00, 0x02, 0x40, 0x22, 0xa0, 0x01, 0x01, 0x00, 0x20, 0x33, 0x44,
+   0x0a, 0x00, 0x40, 0x40, 0x00, 0x00, 0x20, 0x00, 0x38, 0x00, 0x5b, 0x00,
+   0x20, 0x70, 0x00, 0x00, 0x00, 0x40, 0x12, 0x00, 0x80, 0x6e, 0x4a, 0x08,
+   0x80, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x36, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x1c, 0x04, 0x00, 0x80, 0x00,
+   0x20, 0x00, 0x10, 0x00, 0x80, 0x01, 0x00, 0x00, 0x00, 0x10, 0x80, 0x02,
+   0x00, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xac, 0x00, 0x00,
+   0xb9, 0x00, 0x14, 0x00, 0x00, 0x04, 0x04, 0xa3, 0x00, 0x00, 0x06, 0x00,
+   0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x8a, 0xc2, 0x01, 0x40, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x88, 0x3d, 0x82, 0x00, 0x02, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x10, 0x38, 0x00, 0x42, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00,
+   0x80, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x10,
+   0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x10, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
+#define terrain_width 20
+#define terrain_height 20
+static unsigned char a0000_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x30, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02,
+  0x0e, 0x03, 0x01, 0x0c, 0x06, 0x00, 0x08, 0x02, 0x00, 0x40, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x01,
+  0x80, 0xc1, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char a0001_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x01, 0x00, 0x00, 0x81, 0x01, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xc0, 0x60, 0x00, 0x60, 0x30, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char a0010_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x08, 0x80, 0x01,
+  0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x00,
+  0x00, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+  0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x06, 0x60, 0x00,
+};
+static unsigned char a0011_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x47, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x30, 0x00, 0x00, 0x20, 0x00,
+  0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
+  0xc0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x02, 0x00, 0x00, 0x20, 0x00, 0x06, 0x60, 0x00,
+};
+static unsigned char a0100_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x60, 0x00, 0x00, 0x40, 0x10, 0x00,
+  0x00, 0x60, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x04, 0x00,
+  0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char a0101_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x08, 0x03, 0x00, 0x0c, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x10, 0x00, 0x03, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00,
+  0x00, 0x1c, 0x00, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
+};
+static unsigned char a0110_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x10, 0x00, 0x80, 0x01, 0x00,
+  0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x60, 0x00,
+  0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08,
+  0x80, 0x00, 0x08, 0x80, 0x00, 0x00, 0x02, 0x00, 0x00, 0x04, 0x60, 0x00,
+};
+static unsigned char a0111_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x00, 0x03, 0x84, 0x00, 0x01, 0x18, 0x00, 0x00, 0x30, 0x00, 0x00,
+  0x00, 0x08, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x06, 0x60, 0x00,
+};
+static unsigned char a1000_bits[] = {
+  0x0c, 0xa0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x08, 0x02, 0x00, 0x84, 0x03, 0x00, 0x06, 0x41, 0x00,
+  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00,
+  0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x08, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char a1001_bits[] = {
+  0x0c, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00,
+  0x83, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0xc0, 0x01, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x20, 0x00, 0x00,
+  0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char a1010_bits[] = {
+  0x04, 0xe0, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x02, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00,
+  0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x0c, 0x40, 0x00, 0x06, 0x60, 0x00,
+};
+static unsigned char a1011_bits[] = {
+  0x0c, 0x80, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0x00, 0x00, 0x02, 0x04, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x03, 0x20, 0x00,
+  0x82, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x04, 0x70, 0x00,
+};
+static unsigned char a1100_bits[] = {
+  0x3c, 0x80, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0xe0, 0x00, 0x00, 0x80, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x80, 0x00, 0x00, 0x00, 0x0c,
+  0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00,
+};
+static unsigned char a1101_bits[] = {
+  0x0c, 0xc0, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x60, 0x08, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00,
+  0x31, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
+  0x80, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x10, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static unsigned char a1110_bits[] = {
+  0x08, 0xe0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x08, 0x00, 0x02, 0x0c, 0x00, 0x0e, 0x04, 0x30, 0x08, 0x00,
+  0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00,
+  0xc0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x02, 0x40, 0x00, 0x06, 0x20, 0x00,
+};
+static unsigned char a1111_bits[] = {
+  0x0c, 0xe0, 0x00, 0x08, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+  0x03, 0x00, 0x0c, 0x01, 0x00, 0x08, 0x81, 0x01, 0x00, 0x00, 0x03, 0x00,
+  0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+  0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
+  0x00, 0x01, 0x04, 0x01, 0x00, 0x08, 0x05, 0x20, 0x00, 0x06, 0x60, 0x00,
+};
+
+/* asteroid "fluff" bitmaps */
+static unsigned char a0_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+static unsigned char a1_bits[] = {
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
+static unsigned char a2_bits[] = {
+  0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stats.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,206 @@
+/* $Id: stats.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * stats.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+#define	MIN(a,b)	(((a) < (b)) ? (a) : (b))
+
+#define	BX_OFF()	((textWidth + 1) * W_Textwidth + S_IBORDER)
+#define	BY_OFF(line)	((line) * (W_Textheight + S_IBORDER) + S_IBORDER)
+#define	TX_OFF(len)	((textWidth - len) * W_Textwidth + S_IBORDER)
+#define	TY_OFF(line)	BY_OFF(line)
+
+#if 0
+#define STAT_WIDTH		160
+#else
+#define	STAT_WIDTH		st_width
+#endif
+#define STAT_HEIGHT		BY_OFF(NUM_SLIDERS)
+#define STAT_BORDER		2
+#define S_IBORDER		5
+#define STAT_X			422
+#define STAT_Y			13
+
+#define SL_WID			\
+	(STAT_WIDTH - 2 * S_IBORDER - (textWidth + 1) * W_Textwidth)
+#define SL_HEI			(W_Textheight)
+
+#define NUM_ELS(a)		(sizeof (a) / sizeof (*(a)))
+#define NUM_SLIDERS		NUM_ELS(sliders)
+
+typedef struct slider {
+    char   *label;
+    int     min, max;
+    int     red;
+    int     yellow;
+    int     label_length;
+    int     diff;
+    int    *var;
+    int     lastVal;
+}       SLIDER;
+
+typedef struct record {
+    int    *data;
+    int     last_value;
+}       RECORD;
+
+static SLIDER sliders[] = {
+    {"Shield Cond", 0, 100, 20, 100},
+    {"Hull Cond", 0, 100, 0, 0},
+    {"Fuel Cond", 0, 10000, 2000, 10000},
+    {"Weapon Temp", 0, 1200, 0, 800},
+    {"Engine Temp", 0, 1200, 0, 800},
+};
+
+static int textWidth = 0;
+static int initialized = 0;
+
+/* Prototypes */
+static void box
+P((int filled, int x, int y, int wid, int hei,
+   W_Color color));
+    static void initStats P((void));
+
+    static int st_width = -1;
+
+    static void initStats()
+{
+    int     i;
+
+    if (initialized)
+	return;
+    initialized = 1;
+    sliders[0].var = &(me->p_shield);
+    sliders[1].var = &(me->p_damage);
+    sliders[2].var = &(me->p_fuel);
+    sliders[3].var = &(me->p_wtemp);
+    sliders[4].var = &(me->p_etemp);
+    for (i = 0; i < NUM_SLIDERS; i++) {
+	sliders[i].label_length = strlen(sliders[i].label);
+	textWidth = MAX(textWidth, sliders[i].label_length);
+	sliders[i].diff = sliders[i].max - sliders[i].min;
+	sliders[i].lastVal = 0;
+    }
+    st_width = W_WindowWidth(statwin);
+}
+
+void
+redrawStats()
+{
+    int     i;
+
+    W_ClearWindow(statwin);
+    initStats();
+    for (i = 0; i < NUM_SLIDERS; i++) {
+	sliders[i].lastVal = 0;
+    }
+    for (i = 0; i < NUM_SLIDERS; i++) {
+	W_WriteText(statwin, TX_OFF(sliders[i].label_length), TY_OFF(i),
+		    textColor, sliders[i].label, sliders[i].label_length,
+		    W_RegularFont);
+	box(0, BX_OFF() - 1, BY_OFF(i) - 1, SL_WID + 2, SL_HEI + 2, borderColor);
+	sliders[i].lastVal = 0;
+    }
+}
+
+void
+updateStats()
+{
+    int     i, value, new_x;
+    int     r, y, t;
+    SLIDER *s;
+
+    initStats();
+    for (i = 0; i < NUM_SLIDERS; i++) {
+	s = &sliders[i];
+	value = *(s->var);
+	if ((i == 0) || (i == 2))
+	    value = s->max - value;
+	if (value < s->min)
+	    value = s->min;
+	else if (value > s->max)
+	    value = s->max;
+#if 0
+	if (value == s->lastVal)
+	    continue;
+#endif
+	new_x = value * SL_WID / s->diff;
+	y = s->yellow * SL_WID / s->diff;
+	r = s->red * SL_WID / s->diff;
+	t = s->max * SL_WID / s->diff;
+	if (value > s->red) {
+	    box(1, BX_OFF(), BY_OFF(i), y, SL_HEI, gColor);
+	    box(1, BX_OFF() + y, BY_OFF(i), r - y, SL_HEI, yColor);
+	    box(1, BX_OFF() + r, BY_OFF(i), new_x - r, SL_HEI, rColor);
+	} else if (value > s->yellow) {
+	    box(1, BX_OFF(), BY_OFF(i), y, SL_HEI, gColor);
+	    box(1, BX_OFF() + y, BY_OFF(i), new_x - y, SL_HEI, yColor);
+	} else {
+	    box(1, BX_OFF(), BY_OFF(i), new_x, SL_HEI, gColor);
+	}
+	box(1, BX_OFF() + new_x, BY_OFF(i), t - new_x, SL_HEI, backColor);
+    }
+}
+
+static void
+box(filled, x, y, wid, hei, color)
+    int     filled, x, y, wid, hei;
+    W_Color color;
+{
+    if (wid == 0)
+	return;
+
+    if (filled) {
+	/* XFIX */
+	W_FillArea(statwin, x, y, wid + 1, hei + 1, color);
+	return;
+    }
+    W_MakeLine(statwin, x, y, x + wid, y, color);
+    W_MakeLine(statwin, x + wid, y, x + wid, y + hei, color);
+    W_MakeLine(statwin, x + wid, y + hei, x, y + hei, color);
+    W_MakeLine(statwin, x, y + hei, x, y, color);
+}
+
+
+void
+calibrate_stats()
+{
+    register int i;
+    sliders[0].min = 0;
+    sliders[0].max = me->p_ship->s_maxshield;
+    sliders[0].yellow = .33 * ((double) sliders[0].max);
+    sliders[0].red = .66 * ((double) sliders[0].max);
+
+    sliders[1].min = 0;
+    sliders[1].max = me->p_ship->s_maxdamage;
+    sliders[1].yellow = .33 * ((double) sliders[1].max);
+    sliders[1].red = .66 * ((double) sliders[1].max);
+
+    sliders[2].min = 0;
+    sliders[2].max = me->p_ship->s_maxfuel;
+    sliders[2].yellow = .33 * ((double) sliders[2].max);
+    sliders[2].red = .66 * ((double) sliders[2].max);
+
+    sliders[3].min = 0;
+    sliders[3].max = 1.0 * ((double) me->p_ship->s_maxwpntemp);
+    sliders[3].yellow = .33 * ((double) sliders[3].max);
+    sliders[3].red = .66 * ((double) sliders[3].max);
+
+    sliders[4].min = 0;
+    sliders[4].max = 1.0 * ((double) me->p_ship->s_maxegntemp);
+    sliders[4].yellow = .33 * ((double) sliders[4].max);
+    sliders[4].red = .66 * ((double) sliders[4].max);
+
+    for (i = 0; i < NUM_SLIDERS; i++)
+	sliders[i].diff = sliders[i].max - sliders[i].min;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/struct.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,810 @@
+/* $Id: struct.h,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * struct.h for the client of an xtrek socket protocol.
+ *
+ * Most of the unneeded stuff in the structures has been thrown away.
+ */
+
+#ifndef struct_h_
+#define struct_h_
+
+#include "copyright.h"
+#include "Wlib.h"
+#include "defs.h"
+#include "packets.h"
+
+#ifdef HOCKEY
+/* hockey struct [BDyess] */
+struct hockeyLine {
+  int vertical;		/* vertical or horizontal flag */
+  W_Color color;
+  int pos, end1, end2;	/* x or y constant and two endpoints */
+};
+#endif /*HOCKEY*/
+
+/* ratings struct [BDyess] */
+struct ratings {
+    float   r_offrat;		/* offense rating */
+    float   r_planetrat;	/* planets rating */
+    float   r_bombrat;		/* bombing rating */
+    float   r_defrat;		/* defense rating */
+    float   r_resrat;		/* resource rating */
+    float   r_dooshrat;		/* doosh rating */
+    float   r_stratrat;		/* strategy rating */
+    float   r_batrat;		/* battle rating */
+    float   r_sbrat;		/* sb rating */
+    float   r_wbrat;		/* wb rating */
+    float   r_jsrat;		/* js rating */
+    int     r_jsplanets;	/* js planets */
+    int     r_resources;	/* total resources bombed */
+    int     r_armies;		/* total armies bombed */
+    int     r_planets;		/* total planets taken */
+    int     r_dooshes;		/* total armies dooshed */
+    float   r_specrat;		/* special ship rating */
+    float   r_di;		/* damage inflicted */
+    float   r_ratio;		/* ratio, kills/losses */
+    int     r_kills;		/* kills */
+    int     r_losses;		/* losses */
+    float   r_ratings;		/* total ratings */
+    float   r_killsPerHour;	/* kills/hour */
+    float   r_lossesPerHour;	/* losses/hour */
+    float   r_maxkills;		/* max kills */
+    int     r_genocides;	/* number of genocides */
+};
+
+/* messageWindow structure [BDyess] */
+struct messageWin {
+    W_Window window;
+    int     flags;
+    struct messageNode *head, *curHead;
+};
+
+/* stuff yanked from COW-lite for rc_distress [BDyess] */
+struct distress {
+    unsigned char sender;
+    unsigned char dam, shld, arms, wtmp, etmp, fuelp, sts;
+    unsigned char wtmpflag, etempflag, cloakflag, distype, macroflag;
+    unsigned char close_pl, close_en, tclose_pl, tclose_en, pre_app, i;
+    unsigned char close_j, close_fr, tclose_j, tclose_fr;
+    unsigned char cclist[6];	/* allow us some day to cc a message up to 5
+				   people */
+    /* sending this to the server allows the server to do the cc action */
+    /* otherwise it would have to be the client ... less BW this way */
+    char    preappend[80];	/* text which we pre or append */
+};
+
+enum dist_type {
+    /* help me do series */
+    take = 1, ogg, bomb, space_control,
+    save_planet,
+    base_ogg,
+    help3, help4,
+
+    /* doing series */
+    escorting, ogging, bombing, controlling,
+    asw,
+    asbomb,
+    doing3, doing4,
+
+    /* other info series */
+    free_beer,			/* ie. player x is totally hosed now */
+    no_gas,			/* ie. player x has no gas */
+    crippled,			/* ie. player x is way hurt but may have gas */
+    pickup,			/* player x picked up armies */
+    pop,			/* there was a pop somewhere */
+    carrying,			/* I am carrying */
+    other1, other2,
+
+    /* just a generic distress call */
+    generic
+};
+
+/* The General distress has format:
+
+   byte1: 00yzzzzz
+   where zzzzz is dist_type, and y is 1 if this is a more complicated macro
+   and not just a simple distress (a simple distress will ONLY send ship
+   info like shields, armies, status, location, etc.). I guess y=1 can be for !
+   future expansion.
+
+   byte2: 1fff ffff - f = percentage fuel remaining (0-100)
+   byte3: 1ddd dddd - % damage
+   byte4: 1sss ssss - % shields remaining
+   byte5: 1eee eeee - % etemp
+   byte6: 1www wwww - % wtemp
+   byte7: 100a aaaa - armies carried
+   byte8: (lsb of me->p_status) & 0x80
+   byte9: 1ppp pppp - planet closest to me
+   byte10: 1eee eeee - enemy closest to me
+   byte11: 1ppp pppp - planet closest to target
+   byte12: 1eee eeee - enemy closest to target
+   byte13: 1ttt tttt - tclose_j
+   byte14: 1jjj jjjj - close_j
+   byte15: 1fff ffff - tclose_fr
+   byte16: 1ccc cccc - close_fr
+   byte17+: cc list (each player to cc this message to is 11pp ppp)
+   cc list is terminated by 0x80 (pre-pend) or 0100 0000 (append) )
+   byte18++: the text to pre or append .. depending on termination above.
+   text is null terminated and the last thing in this distress
+ */
+
+struct macro_list {
+    int     type;
+    char    key;
+    char    who;
+    char   *string;
+};
+
+struct dmacro_list {
+    unsigned char c;
+    char   *name;
+    char   *macro;
+};
+/* end rc_distress stuff [BDyess] */
+
+struct status {
+    unsigned char tourn;	/* Tournament mode? */
+    /* These stats only updated during tournament mode */
+    unsigned int armsbomb, planets, kills, losses, time;
+    /* Use long for this, so it never wraps */
+    unsigned long timeprod;
+};
+
+struct status2 {		/* paradise status struct */
+    int     active;		/* for interfacing with people who */
+    unsigned int wait, count;	/* want to get into the game */
+    unsigned int number, request, answer;
+    unsigned char tourn;	/* Tournament mode? */
+    unsigned long dooshes;	/* total number of armies dooshed */
+    unsigned long armsbomb;	/* all t-mode armies bombed */
+    unsigned long resbomb;	/* resources bombed */
+    unsigned long planets;	/* all t-mode planets taken */
+    unsigned long kills;	/* all t-mode kills made */
+    unsigned long losses;	/* all t-mode losses */
+    unsigned long genocides;	/* number of genocides */
+    unsigned long sbkills;	/* total kills in SB's */
+    unsigned long sblosses;	/* total losses in Sb's */
+    unsigned long sbtime;	/* total time in SB's */
+    unsigned long wbkills;	/* kills in warbases */
+    unsigned long wblosses;	/* losses in warbases */
+    unsigned long wbtime;	/* total time played in wb's */
+    unsigned long jsplanets;	/* total planets taken by jump ships */
+    unsigned long jstime;	/* total time in a jump ship */
+    unsigned long time;		/* t-mode time */
+    unsigned long timeprod;	/* t-mode ship ticks--sort of like */
+    /* manhours in t-mode */
+    int     gameup;		/* is game up */
+    unsigned long clock;	/* clock for planet info timestamp */
+};
+
+
+#ifdef METASERVER
+/* metaserver window struct */
+struct servers {
+    char    address[LINE];
+    int     port;
+    int     time;
+    int     players;
+    int     status;
+    int     RSA_client;
+    char    typeflag;
+    char    hilited;
+};
+#endif				/* METASERVER */
+
+/* MOTD structures */
+struct piclist {
+    int     page;
+    W_Icon  thepic;
+    int     x, y;
+    int     width, height;
+    struct piclist *next;
+};
+struct page {
+    struct list *text;
+    struct page *next;
+    struct page *prev;
+    int     first;
+    int     page;
+};
+
+#define PFREE 0
+#define POUTFIT 1
+#define PALIVE 2
+#define PEXPLODE 3
+#define PDEAD 4
+#define PTQUEUE 5
+#define POBSERVE 6
+
+#define PFSHIELD	  (1<< 0)	/* shields are raised */
+#define PFREPAIR	  (1<< 1)	/* player in repair mode */
+#define PFBOMB		  (1<< 2)	/* player is bombing */
+#define PFORBIT		  (1<< 3)	/* player is orbiting */
+#define PFCLOAK		  (1<< 4)	/* player is cloaked */
+#define PFWEP		  (1<< 5)	/* player is weapon temped */
+#define PFENG		  (1<< 6)	/* player is engine temped */
+#define PFROBOT		  (1<< 7)	/* player is a robot */
+#define PFBEAMUP	  (1<< 8)	/* player is beaming up */
+#define PFBEAMDOWN	  (1<< 9)	/* player is beaming down */
+#define PFSELFDEST	  (1<<10)	/* player is self destructing */
+#define PFGREEN		  (1<<11)	/* player at green alert */
+#define PFYELLOW	  (1<<12)	/* player is at yellow alert */
+#define PFRED		  (1<<13)	/* player is at red alert */
+#define PFPLOCK		  (1<<14)	/* Locked on a player */
+#define PFPLLOCK	  (1<<15)	/* Locked on a planet */
+#define PFCOPILOT	  (1<<16)	/* Allow copilots */
+#define PFWAR		  (1<<17)	/* computer reprogramming for war */
+#define PFPRACTR	  (1<<18)	/* practice type robot (no kills) */
+#define PFDOCK            (1<<19)	/* true if docked to a starbase */
+#define PFREFIT           (1<<20)	/* true if about to refit */
+#define PFREFITTING	  (1<<21)	/* true if currently refitting */
+#define PFTRACT  	  (1<<22)	/* tractor beam activated */
+#define PFPRESS  	  (1<<23)	/* pressor beam activated */
+#define PFDOCKOK	  (1<<24)	/* docking permission */
+#define PFSEEN		  (1<<25)	/* seen by enemy on galactic map? */
+#define PFWARPPREP	  (1<<26)	/* in warp prep [BDyess] */
+#define PFWARP		  (1<<27)	/* ship warping */
+#define PFAFTER		  (1<<28)	/* after burners on */
+#define PFWPSUSPENDED     (1<<29)	/* warp prep suspended [BDyess] */
+#define PFSNAKE	          (1<<30)	/* it's a space snake */
+#define PFBIRD	          (1<<31)	/* it's a space bird */
+
+enum why_dead {
+    KNOREASON, KQUIT, KTORP, KPHASER, KPLANET,
+    KSHIP, KDAEMON, KWINNER, KGHOST, KGENOCIDE,
+    KPROVIDENCE, KPLASMA, KTOURNEND, KOVER, KTOURNSTART,
+    KBADBIN, KMISSILE, KASTEROID
+};
+
+#define DEFAULT -1
+#define SCOUT 0
+#define DESTROYER 1
+#define CRUISER 2
+#define BATTLESHIP 3
+#define ASSAULT 4
+#define STARBASE 5
+#define ATT 6
+#define GALAXY 6		/* galaxy ships now supported - they look
+				   extremely similar to flagships :) [BDyess] */
+#define JUMPSHIP 7
+#define FLAGSHIP 8
+#define WARBASE 9
+#define LIGHTCRUISER 10
+#define CARRIER 11
+#define UTILITY 12
+#define PATROL 13
+#define PUCK 14
+/*#define NUM_TYPES 14*/
+
+struct shiplist {
+    struct ship *ship;
+    struct shiplist *prev, *next;
+};
+
+struct ship {
+    int     s_phaserrange;
+    int     s_maxspeed;
+    int     s_maxfuel;
+    int     s_maxshield;
+    int     s_maxdamage;
+    int     s_maxegntemp;
+    int     s_maxwpntemp;
+    short   s_maxarmies;
+    short   s_type;
+    int     s_torpspeed;
+    char    s_letter;
+    /* char s_name[16]; */
+    char    s_desig[2];
+    short   s_bitmap;
+    unsigned char s_keymap[256];
+    unsigned char s_buttonmap[12];
+};
+
+struct ship_shape {
+    int     nviews;
+    W_Icon *bmap;
+    W_Icon  shield;
+    int     width, height;
+};
+
+struct stats {
+    double  st_maxkills;	/* max kills ever */
+    int     st_kills;		/* how many kills */
+    int     st_losses;		/* times killed */
+    int     st_armsbomb;	/* armies bombed */
+    int     st_planets;		/* planets conquered */
+    int     st_ticks;		/* Ticks I've been in game */
+    int     st_tkills;		/* Kills in tournament play */
+    int     st_tlosses;		/* Losses in tournament play */
+    int     st_tarmsbomb;	/* Tournament armies bombed */
+    int     st_tplanets;	/* Tournament planets conquered */
+    int     st_tticks;		/* Tournament ticks */
+    /* SB stats are entirely separate */
+    int     st_sbkills;		/* Kills as starbase */
+    int     st_sblosses;	/* Losses as starbase */
+    int     st_sbticks;		/* Time as starbase */
+    double  st_sbmaxkills;	/* Max kills as starbase */
+    long    st_lastlogin;	/* Last time this player was played */
+    int     st_flags;		/* Misc option flags */
+#if 0
+    unsigned char st_keymap[256];	/* keymap for this player */
+#endif
+    int     st_rank;		/* Ranking of the player */
+};
+
+
+struct stats2 {			/* paradise stats */
+    int     st_genocides;	/* number of genocides participated in */
+    float   st_tmaxkills;	/* max kills ever */
+    float   st_di;		/* total destruction inflicted for all time */
+    int     st_tkills;		/* Kills in tournament play */
+    int     st_tlosses;		/* Losses in tournament play */
+    int     st_tarmsbomb;	/* Tournament armies bombed */
+    int     st_tresbomb;	/* resources bombed off */
+    int     st_tdooshes;	/* armies killed while being carried */
+    int     st_tplanets;	/* Tournament planets conquered */
+    int     st_tticks;		/* Tournament ticks */
+    /* SB/WB/JS stats are entirely separate */
+    int     st_sbkills;		/* Kills as starbase */
+    int     st_sblosses;	/* Losses as starbase */
+    int     st_sbticks;		/* Time as starbase */
+    float   st_sbmaxkills;	/* Max kills as starbase */
+    int     st_wbkills;		/* Kills as warbase */
+    int     st_wblosses;	/* Losses as warbase */
+    int     st_wbticks;		/* Time as warbase */
+    float   st_wbmaxkills;	/* Max kills as warbase */
+    int     st_jsplanets;	/* planets assisted with in JS */
+    int     st_jsticks;		/* ticks played as a JS */
+    long    st_lastlogin;	/* Last time this player was played */
+    int     st_flags;		/* Misc option flags */
+    unsigned char st_keymap[256];	/* keymap for this player */
+    int     st_rank;		/* Ranking of the player */
+    int     st_royal;		/* royaly, specialty, rank */
+};
+
+#define ST_NOBITMAPS	(1<<0)
+#define ST_KEEPPEACE    (1<<3)
+
+struct player {
+    int     p_no;
+    int     p_updates;		/* Number of updates ship has survived */
+    int     p_status;		/* Player status */
+    unsigned int p_flags;	/* Player flags */
+    char    p_name[16];
+    char    p_login[16];
+    char    p_monitor[16];	/* Monitor being played on */
+    char    p_mapchars[2];	/* Cache for map window image */
+    struct ship *p_ship;	/* Personal ship statistics */
+    int     p_x;
+    int     p_y;
+    unsigned char p_dir;	/* Real direction */
+    unsigned char p_desdir;	/* desired direction */
+    int     p_subdir;		/* fraction direction change */
+    int     p_speed;		/* Real speed */
+    short   p_desspeed;		/* Desired speed */
+    int     p_subspeed;		/* Fractional speed */
+    short   p_teami;		/* Team I'm on */
+    int     p_damage;		/* Current damage */
+    int     p_subdamage;	/* Fractional damage repair */
+    int     p_shield;		/* Current shield power */
+    int     p_subshield;	/* Fractional shield recharge */
+    short   p_cloakphase;	/* Drawing stage of cloaking
+				   engage/disengage. */
+    short   p_ntorp;		/* Number of torps flying */
+    short   p_ndrone;		/* Number of drones .. why was this missing? */
+    short   p_totmissiles;	/* number of total missiles [Bill Dyess] */
+    short   p_nplasmatorp;	/* Number of plasma torps active */
+    char    p_hostile;		/* Who my torps will hurt */
+    char    p_swar;		/* Who am I at sticky war with */
+    float   p_kills;		/* Enemies killed */
+    short   p_planet;		/* Planet orbiting or locked onto */
+    short   p_playerl;		/* Player locked onto */
+#ifdef ARMY_SLIDER
+    int     p_armies;		/* XXX: for stats */
+#else
+    short   p_armies;
+#endif				/* ARMY_SLIDER */
+    int     p_fuel;
+    short   p_explode;		/* Keeps track of final explosion */
+    int     p_etemp;
+    short   p_etime;
+    int     p_wtemp;
+    short   p_wtime;
+    short   p_whydead;		/* Tells you why you died */
+    short   p_whodead;		/* Tells you who killed you */
+    struct stats p_stats;	/* player statistics */
+    struct stats2 p_stats2;	/* Paradise stats */
+    short   p_genoplanets;	/* planets taken since last genocide */
+    short   p_genoarmsbomb;	/* armies bombed since last genocide */
+    short   p_planets;		/* planets taken this game */
+    short   p_armsbomb;		/* armies bombed this game */
+    int     p_docked;		/* If starbase, # docked to, else pno base
+				   host */
+    int     p_port[4];		/* If starbase, pno of ship docked to that
+				   port, else p_port[0] = port # docked to on
+				   host.   */
+    short   p_tractor;		/* What player is in tractor lock */
+    int     p_pos;		/* My position in the player file */
+};
+
+struct statentry {
+    char    name[16], password[16];
+    struct stats stats;
+};
+
+/* Torpedo states */
+
+#define TFREE 0
+#define TMOVE 1
+#define TEXPLODE 2
+#define TDET 3
+#define TOFF 4
+#define TSTRAIGHT 5		/* Non-wobbling torp */
+
+struct torp {
+    int     t_no;
+    int     t_status;		/* State information */
+    int     t_owner;
+    int     t_x;
+    int     t_y;
+    unsigned char t_dir;	/* direction */
+    short   t_turns;		/* rate of change of direction if tracking */
+    int     t_damage;		/* damage for direct hit */
+    int     t_speed;		/* Moving speed */
+    int     t_fuse;		/* Life left in current state */
+    char    t_war;		/* enemies */
+    char    t_team;		/* launching team */
+    char    t_whodet;		/* who detonated... */
+    char    frame;		/* frame of animation [BDyess] */
+};
+
+struct thingy {
+    int     t_no;
+    int     t_shape;		/* State information */
+    int     t_owner;
+    int     t_x;
+    int     t_y;
+    unsigned char t_dir;	/* direction */
+    int     t_speed;		/* Moving speed */
+    int     t_fuse;		/* Life left in current state */
+    char    t_war;		/* enemies */
+};
+
+/* Plasma Torpedo states */
+
+#define PTFREE 0
+#define PTMOVE 1
+#define PTEXPLODE 2
+#define PTDET 3
+
+struct plasmatorp {
+    int     pt_no;
+    int     pt_status;		/* State information */
+    int     pt_owner;
+    int     pt_x;
+    int     pt_y;
+    unsigned char pt_dir;	/* direction */
+    short   pt_turns;		/* ticks turned per cycle */
+    int     pt_damage;		/* damage for direct hit */
+    int     pt_speed;		/* Moving speed */
+    int     pt_fuse;		/* Life left in current state */
+    char    pt_war;		/* enemies */
+    char    pt_team;		/* launching team */
+};
+
+#define PHFREE 0x00
+#define PHHIT  0x01		/* When it hits a person */
+#define PHMISS 0x02
+#define PHHIT2 0x04		/* When it hits a photon */
+#ifdef CHECK_DROPPED
+#define PHGHOST 0x80		/* fuse has exceeded longest received so far */
+#endif
+struct phaser {
+    int     ph_status;		/* What it's up to */
+    unsigned char ph_dir;	/* direction */
+    int     ph_target;		/* Who's being hit (for drawing) */
+    int     ph_x, ph_y;		/* For when it hits a torp */
+    int     ph_fuse;		/* Life left for drawing */
+    int     ph_damage;		/* Damage inflicted on victim */
+};
+
+/* An important note concerning planets:  The game assumes that
+    the planets are in a 'known' order.  Ten planets per team,
+    the first being the home planet.
+*/
+
+ /* defines for the pl_flags field of planet struct */
+
+/*
+   pl_flags is an int of 32 bits:
+
+   bits 16 and 23 currently define the type of the planet.  The
+   interpretation of the other bits is dependent upon the planet
+   type.
+
+   Here is the interpretation for a planet
+   bits 0..3			unknown
+   bits 4..6			planetary facilities (REPAIR,FUEL,AGRI)
+   bit  7			redraw (archaic, recyclable?)
+   bits 8..11			old flags (archaic, recyclable?)
+   bits 12..15			paradise planetary facilities
+				(REPAIR,FUEL,AGRI,SHIPY)
+   bit  16			cosmic object type (also bit 23)
+   bits 17,18			planet atmosphere type
+   bits 19..21			planetary surface properties
+				(DILYTH,METAL,ARABLE)
+   bit  22			paradise planet flag (why?)
+   bit  23			cosmic object type (also bit 16)
+   bits 24..31	currently unallocated (8 bits to play with)
+
+   Asteroids are NYI but here is a draft standard:
+   bits 12,15			facilities
+				(REPAIR,FUEL,SHIPY)
+   bit  20			surface properties
+				(DILYTH,METAL)
+   other bits	currently unallocated
+
+   */
+
+/* facilities, bits 4..6 and 12..15
+   valid for planets and asteroids */
+#define PLREPAIR   ((1<<12) | (1<<4))	/* planet can repair ships */
+#define PLFUEL     ((1<<13) | (1<<5))	/* planet has fuel depot */
+#define PLAGRI     ((1<<14) | (1<<6))	/* agricultural thingies built here */
+#define PLSHIPYARD ((1<<15))	/* planet has a shipyard on it */
+#define PLORESMASK (0x7<<4)	/* mask for original resource flags */
+#define PLRESSHIFT       12	/* bit to shift right by for resources */
+#define PLRESMASK  (0xF<<PLRESSHIFT)	/* to mask off all but resource bits */
+
+#define PLREDRAW   (1<<7)	/* Player close for redraw */
+
+#define PLHOME 	   (1<< 8)	/* These 4 flags no longer are */
+#define PLCOUP     (1<< 9)	/* used in the server */
+#define PLCHEAP    (1<<10)
+#define PLCORE     (1<<11)
+
+/* cosmic object types, bits 16 and 23, and 24 */
+#define PLPLANET	0	/* object is a planet */
+#define PLSTAR     (1<<16)	/* object is a star */
+#define PLAST	   (1<<23)	/* object is an asteroid NYI */
+#define PLNEB	   ((1<<16)|(1<<23))	/* object is a nebula NYI */
+#define PLBHOLE    (1<<24)	/* object is a black hole NYI */
+#define PLPULSAR   ((1<<16)|(1<<24))	/* object is a pulsar NYI */
+#define PLUK1      ((1<<23)|(1<<24))	/* future expansion */
+#define PLWHOLE    ((1<<16)|(1<<23)|(1<<24))	/* object is a wormhole */
+#define PLTYPEMASK ((1<<16)|(1<<23)|(1<<24))	/* mask to extract object
+						   type */
+#define PL_TYPE(p) ( (p).pl_flags & PLTYPEMASK )
+
+/* Atmosphere Types, bits 17 and 18.
+   Valid for planets.
+   */
+#define PLATSHIFT	 17	/* number of right bit shifts for atmos bits */
+#define PLPOISON   (0<<PLATSHIFT)	/* poison atmosphere, no army growth */
+#define PLATYPE3   (1<<PLATSHIFT)	/* slightly toxic, very slow army
+					   growth */
+#define PLATYPE2   (2<<PLATSHIFT)	/* thin atmosphere, slow army growth */
+#define PLATYPE1   (3<<PLATSHIFT)	/* normal human atmosphere, normal
+					   growth */
+#define PLATMASK   (0x3<<PLATSHIFT)	/* to mask off everything but atmos
+					   bits */
+
+/* Surface Properties, bits 19..21
+   Valid for planets and asteroids.
+   */
+#define PLBARREN   0		/* rocky barren surface */
+#define PLSURSHIFT 	 19	/* number of bit shift to surface */
+#define PLDILYTH   (1<<(PLSURSHIFT+0))	/* dilythium deposits on the planet */
+#define PLMETAL    (1<<(PLSURSHIFT+1))	/* metal deposits on the planet */
+#define PLARABLE   (1<<(PLSURSHIFT+2))	/* planet has farmland */
+#define PLSURMASK  (0x7<<PLSURSHIFT)	/* number of surface combinations */
+
+
+#define PLPARADISE (1<<22)	/* Paradise server flag set to 1 for P server */
+
+
+struct planet {
+    int     pl_no;
+    int     pl_flags;		/* State information */
+    int     pl_owner;
+    int     pl_x;
+    int     pl_y;
+    char    pl_name[16];
+    int     pl_namelen;		/* Cuts back on strlen's */
+    int     pl_armies;
+    int     pl_info;		/* Teams which have info on planets */
+    int     pl_deadtime;	/* Time before planet will support life */
+    int     pl_couptime;	/* Time before coup may take place */
+    int     pl_timestamp;	/* time the info was taken */
+};
+
+struct t_unit {
+/*  int	    alt1;*/
+/*  int     alt2;*/		/* Terrain types. */
+    char types;
+};
+
+/* Terrain types */
+#define T_EMPTY_SPACE 0x00
+#define T_ASTEROIDS   0x01
+#define T_NEBULA      0x02
+#define T_RADIATION   0x04
+#define T_EXPANSN1    0x08
+#define T_EXPANSN2    0x10
+#define T_EXPANSN3    0x20
+#define T_EXPANSN4    0x40
+#define T_EXPANSN5    0x80
+
+struct _clearzone {
+    int     x, y;
+    int     width, height;
+};
+
+#ifndef SHORT_PACKETS
+#define MVALID 0x01
+#define MINDIV 0x02
+#define MTEAM  0x04
+#define MALL   0x08
+#define MGOD   0x10
+#define MCAST  0x18		/* not an offial packet type. only */
+                                /* used in smessage to stay orthogonal */
+#else
+#define MVALID 0x01
+#define MGOD   0x10
+#define MMOO   0x12
+
+#ifdef TOOLS
+#define MTOOLS 0x14
+#endif
+
+/* order flags by importance (0x100 - 0x400) */
+/* restructuring of message flags to squeeze them all into 1 byte - jmn */
+/* hopefully quasi-back-compatible:
+   MVALID, MINDIV, MTEAM, MALL, MGOD use up 5 bits. this leaves us 3 bits.
+   since the server only checks for those flags when deciding message
+   related things and since each of the above cases only has 1 flag on at
+   a time we can overlap the meanings of the flags */
+
+#define MINDIV 0x02
+/* these go with MINDIV flag */
+#ifdef STDBG
+#define MDBG   0x20
+#endif
+#define MCONFIG 0x40		/* config messages from server */
+#define MDIST 0x60		/* flag distress messages - client thing
+				   really but stick it in here for
+				   consistency */
+#define MCAST 0x18		/* not an offial packet type. only */
+                                /* used in smessage.c to stay orthogonal */
+
+#define MTEAM  0x04
+/* these go with MTEAM flag */
+#define MTAKE  0x20
+#define MDEST  0x40
+#define MBOMB  0x60
+#define MCOUP1 0x80
+#define MCOUP2 0xA0
+#define MDISTR 0xC0
+
+#define MALL   0x08
+/* these go with MALL flag */
+#define MGENO  0x20		/* MGENO is not used in INL server but
+				   belongs here */
+#define MCONQ  0x20		/* not enought bits to distinguish
+				   MCONQ/MGENO :-( */
+#define MKILLA 0x40
+#define MKILLP 0x60
+#define MKILL  0x80
+#define MLEAVE 0xA0
+#define MJOIN  0xC0
+#define MGHOST 0xE0
+/* MMASK not used in INL server */
+
+/* to flag multi-line macros */
+#define MMACRO 0x80
+
+#define MWHOMSK  0x1f		/* mask with this to find who msg to */
+#define MWHATMSK 0xe0		/* mask with this to find what message about */
+
+/*   old flags...
+#define MVALID 0x01
+#define MINDIV 0x02
+#define MTEAM  0x04
+#define MALL   0x08
+#define MGOD   0x10
+
+#define MGENO  0x100            order these by importance (0x100 - 0x400)
+#define MCONQ  0x110
+#define MTAKE  0x120
+#define MDEST  0x130
+#define MKILLA 0x200
+#define MBOMB  0x210
+#define MKILLP 0x220
+#define MKILL  0x230
+#define MLEAVE 0x300
+#define MJOIN  0x310
+#define MGHOST 0x320
+#define MCOUP1 0x330
+#define MCOUP2 0x340    end of old flags  */
+#endif
+
+struct message {
+    int     m_no;
+    int     m_flags;
+    int     m_time;
+    int     m_recpt;
+    char    m_data[80];
+};
+
+/* message control structure */
+
+struct mctl {
+    int     mc_current;
+};
+
+/* This is a structure used for objects returned by mouse pointing */
+
+#define PLANETTYPE 0x1
+#define PLAYERTYPE 0x2
+
+struct obtype {
+    int     o_type;
+    int     o_num;
+};
+
+struct id {
+    char   *name;
+    int     team;
+    int     number;
+    int     type;
+    char    mapstring[4];
+};
+
+struct rank {
+    float   hours, ratings, defense;
+    char   *name;
+};
+
+struct rank2 {			/* Paradise ranks */
+    int     genocides;		/* minimum number of genocides */
+    float   di;			/* minimum destruction inflicted */
+    float   battle;		/* minimum battle ratings */
+    float   strategy;		/* minimum strategy ratings */
+    float   specship;		/* minimum total ratings in a specialty */
+    /* ship  SB + WB + JS */
+    char   *name;		/* name of this rank */
+};
+
+
+struct royalty {		/* Paradise royalty ranks */
+    char   *name;		/* name of rank */
+};
+
+struct plupdate {
+
+    int     plu_update;
+    int     plu_x, plu_y;
+};
+
+#ifdef MACROS
+#define MACSINGLE 1
+#define MACRCD 2
+#define MACMULTI 4
+struct macro {
+    char    flags;		/* WAS isSingleMacro; now, uses above flags */
+    INT8    to;			/* if to team, rom, etc put here or -1 */
+    char    specialto;		/* player nearest mouse, etc here */
+    struct macro *next;		/* for multi-line macros, points to a struct
+				   *distress if MACRCD flag set. -JR */
+    char   *string;		/* string to be sent, % escapes intact */
+};
+#endif				/* MACROS */
+
+struct stringlist {
+    char   *string;
+    char   *value;
+    struct stringlist *next, *prev;
+    int searched;
+};
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/time.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,58 @@
+/* $Id: time.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+#ifdef HANDLER_TIMES
+#include <stdio.h>
+#include <sys/time.h>
+
+unsigned long avg[70], count[70];
+struct timeval pre, post;
+
+void print_times(void);
+void log_time(int type, struct timeval *pre, struct timeval *post)
+{
+    static int init=0;
+    unsigned long usecs;
+    int i;
+
+    if(!init) {
+	for(i=0;i<70;i++)
+	    avg[i] = count[i] = 0;
+	init=1;
+	atexit(print_times);
+    }
+
+    usecs = (post->tv_sec * 1000000 + post->tv_usec) - 
+            ( pre->tv_sec * 1000000 +  pre->tv_usec); 
+    avg[type] = ((avg[type]*count[type])+usecs)/(count[type]+1);
+    count[type]++;
+}
+    
+void print_times()
+{
+    int i, t_cnt=0, t_avg=0;
+    
+    printf("Packet handler average times:\n");
+    printf("Type Count Average time (secs)\n");
+    for(i=0;i<70;i++) {
+	if(count[i]) {
+	    printf("  %2d %5d %8.7f\n",i,count[i],(double)((double)avg[i]/1000000.0));
+	    t_cnt+=count[i];
+	    t_avg+=avg[i];
+	}
+    }
+    t_avg /= t_cnt;
+    printf("Totals:\n");
+    printf("  -- %5d, %8.7f\n", t_cnt, (double)((double)t_avg/1000000.0));
+}
+
+start_log()
+{
+    gettimeofday(&pre, 0);
+}
+
+stop_log(int type)
+{
+    gettimeofday(&post, 0);
+    log_time(type, &pre, &post);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,59 @@
+/* $Id: tools.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/* tools.c - shell escape, graphic toolsw - 10/10/93
+ * 
+ * copyright 1993 Kurt Siegl <siegl@risc.uni-linz.ac.at> Free to use, hack, etc.
+ * Just keep these credits here. Use of this code may be dangerous to your
+ * health and/or system. Its use is at your own risk. I assume no
+ * responsibility for damages, real, potential, or imagined, resulting  from
+ * the use of it.
+ * 
+ */
+
+#ifdef TOOLS
+#include <stdio.h>
+#include "math.h"
+#include <signal.h>
+#include <sys/types.h>
+#include <strings.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+
+void
+sendTools(str)
+char *str;
+{
+  char    pipebuf[100];
+  FILE   *pipefp;
+  int     len;
+
+  if (!W_IsMapped(toolsWin))
+    showToolsWin();
+  signal(SIGCHLD, SIG_DFL);
+  if (shelltools && (pipefp = popen(str, "r")) != NULL)
+    {
+      while (fgets(pipebuf, 80, pipefp) != NULL)
+	{
+	  len = strlen(pipebuf);
+	  if (pipebuf[len - 1] == '\n')
+	    pipebuf[len - 1] = '\0';
+	  W_WriteText(toolsWin, 0, 0, textColor, pipebuf,
+		      strlen(pipebuf), W_RegularFont);
+	}
+      pclose(pipefp);
+    }
+  else
+    W_WriteText(toolsWin, 0, 0, textColor, str, strlen(str), W_RegularFont);
+}
+
+showToolsWin()
+{
+  if (W_IsMapped(toolsWin))
+    W_UnmapWindow(toolsWin);
+  else
+    W_MapWindow(toolsWin);
+}
+
+#endif /* TOOLS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/udpopt.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,227 @@
+/* $Id: udpopt.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * udpopt.c - present UDP control window
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+#define UDPBORDER	2
+#define UDPLEN		35
+
+/* Set up the UDP control window */
+void
+udpwindow()
+{
+    register int i;
+
+    for (i = 0; i < UDP_NUMOPTS; i++)
+	udprefresh(i);
+
+    /* Map window */
+    W_MapWindow(udpWin);
+}
+
+/*
+ * Refresh item i
+ */
+void
+udprefresh(i)
+    int     i;
+{
+    char    buf[BUFSIZ];
+
+    switch (i) {
+    case UDP_CURRENT:
+	sprintf(buf, "UDP channel is %s", (commMode == COMM_TCP) ?
+		"CLOSED" : "OPEN");
+	break;
+    case UDP_STATUS:
+	strcpy(buf, "> Status: ");
+	switch (commStatus) {
+	case STAT_CONNECTED:
+	    strcat(buf, "Connected");
+	    break;
+	case STAT_SWITCH_UDP:
+	    strcat(buf, "Requesting switch to UDP");
+	    break;
+	case STAT_SWITCH_TCP:
+	    strcat(buf, "Requesting switch to TCP");
+	    break;
+	case STAT_VERIFY_UDP:
+	    strcat(buf, "Verifying UDP connection");
+	    break;
+	default:
+	    fprintf(stderr, "netrek: UDP error: bad commStatus (%d)\n",
+		    commStatus);
+	}
+	break;
+    case UDP_DROPPED:
+	sprintf(buf, "> UDP trans dropped: %d (%d%% | %d%%)", udpDropped,
+		udpDropped * 100 / udpTotal,	/* (udpTotal always > 0) */
+		udpRecentDropped * 100 / UDP_RECENT_INTR);
+	break;
+    case UDP_SEQUENCE:
+	sprintf(buf, "Sequence checking is %s", (udpSequenceChk) ?
+		"ON" : "OFF");
+	break;
+    case UDP_DEBUG:
+	sprintf(buf, "Debugging info is ");
+	switch (udpDebug) {
+	case 0:
+	    strcat(buf, "OFF");
+	    break;
+	case 1:
+	    strcat(buf, "ON (connect msgs only)");
+	    break;
+	case 2:
+	    strcat(buf, "ON (verbose output)");
+	    break;
+	}
+	break;
+    case UDP_SEND:
+	sprintf(buf, "Sending with ");
+	switch (udpClientSend) {
+	case 0:
+	    strcat(buf, "TCP only");
+	    break;
+	case 1:
+	    strcat(buf, "simple UDP");
+	    break;
+	case 2:
+	    strcat(buf, "enforced UDP (state only)");
+	    break;
+	case 3:
+	    strcat(buf, "enforced UDP (state & weap)");
+	    break;
+	}
+	break;
+    case UDP_RECV:
+	sprintf(buf, "Receiving with ");
+	switch (udpClientRecv) {
+	case MODE_TCP:
+	    strcat(buf, "TCP only");
+	    break;
+	case MODE_SIMPLE:
+	    strcat(buf, "simple UDP");
+	    break;
+	case MODE_FAT:
+	    strcat(buf, "fat UDP");
+	    break;
+#ifdef DOUBLE_UDP
+	case MODE_DOUBLE:
+	    strcat(buf, "double UDP");
+	    break;
+#endif				/* DOUBLE_UDP */
+	}
+	break;
+    case UDP_FORCE_RESET:
+	sprintf(buf, "Force reset to TCP");
+	break;
+    case UDP_UPDATE_ALL:
+	sprintf(buf, "Request full update (=)");
+	break;
+#ifdef GATEWAY
+    case UDP_GW:
+	sprintf(buf, "gw: %s %d/%d/%d", gw_mach, gw_serv_port, gw_port,
+		gw_local_port);
+	break;
+#endif
+    case UDP_DONE:
+	strcpy(buf, "Done");
+	break;
+    default:
+	fprintf(stderr, "netrek: UDP error: bad udprefresh(%d) call\n", i);
+    }
+
+    W_WriteText(udpWin, 0, i, textColor, buf, strlen(buf), 0);
+}
+
+void
+udpaction(data)
+    W_Event *data;
+{
+    register int i;
+
+    switch (data->y) {
+    case UDP_CURRENT:
+	if (commMode == COMM_TCP)
+	    sendUdpReq(COMM_UDP);
+	else
+	    sendUdpReq(COMM_TCP);
+	break;
+
+    case UDP_STATUS:
+    case UDP_DROPPED:
+	W_Beep();
+	break;
+    case UDP_SEQUENCE:
+	udpSequenceChk = !udpSequenceChk;
+	udprefresh(UDP_SEQUENCE);
+	break;
+    case UDP_SEND:
+	udpClientSend++;
+	if (udpClientSend > 3)
+	    udpClientSend = 0;
+	udprefresh(UDP_SEND);
+	break;
+    case UDP_RECV:
+	udpClientRecv++;
+#ifdef DOUBLE_UDP
+	if (udpClientRecv > MODE_DOUBLE)
+	    udpClientRecv = 0;
+#else
+	if (udpClientRecv >= MODE_DOUBLE)
+	    udpClientRecv = 0;
+#endif
+	udprefresh(UDP_RECV);
+	sendUdpReq(COMM_MODE + udpClientRecv);
+	break;
+    case UDP_DEBUG:
+	udpDebug++;
+	if (udpDebug > 2)
+	    udpDebug = 0;
+	udprefresh(UDP_DEBUG);
+	break;
+    case UDP_FORCE_RESET:
+	/* clobber UDP */
+	UDPDIAG(("*** FORCE RESET REQUESTED\n"));
+	sendUdpReq(COMM_TCP);
+	commMode = commModeReq = COMM_TCP;
+	commStatus = STAT_CONNECTED;
+	commSwitchTimeout = 0;
+	udpClientSend = udpClientRecv = udpSequenceChk = udpTotal = 1;
+	udpDebug = udpDropped = udpRecentDropped = 0;
+	if (udpSock >= 0)
+	    closeUdpConn();
+	for (i = 0; i < UDP_NUMOPTS; i++)
+	    udprefresh(i);
+	break;
+    case UDP_UPDATE_ALL:
+	sendUdpReq(COMM_UPDATE);
+	break;
+#ifdef GATEWAY
+    case UDP_GW:
+	W_Beep();
+	break;
+#endif
+    case UDP_DONE:
+	udpdone();
+	break;
+    }
+}
+
+void
+udpdone()
+{
+    /* Unmap window */
+    W_UnmapWindow(udpWin);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,289 @@
+/* $Id: util.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * util.c
+ * added functionality to gettarget() - Bill Dyess 10/6/93
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include <stdlib.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+#include "gameconf.h"
+
+#if 0
+/*
+** Provide the angular distance between two angles.
+*/
+angdist(x, y)
+    unsigned char x, y;
+{
+    register unsigned char res;
+
+    if (x > y)
+	res = x - y;
+    else
+	res = y - x;
+    if (res > 128)
+	return (256 - (int) res);
+    return ((int) res);
+}
+#endif
+
+double
+hypot2(x, y)
+    double  x, y;
+{
+    return sqrt(x * x + y * y);
+}
+
+/*
+ * * Find the object nearest mouse.  Returns a pointer to an * obtype
+ * structure.  This is used for info and locking on. *
+ *
+ * Because we are never interested in it, this function will * never return
+ * your own ship as the target. *
+ *
+ * Finally, this only works on the two main windows
+*/
+
+static struct obtype _target;
+
+struct obtype *
+gettarget(ww, x, y, targtype)
+    W_Window ww;
+    int     x, y;
+    int     targtype;
+{
+/* now can get the closest friendly/enemy player or planet.  Use
+   TARG_FRIENDLY or TARG_ENEMY or'd with TARG_PLAYER or TARG_PLANET */
+    register int i;
+    register struct player *j;
+    register struct planet *k;
+    int     g_x, g_y, friendly;
+    double  dist, closedist;
+    int     slotnum, width;
+
+    if (ww == mapw) {
+	register gwidth, offsetx, offsety;
+	if (blk_zoom) {
+	    gwidth = blk_gwidth / 2;
+	    offsetx = zoom_offset(me->p_x);
+	    offsety = zoom_offset(me->p_y);
+	} else {
+	    gwidth = blk_gwidth;
+	    offsetx = 0;
+	    offsety = 0;
+	}
+	g_x = x * (gwidth / WINSIDE) + offsetx;
+	g_y = y * (gwidth / WINSIDE) + offsety;
+
+    } else if (ww == playerw) {
+	if (targtype & TARG_PLAYER) {
+	    W_TranslatePoints(playerw, &x, &y);
+	    y -= 2;
+	    if (y < 0)
+		y = 0;
+	    if (*playerList == 0 || *playerList == ',') {
+		if (y > 15)
+		    y = 15;
+		slotnum = y;
+		width = W_WindowWidth(ww);
+		if (x > width / 2)
+		    slotnum += 16;
+	    } else {
+		slotnum = y;
+	    }
+	    if (slot[slotnum] != -1 &&
+		(paradise || !(players[slot[slotnum]].p_flags & PFCLOAK))) {
+		/* don't show info for cloakers on Bronco servers */
+		_target.o_type = PLAYERTYPE;
+		_target.o_num = slot[slotnum];
+		return &_target;
+	    }
+	    return NULL;	/* no target found */
+	} else {
+	    g_x = me->p_x + ((x - WINSIDE / 2) * SCALE);
+	    g_y = me->p_y + ((y - WINSIDE / 2) * SCALE);
+	}
+    } else if (ww) {		/* tactical window */
+	g_x = me->p_x + ((x - WINSIDE / 2) * SCALE);
+	g_y = me->p_y + ((y - WINSIDE / 2) * SCALE);
+    } else {
+	g_x = x;
+	g_y = y;
+    }
+    closedist = blk_gwidth;
+
+    if (targtype & TARG_ASTRAL) {
+	for (i = 0, k = &planets[0]; i < nplanets; i++, k++) {
+	    int     ptype = 0;
+	    friendly = friendlyPlanet(k);
+	    if (friendly && (targtype & TARG_ENEMY))
+		continue;
+	    if (!friendly && (targtype & TARG_FRIENDLY))
+		continue;
+	    if (k->pl_owner != idx_to_mask(me->p_teami) && (targtype & TARG_TEAM))
+		continue;
+	    switch (PL_TYPE(*k)) {
+	    case PLPLANET:
+		ptype = TARG_PLANET;
+		break;
+	    case PLSTAR:
+		ptype = TARG_STAR;
+		break;
+	    case PLAST:
+		ptype = TARG_PLANET;
+		break;
+	    case PLNEB:
+		ptype = TARG_NEBULA;
+		break;
+	    case PLBHOLE:
+		ptype = TARG_BLACKHOLE;
+		break;
+	    case PLPULSAR:
+		ptype = TARG_STAR;
+		break;
+	    }
+	    if (!(ptype & targtype))
+		continue;
+	    dist = hypot((double) (g_x - k->pl_x), (double) (g_y - k->pl_y));
+	    if (dist < closedist) {
+		_target.o_type = PLANETTYPE;
+		_target.o_num = i;
+		closedist = dist;
+	    }
+	}
+    }
+    if (targtype & TARG_PLAYER) {
+	for (i = 0, j = &players[i]; i < nplayers; i++, j++) {
+	    if (j->p_status != PALIVE)
+		continue;
+	    if ((j->p_flags & PFCLOAK) && (!(targtype & TARG_CLOAK)) && j != me)
+		continue;
+	    if (j == me && !(targtype & TARG_SELF))
+		continue;
+	    friendly = friendlyPlayer(j);
+	    if (friendly && (targtype & TARG_ENEMY))
+		continue;
+	    if (!friendly && (targtype & TARG_FRIENDLY))
+		continue;
+	    if (j->p_teami != me->p_teami && targtype & TARG_TEAM)
+		continue;
+	    if (!(targtype & (isBase(j->p_ship->s_type)
+			      ? TARG_BASE
+			      : TARG_SHIP)))
+		continue;
+	    dist = hypot((double) (g_x - j->p_x), (double) (g_y - j->p_y));
+	    if (dist <= closedist) {
+		_target.o_type = PLAYERTYPE;
+		_target.o_num = i;
+		closedist = dist;
+	    }
+	}
+    }
+    if (closedist == blk_gwidth) {	/* Didn't get one.  bad news */
+	_target.o_type = PLAYERTYPE;
+	_target.o_num = me->p_no;	/* Return myself.  Oh well... */
+	return (&_target);
+    } else {
+	return (&_target);
+    }
+}
+
+#ifdef hpux
+
+srandom(foo)
+    int     foo;
+{
+    rand(foo);
+}
+
+random()
+{
+    return (rand());
+}
+
+#include <time.h>
+#include <sys/resource.h>
+
+#include <sys/signal.h>
+
+void    (*
+	 signal(sig, funct)) ()
+    int     sig;
+    void    (*funct) ();
+{
+    struct sigvec vec, oldvec;
+
+    sigvector(sig, 0, &vec);
+    vec.sv_handler = funct;
+    sigvector(sig, &vec, (struct sigvec *) 0);
+}
+#endif				/* hpux */
+
+
+char   *
+team_bit_string(mask)
+    int     mask;
+{
+    static char visitorstring[16];	/* better not have more than 16 teams */
+    int     i;
+
+    for (i = 0; i < number_of_teams; i++) {
+	visitorstring[i] = (mask & (1 << i)) ? teaminfo[i].letter : ' ';
+    }
+    visitorstring[i] = 0;
+    return visitorstring;
+}
+
+/* getTargetID returns an id stuct containing then name of the object, the
+   type of object, the number of the object, the
+   team the object belongs to, and .  Used a lot in the macro code.
+   [BDyess] */
+
+struct id *
+getTargetID(ww, x, y, targtype)
+    W_Window ww;
+    int     x, y;
+    int     targtype;
+{
+    struct obtype *target;
+    static struct id buf;
+    struct player *j;
+    struct planet *k;
+
+    target = gettarget(ww, x, y, targtype);
+    if (target->o_type == PLAYERTYPE) {
+	buf.type = PLAYERTYPE;
+	j = &players[target->o_num];
+	buf.name = j->p_name;
+	buf.number = target->o_num;
+	buf.team = j->p_teami;
+	buf.mapstring[0] = j->p_mapchars[0];
+	buf.mapstring[1] = j->p_mapchars[1];
+	buf.mapstring[2] = 0;
+    } else if (target->o_type == PLANETTYPE) {
+	buf.type = PLANETTYPE;
+	k = &planets[target->o_num];
+	buf.name = k->pl_name;
+	buf.number = target->o_num;
+	buf.team = mask_to_idx(k->pl_owner);
+	if (0 == strncmp(k->pl_name, "New ", 4)) {
+	    strncpy(buf.mapstring, k->pl_name + 4, 3);
+	} else if (0 == strncmp(k->pl_name, "Planet ", 7)) {
+	    strncpy(buf.mapstring, k->pl_name + 7, 3);
+	} else
+	    strncpy(buf.mapstring, k->pl_name, 3);
+	buf.mapstring[3] = 0;
+    } else {			/* tried to find something that doesn't exist */
+	return NULL;
+    }
+    return &buf;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/varydamage.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,103 @@
+/* $Id: varydamage.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * redraw.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <signal.h>
+#include <math.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+#include "gameconf.h"
+
+void
+doShields(dx, dy, ship_bits, j)
+    int     dx, dy;
+    struct ship_shape *ship_bits;
+    struct player *j;
+{
+    if (showShields && (j->p_flags & PFSHIELD)) {
+	/*-----------Colored shields by shield damage--------*/
+
+	int     color = playerColor(j);
+	if (show_shield_dam && j == me) {
+	    float   ft;
+
+	    ft = (float) j->p_shield / (float) j->p_ship->s_maxshield;
+	    if (ft > 0.66)
+		color = gColor;
+	    else if (ft > 0.33)
+		color = yColor;
+	    else if (j->p_shield > 5)
+		color = rColor;
+	    else
+		color = unColor;
+	}
+#if 0				/* shields the alert color, ick */
+	switch (me->p_flags & (PFGREEN | PFYELLOW | PFRED)) {
+	case PFGREEN:
+	    color = gColor;
+	    break;
+	case PFYELLOW:
+	    color = yColor;
+	    break;
+	    /* red shield tough to see */
+	case PFRED:
+	    color = playerColor(j);
+	    break;
+	}
+#endif
+	W_WriteBitmap(dx - (ship_bits->width / 2),
+		      dy - (ship_bits->height / 2),
+		      ship_bits->shield, color);
+    }
+}
+
+#ifdef VARY_HULL
+void
+doHull(dx, dy, ship_bits, j)
+    int     dx, dy;
+    struct ship_shape *ship_bits;
+    struct player *j;
+{
+    if (j == me && vary_hull) {
+	int     hull_left = (100 * (me->p_ship->s_maxdamage -
+		     me->p_damage)) / me->p_ship->s_maxdamage, hull_num = 7;
+	int     hull_color;
+
+	if (hull_left <= 16) {
+	    hull_num = 0;
+	    hull_color = W_Red;
+	} else if (hull_left <= 28) {
+	    hull_num = 1;
+	    hull_color = W_Red;
+	} else if (hull_left <= 40) {
+	    hull_num = 2;
+	    hull_color = W_Red;
+	} else if (hull_left <= 52) {
+	    hull_num = 3;
+	    hull_color = W_Yellow;
+	} else if (hull_left <= 64) {
+	    hull_num = 4;
+	    hull_color = W_Yellow;
+	} else if (hull_left <= 76) {
+	    hull_num = 5;
+	    hull_color = W_Yellow;
+	} else if (hull_left <= 88) {
+	    hull_num = 6;
+	    hull_color = W_Green;
+	} else
+	    hull_color = W_Green /* playerColor (j) */ ;
+
+	W_WriteBitmap(dx - (ship_bits->width / 2 + 1),
+		      dy - (ship_bits->height / 2 + 1),
+		      hull[hull_num], hull_color);
+    }
+}
+#endif				/* VARY_HULL */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/war.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,103 @@
+/* $Id: war.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * war.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "packets.h"
+#include "proto.h"
+
+static int newhostile;
+
+/* Set up the war window and map it */
+static char *feds = "FED - ";
+static char *roms = "ROM - ";
+static char *klis = "KLI - ";
+static char *oris = "ORI - ";
+static char *gos = "  Re-program";
+static char *exs = "  Exit - no change";
+static char *peaces = "Peace";
+static char *hostiles = "Hostile";
+static char *wars = "War";
+
+/* Prototypes */
+static void fillwin P((int menunum, char *string, int hostile, int warbits, int team));
+static void warrefresh P((void));
+
+void
+warwindow()
+{
+    W_MapWindow(war);
+    newhostile = me->p_hostile;
+    warrefresh();
+}
+
+static void
+warrefresh()
+{
+    fillwin(0, feds, newhostile, me->p_swar, FEDm);
+    fillwin(1, roms, newhostile, me->p_swar, ROMm);
+    fillwin(2, klis, newhostile, me->p_swar, KLIm);
+    fillwin(3, oris, newhostile, me->p_swar, ORIm);
+    W_WriteText(war, 0, 4, textColor, gos, strlen(gos), 0);
+    W_WriteText(war, 0, 5, textColor, exs, strlen(exs), 0);
+}
+
+static void
+fillwin(menunum, string, hostile, warbits, teammask)
+    int     menunum;
+    char   *string;
+    int     hostile, warbits;
+    int     teammask;
+{
+    char    buf[80];
+
+    if (teammask & warbits) {
+	(void) sprintf(buf, "  %s%s", string, wars);
+	W_WriteText(war, 0, menunum, rColor, buf, strlen(buf), 0);
+    } else if (teammask & hostile) {
+	(void) sprintf(buf, "  %s%s", string, hostiles);
+	W_WriteText(war, 0, menunum, yColor, buf, strlen(buf), 0);
+    } else {
+	(void) sprintf(buf, "  %s%s", string, peaces);
+	W_WriteText(war, 0, menunum, gColor, buf, strlen(buf), 0);
+    }
+}
+
+void
+waraction(data)
+    W_Event *data;
+{
+    int     enemymask;
+
+    if (data->y == 4) {
+	W_UnmapWindow(war);
+	sendWarReq(newhostile);
+	return;
+    }
+    if (data->y == 5) {
+	W_UnmapWindow(war);
+	return;
+    }
+    enemymask = 1 << data->y;
+
+    if (me->p_swar & enemymask) {
+	warning("You are already at war!");
+	W_Beep();
+    } else {
+	if (idx_to_mask(me->p_teami) == enemymask) {
+	    warning("It would never work ... your crew would have you in the brig in no time.");
+	} else {
+	    newhostile ^= enemymask;
+	}
+    }
+    warrefresh();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/warning.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,153 @@
+/* $Id: warning.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*
+ * warning.c
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include <math.h>
+#include <signal.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#ifdef hupx
+#include <time.h>
+#else				/* hpux */
+#include <sys/time.h>
+#endif				/* hpux */
+#ifdef RS6K
+struct tm {
+    int     tm_sec;		/* seconds (0 - 59) */
+    int     tm_min;		/* minutes (0 - 59) */
+    int     tm_hour;		/* hours (0 - 23) */
+    int     tm_mday;		/* day of month (1 - 31) */
+    int     tm_mon;		/* month of year (0 - 11) */
+    int     tm_year;		/* year - 1900 */
+    int     tm_wday;		/* day of week (Sunday = 0) */
+    int     tm_yday;		/* day of year (0 - 365) */
+    int     tm_isdst;		/* flag: daylight savings time in effect */
+    long    tm_gmtoff;		/* offset from GMT in seconds */
+    char   *tm_zone;		/* abbreviation of timezone name */
+
+};
+
+#endif
+
+#define W_XOFF 5
+#ifndef AMIGA
+#define W_YOFF 5
+#else
+#define W_YOFF 1
+#endif
+
+char   *
+timeString(t)
+    time_t  t;
+/* returns a string of the form hour:minute:second */
+{
+    static char *s = NULL;
+    struct tm *tm;
+
+    if (!s)
+	s = (char *) malloc(9);
+    if (t > 24 * 60 * 60) {
+	tm = localtime(&t);
+	sprintf(s, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
+    } else
+	sprintf(s, "%02d:%02d:%02d", (int) (t / (60 * 60)), (int) ((t % (60 * 60)) / 60),
+		(int) (t % 60));
+    return s;
+}
+
+/*
+   ** The warning in text will be printed in the warning window.
+   ** The message will last WARNTIME/10 seconds unless another message
+   ** comes through and overwrites it.
+ */
+
+void
+warning(text)
+    char   *text;
+{
+    /* long curtime; */
+    /* char timebuf[10]; */
+    /* struct tm *tm; */
+    char    newtext[91];	/* infinite appending fix - jn */
+    int     len;
+
+    char   *d;
+    int     dmg;
+    float   phasRatio, avgDmg;
+    int     thisHit = 0;
+
+    newtext[0] = '\0';
+    warntimer = udcounter + WARNTIME;	/* set the line to be cleared */
+
+    if (warncount > 0) {
+	/* XFIX */
+	W_ClearArea(warnw, W_XOFF, W_YOFF, W_Textwidth * warncount, W_Textheight);
+    }
+    warncount = strlen(text);
+    W_WriteText(warnw, W_XOFF, W_YOFF, textColor, text, warncount, W_RegularFont);
+    if (strncmp(text, "Phaser", 6) == 0) {
+	if (strncmp(text + 7, "missed", 6) == 0) {
+	    phasFired++;
+	    if (!logPhaserMissed)
+		return;
+	    thisHit = 0;
+	} else if (strncmp(text + 7, "burst", 5) != 0 &&
+		   strncmp(text + 7, "shot", 4) != 0)
+	    return;
+	else {			/* a hit! */
+	    phasFired++;
+	    phasHits++;
+	    thisHit = 1;
+	}
+
+	if (phaserStats) {
+	    if (thisHit) {
+		d = &text[strlen(text)];
+
+		while (!isdigit(*d) && d > text)	/* find the last number
+							   in the string, should
+							   be damage */
+		    d--;
+		while (d > text && isdigit(*d))
+		    d--;
+
+		if (d > text) {
+		    dmg = atoi(d);
+		    totalDmg += dmg;
+		    avgDmg = (float) totalDmg / (float) phasHits;
+		    phasRatio = (100 * phasHits) / (float) phasFired;
+		    sprintf(newtext, "Av:%5.2f, Hit:%5.2f%%: ", avgDmg, phasRatio);
+		}
+	    } else {		/* a miss */
+		sprintf(newtext, "Hit: %d, Miss: %d, Dmg: %d: ", phasHits, phasFired - phasHits, totalDmg);
+	    }
+	} else {		/* not keeping phaser stats right now */
+	    phasFired--;
+	    if (thisHit)
+		phasHits--;
+	    newtext[0] = '\0';
+	}
+	strncat(newtext, text, 80);
+	len = strlen(newtext);
+	newtext[len++] = ' ';
+	strcpy(newtext + len, timeString(time(NULL)));
+	warncount = warncount + 9;
+
+	dmessage(newtext, 0, 254, 0);
+
+    } else if (strncmp(text, "Missile away", 12) == 0) {
+	/* missile total kludge.  No value until one is shot :( */
+	me->p_totmissiles = atoi(text + 13);
+    } else if (strcmp(text, "Prepping for warp jump") == 0) {
+	/* keep track of when in warp prep */
+	me->p_flags |= PFWARPPREP;
+    } else if (strcmp(text, "Warp drive aborted") == 0) {
+	me->p_flags &= ~PFWARPPREP;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wide_plist.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,730 @@
+/* $Id: wide_plist.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+
+#ifdef WIDE_PLIST
+#define PLIST1
+#define PLIST2
+#define PLIST
+/*
+ * playerlist.c
+ *
+ *   Fairly substantial re-write to do variable player lists: Sept 93 DRG
+ *   Paradise shoehorning:  2/13/94  [BDyess]
+ */
+#include "copyright.h"
+
+#include <stdio.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "gameconf.h"
+#include "proto.h"
+
+static char header[BUFSIZ];
+int     header_len=0;
+char   *old_playerList=NULL;
+char  **slottext=NULL;		/* array of strings shown in each slot
+				   [BDyess] */
+W_Color *slotcolors=NULL;		/* array of colors, one per slot [BDyess] */
+int     slottext_size=0;		/* keep track of the size in case nplayers
+				   changes */
+
+/*===========================================================================*/
+
+int
+playerlistnum()
+{
+    int     num = 0;
+    char   *ptr;
+    int     i;
+
+    ptr = playerList;
+    header[0] = '\0';
+    while (ptr[0] != '\0' && ptr[0] != ',') {
+	switch (ptr[0]) {
+	case 'n':		/* Ship Number */
+	    strcat(header, " No");
+	    num += 3;
+	    break;
+	case 'T':		/* Ship Type */
+	    strcat(header, " Ty");
+	    num += 3;
+	    break;
+	case 'R':		/* Rank */
+	    strcat(header, " Rank      ");
+	    num += 11;
+	    break;
+	case 'N':		/* Name */
+	    strcat(header, " Name            ");
+	    num += 17;
+	    break;
+	case 'K':		/* Kills */
+	    strcat(header, " Kills");
+	    num += 6;
+	    break;
+	case 'l':		/* Login Name */
+	    strcat(header, " Login           ");
+	    num += 17;
+	    break;
+	case 'O':		/* Offense */
+	    strcat(header, " Offse");
+	    num += 6;
+	    break;
+	case 'W':		/* Wins */
+	    strcat(header, "  Wins");
+	    num += 6;
+	    break;
+	case 'D':		/* Defense */
+	    strcat(header, " Defse");
+	    num += 6;
+	    break;
+	case 'L':		/* Losses */
+	    strcat(header, "  Loss");
+	    num += 6;
+	    break;
+	case 'S':		/* Total Rating (stats) */
+	    strcat(header, " Stats");
+	    num += 6;
+	    break;
+	case 'r':		/* Ratio */
+	    strcat(header, " Ratio");
+	    num += 6;
+	    break;
+	case 'd':		/* Damage Inflicted (DI) */
+	    strcat(header, "      DI");
+	    num += 8;
+	    break;
+	case ' ':		/* White Space */
+	    strcat(header, " ");
+	    num += 1;
+	    break;
+#ifdef PLIST1
+	case 'B':		/* Bombing */
+	    strcat(header, " Bmbng");
+	    num += 6;
+	    break;
+	case 'b':		/* Armies Bombed */
+	    strcat(header, " Bmbed");
+	    num += 6;
+	    break;
+	case 'P':		/* Planets */
+	    strcat(header, " Plnts");
+	    num += 6;
+	    break;
+	case 'p':		/* Planets Taken */
+	    strcat(header, " Plnts");
+	    num += 6;
+	    break;
+	case 'G':		/* Doosh rating ('oGGing') [BDyess] */
+	    strcat(header, " Dshng");
+	    num += 6;
+	    break;
+	case 'g':		/* number of dooshes [BDyess] */
+	    strcat(header, " Dshed");
+	    num += 6;
+	    break;
+	case 'F':		/* Resource rating [BDyess] */
+	    /* 'F' is from Farming...I'm out of good letters */
+	    strcat(header, " Resrc");
+	    num += 6;
+	    break;
+	case 'f':		/* number of Resources bombed [BDyess] */
+	    strcat(header, " Rsrcs");
+	    num += 6;
+	    break;
+	case 'Z':		/* SB rating [BDyess] */
+	    /* 'Z' is the last letter - a SB is the team anchor. :) */
+	    strcat(header, " SBrat");
+	    num += 6;
+	    break;
+	case 'z':		/* WB rating (small SB) [BDyess] */
+	    strcat(header, " WBrat");
+	    num += 6;
+	    break;
+	case 'J':		/* JS rating - good letter [BDyess] */
+	    strcat(header, " JSrat");
+	    num += 6;
+	    break;
+	case 'j':		/* JS planets [BDyess] */
+	    strcat(header, " JSpls");
+	    num += 6;
+	    break;
+	case 'C':		/* SpeCial ships rating [BDyess] */
+	    strcat(header, " Specl");
+	    num += 6;
+	    break;
+	case 'E':		/* genocides (Endings) [BDyess] */
+	    strcat(header, " Genos");
+	    num += 6;
+	    break;
+	case 'M':		/* Display, Host Machine */
+	    strcat(header, " Host Machine    ");
+	    num += 17;
+	    break;
+	case 'H':		/* Hours Played */
+	    strcat(header, "  Hours");
+	    num += 7;
+	    break;
+	case 'k':		/* Max Kills */
+	    strcat(header, " Max K");
+	    num += 6;
+	    break;
+	case 'V':		/* Kills per hour */
+	    strcat(header, "   KPH");
+	    num += 6;
+	    break;
+	case 'v':		/* Deaths per hour */
+	    strcat(header, "   DPH");
+	    num += 6;
+	    break;
+#endif
+#ifdef PLIST2
+	case 'w':		/* War staus */
+	    strcat(header, " War Stat");
+	    num += 9;
+	    break;
+	case 's':		/* Speed */
+	    strcat(header, " Sp");
+	    num += 3;
+	    break;
+#endif
+	default:
+	    fprintf(stderr, "%c is not an option for the playerlist\n", ptr[0]);
+	    break;
+	}
+	ptr++;
+    }
+
+    old_playerList = playerList;
+    header_len = num;
+    return (num);
+}
+
+/*===========================================================================*/
+
+void
+wideplayerlist()
+{
+    int     i;
+    int     old_len=header_len;
+    if (old_playerList != playerList) {
+	playerlistnum();
+        if(resizePlayerList)
+            W_ResizeText(playerw,header_len,W_WindowHeight(playerw));
+	/* init slottext [BDyess] */
+    }
+    for (i = 0; i < nplayers; i++)
+	slot[i] = -1;
+
+    W_ClearWindow(playerw);
+    
+    if (slottext && ((old_len != header_len) || (slottext_size != nplayers))) {
+	/* free the old one */
+	for (i = 0; i < slottext_size; i++) {
+	    free(slottext[i]);
+	}
+	free(slottext);
+	free(slotcolors);
+	slottext=0;
+    }
+    if(!slottext) {
+	slottext_size = nplayers;
+	slottext = (char **) malloc(sizeof(char *) * nplayers);
+	slotcolors = (W_Color *) malloc(sizeof(W_Color) * nplayers);
+	for (i = 0; i < nplayers; i++) {
+	    /* malloc extra room in case a line runs off the end */
+	    slottext[i] = (char *) malloc(sizeof(char) * header_len + 30);
+	    slottext[i][0] = 0;
+	    slotcolors[i] = -1;
+	}
+    }
+    W_WriteText(playerw, 0, 1, textColor, header, header_len, W_RegularFont);
+
+    for (i = 0; i < nplayers; i++) {
+	updatePlayer[i] = 1;
+    }
+
+    wideplayerlist2();
+}
+
+/*===========================================================================*/
+
+void
+writeDiffText(window, x, y, color, orig, new, font)
+    W_Window window;
+    int     x, y;
+    W_Color color;
+    char   *orig, *new;
+    W_Font  font;
+{
+/* little routine to print just the chars that are different between orig and
+   new.  [BDyess] */
+    int     i;
+    char   *start;
+
+    for (start = new, i = 0; new[i] && orig[i]; i++) {
+	if (orig[i] != new[i])
+	    continue;
+	if (start == new + i) {
+	    start++;
+	    continue;
+	} else {
+	    W_WriteText(window, x + start - new, y, color, start, new + i - start, font);
+	    start = new + i + 1;
+	}
+    }
+    if (start != new + i) {
+	/* finish up any remaining digits */
+	W_WriteText(window, x + start - new, y, color, start, new + i - start, font);
+    }
+    if (new[i]) {
+	/* write any text that extends past the old one */
+	W_WriteText(window, x + i, y, color, new + i, strlen(new + i), font);
+    } else if (orig[i]) {
+	/* print spaces to clear to EOL */
+	char   *freeme;
+	int     len;
+
+	len = strlen(orig + i);
+	freeme = (char *) malloc(len);
+	memset(freeme, ' ', len);
+	W_WriteText(window, x + i, y, color, freeme, len, font);
+    }
+}
+
+/*===========================================================================*/
+
+void
+plist_line(j, pos)
+    struct player *j;
+    int     pos;
+{
+    char    buf[BUFSIZ];
+    char   *ptr;
+    char    tmp[30];
+    int     my_ticks;
+    struct ratings r;
+    W_Color color;
+
+    get_ratings(j, &r);
+
+    if (pos < 2) {
+	printf("bad line position in playerlist\n");
+	pos = 2;
+    }
+    if (paradise)
+	my_ticks = j->p_stats2.st_tticks;
+    else
+	my_ticks = j->p_stats.st_tticks;
+
+    ptr = playerList;
+    buf[0] = '\0';
+    while (ptr[0] != '\0' && ptr[0] != ',') {
+	tmp[0] = '\0';
+	switch (ptr[0]) {
+	case 'n':		/* Ship Number */
+		tmp[0] = ' ';
+	    if (j->p_status != PALIVE) {
+		tmp[1] = ' ';
+	    } else {
+		tmp[1] = teaminfo[j->p_teami].letter;
+	    }
+		tmp[2] = shipnos[j->p_no];
+		tmp[3] = '\0';
+	    strcat(buf, tmp);
+	    break;
+	case 'T':		/* Ship Type */
+		tmp[0] = ' ';
+	    switch (j->p_status) {
+	    case PALIVE:
+		tmp[1] = j->p_ship->s_desig[0];
+		tmp[2] = j->p_ship->s_desig[1];
+		break;
+	    case PTQUEUE:
+		tmp[1] = 't';
+		tmp[2] = 'q';
+		break;
+	    case POUTFIT:
+		tmp[1] = '-';
+		tmp[2] = '-';
+		break;
+	    case PEXPLODE:
+	    case PDEAD:
+		tmp[1] = '*';
+		tmp[2] = '*';
+		break;
+	    case POBSERVE:
+		tmp[1] = 'o';
+		tmp[2] = 'b';
+		break;
+	    default:
+		tmp[1] = ' ';
+		tmp[2] = ' ';
+	    }
+	    tmp[3] = '\0';
+	    strcat(buf, tmp);
+	    break;
+	case 'R':		/* Rank */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%-10.10s", get_players_rank_name(j));
+	    strcat(buf, tmp);
+	    break;
+	case 'N':		/* Name */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%-16.16s", j->p_name);
+	    strcat(buf, tmp);
+	    break;
+	case 'K':		/* Kills */
+	    tmp[0] = ' ';
+	    if ((j->p_kills <= 0 &&
+		 (paradise || RSA_Client <= 0) && hideNoKills)
+		|| (j->p_status & ~PALIVE))
+		strcpy(tmp + 1, "     ");
+	    else
+		sprintf(tmp + 1, "%5.2f", j->p_kills);
+	    strcat(buf, tmp);
+	    break;
+	case 'l':		/* Login Name */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%-16.16s", j->p_login);
+	    strcat(buf, tmp);
+	    break;
+	case 'O':		/* Offense */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_offrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'W':		/* Wins */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5d", r.r_kills);
+	    strcat(buf, tmp);
+	    break;
+	case 'D':		/* Defense */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_defrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'L':		/* Losses */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5d", r.r_losses);
+	    strcat(buf, tmp);
+	    break;
+	case 'S':		/* Total Rating (stats) */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_ratings);
+	    strcat(buf, tmp);
+	    break;
+	case 'r':		/* Ratio */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_ratio);
+	    strcat(buf, tmp);
+	    break;
+	case 'd':		/* Damage Inflicted (DI) */
+	    tmp[0] = ' ';
+	    /*
+	       ftoa (Ratings * (j->p_stats.st_tticks / 36000.0), tmp+1, 0, 4,
+	       2);
+	    */
+	    sprintf(tmp + 1, "%7.2f", r.r_di);
+	    strcat(buf, tmp);
+	    break;
+	case ' ':		/* White Space */
+	    strcat(buf, " ");
+	    break;
+#ifdef PLIST1
+	case 'B':		/* Bombing */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_bombrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'b':		/* Armies Bombed */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5d", r.r_armies);
+	    strcat(buf, tmp);
+	    break;
+	case 'P':		/* Planets */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_planetrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'p':		/* Planets Taken */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5d", r.r_planets);
+	    strcat(buf, tmp);
+	    break;
+	case 'G':		/* Doosh rating ('oGGing') [BDyess] */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_dooshrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'g':		/* Dooshes [BDyess] */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5d", r.r_dooshes);
+	    strcat(buf, tmp);
+	    break;
+	case 'F':		/* Resource rating [BDyess] */
+	    /* 'F' is from Farming...I'm out of good letters */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_resrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'f':		/* number of Resources bombed [BDyess] */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5d", r.r_resources);
+	    strcat(buf, tmp);
+	    break;
+	case 'Z':		/* SB rating [BDyess] */
+	    /* 'Z' is the last letter - a SB is the team anchor. :) */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_sbrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'z':		/* WB rating (small SB) [BDyess] */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_wbrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'J':		/* JS rating - good letter [BDyess] */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_jsrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'j':		/* JS planets [BDyess] */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5d", r.r_jsplanets);
+	    strcat(buf, tmp);
+	    break;
+	case 'C':		/* SpeCial ships rating [BDyess] */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_specrat);
+	    strcat(buf, tmp);
+	    break;
+	case 'E':		/* genocides (Endings) [BDyess] */
+	    *tmp = ' ';
+	    sprintf(tmp + 1, "%5d", r.r_genocides);
+	    strcat(buf, tmp);
+	    break;
+	case 'M':		/* Display, Host Machine */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%-16.16s", j->p_monitor);
+	    strcat(buf, tmp);
+	    break;
+	case 'H':		/* Hours Played */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%6.2f", my_ticks / 36000.0);
+	    strcat(buf, tmp);
+	    break;
+	case 'k':		/* Max Kills  */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.2f", r.r_maxkills);
+	    strcat(buf, tmp);
+	    break;
+	case 'V':		/* Kills Per Hour  */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.1f", r.r_killsPerHour);
+	    strcat(buf, tmp);
+	    break;
+	case 'v':		/* Deaths Per Hour  */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%5.1f", r.r_lossesPerHour);
+	    strcat(buf, tmp);
+	    break;
+	case 'w':		/* War staus */
+	    if (j->p_swar & idx_to_mask(me->p_teami))
+		strcat(buf, " WAR     ");
+	    else if (j->p_hostile & idx_to_mask(me->p_teami))
+		strcat(buf, " HOSTILE ");
+	    else
+		strcat(buf, " PEACEFUL");
+	    break;
+#endif
+#ifdef PLIST2
+	case 's':		/* Speed */
+	    tmp[0] = ' ';
+	    sprintf(tmp + 1, "%2d", j->p_speed);
+	    strcat(buf, tmp);
+	    break;
+#endif
+	default:
+	    break;
+	}
+	ptr++;
+    }
+
+    color = playerColor(j);
+    if (slot[pos - 2] == j->p_no && slotcolors[pos - 2] == color) {
+	/* write the line, skipping chars that haven't changed [BDyess] */
+	writeDiffText(playerw, 0, pos, color, slottext[pos - 2], buf,
+		      shipFont(j));
+    } else {
+	W_WriteText(playerw, 0, pos, color, buf, strlen(buf),
+		    shipFont(j));
+    }
+    strcpy(slottext[pos - 2], buf);
+    slotcolors[pos - 2] = color;
+    slot[pos - 2] = j->p_no;
+}
+
+/*===========================================================================*/
+
+void
+Sorted_playerlist2()
+{
+    register int i, h, pos = 1, last, boolflag = 0;
+    register struct player *j;
+    static int num;
+    int     numplayers;
+
+  /* 20, not 16, is the max for non-paradise! Mostly the extra 4 are */
+  /* robots, but might as well show them and be safe... -JR*/
+  numplayers = (paradise) ? nplayers : 20;
+
+    /*
+       if (++num % 21 == 0) { boolflag = 1; num = 0; }
+    */
+    /* go through the teams in order */
+    for (h = 0; h < number_of_teams; h++) {
+	/* skip my team, I'll come back to it later */
+	if (me->p_teami == h)
+	    continue;
+
+	/* go through all the players looking for those on team h */
+	for (i = 0, j = &players[0]; i < numplayers; i++, j++) {
+	    if (j->p_teami != h)
+		continue;
+
+	    if (j->p_status == PFREE)
+		continue;
+
+          if(j->p_status == POUTFIT && !showDead) /* already know team */
+                                                  /* is valid.. */
+              continue;
+
+	    pos++;		/* put this AFTER checking for free slots to
+				   get a */
+                 /* nice compact list... */
+
+	    if (!updatePlayer[i] && slot[pos - 2] == i)
+		continue;
+
+	    updatePlayer[i] = 0;
+	    plist_line(j, pos);
+	}
+    }
+
+    /* now go through and do my team.  Note: ind players haven't been done */
+    if (me->p_teami >= 0 && me->p_teami < number_of_teams) {
+    for (i = 0, j = &players[i]; i < numplayers; i++, j++) {
+	if (j->p_teami != me->p_teami)
+	    continue;
+
+	    if (j->p_status == PFREE)
+	    continue;
+
+      if(j->p_status == POUTFIT && !showDead) /* already know team */
+                                                  /* is valid.. */
+          continue;
+
+      pos++;
+	    if (!updatePlayer[i] && slot[pos - 2] == i)
+	    continue;
+
+	updatePlayer[i] = 0;
+	plist_line(j, pos);
+    }
+    }
+#if 0				/* this code displays the ind players from
+				   the bottom up. */
+    /* not everyone has a 32 line playerlist, so this tends to */
+    /* make iggy invisible */
+    last = numplayers + 2;
+
+    for (i = numplayers - 1, j = &players[i]; i >= 0; i--, j--) {
+	if (j->p_teami >=0 && j->p_teami<number_of_teams)
+	    continue;
+
+	if (j->p_status == PFREE)
+	    continue;
+
+	last--;
+
+	if (!updatePlayer[i] && (!boolflag))
+	    continue;
+
+	updatePlayer[i] = 0;
+	plist_line(j, last);
+    }
+#endif				/* 0 */
+
+    for (i = 0, j = &players[0]; i < numplayers; i++, j++) {
+	if (j->p_teami >= 0 && j->p_teami < number_of_teams)
+	    continue;
+
+	if (j->p_status == PFREE)
+	    continue;
+
+	pos++;
+
+	if (!updatePlayer[i] && slot[pos - 2] == i)
+	    continue;
+
+	updatePlayer[i] = 0;
+	plist_line(j, pos);
+    }
+    /* now continue clearing lines until we get to an empty one */
+    pos++;
+    while ((pos - 2) < numplayers && slot[pos - 2] != -1 && slottext[pos - 2][0]) {
+	W_ClearArea(playerw, 0, pos, header_len, 1);
+	slot[pos - 2] = -1;
+	slottext[pos - 2][0] = 0;
+	pos++;
+    }
+
+#if 0
+    if (boolflag && (last > (pos + 1))) {
+	W_ClearArea(playerw, 0, pos + 1, header_len, last - (pos + 1));
+	slot[pos - 2] = -1;
+    }
+#endif				/* 0 */
+}
+
+/*===========================================================================*/
+
+void
+wideplayerlist2()
+{
+    register int i;
+    register struct player *j;
+    int     numplayers;
+
+    /* 20, not 16, is the max for non-paradise! Mostly the extra 4 are */
+    /* robots, but might as well show them and be safe... -JR */
+    numplayers = (paradise) ? nplayers : 20;
+
+    if (old_playerList != playerList) {
+	wideplayerlist();	/* refresh if playerList changed */
+	return;
+    }
+    if (!W_IsMapped(playerw))
+	return;
+
+    if (sortPlayers) {
+	Sorted_playerlist2();
+	return;
+    }
+    for (i = 0, j = &players[i]; i < numplayers; i++, j++) {
+	if (!updatePlayer[i])
+	    continue;
+
+	updatePlayer[i] = 0;
+
+	if (j->p_status == PFREE) {
+	    W_ClearArea(playerw, 0, i + 2, header_len, 1);
+	    continue;
+	}
+	plist_line(j, i + 2);
+    }
+}
+
+#endif				/* WIDE_PLIST */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wtext.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,48 @@
+/* $Id: wtext.h,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+/*	Here are all warnings that are send with SP_S_WARNING */
+/*		HW 93		*/
+/* ab handleTractorReq  socket.c */
+
+#define TEXTE 0
+#define PHASER_HIT_TEXT 1
+#define BOMB_INEFFECTIVE 2
+#define BOMB_TEXT 3
+#define BEAMUP_TEXT 4
+#define BEAMUP2_TEXT 5
+#define BEAMUPSTARBASE_TEXT 6
+#define BEAMDOWNSTARBASE_TEXT 7
+#define BEAMDOWNPLANET_TEXT 8
+#define SBREPORT 9
+#define ONEARG_TEXT 10
+#define BEAM_D_PLANET_TEXT 11
+#define ARGUMENTS 12
+#define BEAM_U_TEXT 13
+#define LOCKPLANET_TEXT 14
+#define LOCKPLAYER_TEXT 15
+#define SBRANK_TEXT 16
+#define SBDOCKREFUSE_TEXT 17
+#define SBDOCKDENIED_TEXT 18
+#define SBLOCKSTRANGER 19
+#define SBLOCKMYTEAM 20
+/*	Daemon messages */
+#define DMKILL 21
+#define KILLARGS 22
+#define DMKILLP 23
+#define DMBOMB 24
+#define DMDEST 25
+#define DMTAKE 26
+#define DGHOSTKILL 27
+/*	INL	messages		*/
+#define INLDMKILLP 28
+#define INLDMKILL 29		/* Because of shiptypes */
+#define INLDRESUME 30
+#define INLDTEXTE 31
+/* Variable warning stuff */
+#define STEXTE 32		/* static text that the server needs to send
+				   to the client first */
+#define SHORT_WARNING 33	/* like CP_S_MESSAGE */
+#define STEXTE_STRING 34
+#define KILLARGS2  35
+
+#define DINVALID 255
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/x11window.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,2532 @@
+/* $Id: x11window.c,v 1.1.1.1 1997/12/06 05:41:31 darius Exp $ */
+
+
+/* x11window.c
+ *
+ * Kevin P. Smith  6/11/89
+ * Much modified by Jerry Frain and Joe Young
+ */
+
+#include <stdio.h>
+#ifdef __STDC__
+#include <stdlib.h>
+#endif
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#ifdef RFCURSORS
+#include <X11/Xmu/CurUtil.h>
+#endif
+#include <X11/cursorfont.h>
+#include <assert.h>
+#include <string.h>
+#include "Wlib.h"
+#include "defs.h"
+#include "struct.h"
+#include "data.h"
+#include "proto.h"
+
+#define INVALID_POSITION	-10000	/* gotta be a big negative */
+/* XFIX speedup */
+#define MAXCACHE	128
+
+/* changes too good to risk leaving out, by Richard Caley (rjc@cstr.ed.ac.uk)*/
+#define RJC
+#define FOURPLANEFIX
+
+/*
+#define NORMAL_FONT	"-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
+#define BOLD_FONT	"-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
+#define ITALIC_FONT	"-*-fixed-medium-r-*-*-10-*-*-*-*-*-*-*"
+*/
+
+#define NORMAL_FONT	"6x10"
+#define BOLD_FONT	"6x10"
+#define BOLD_FONT2	"-*-clean-bold-r-normal--10-100-75-75-c-60-*"
+#define ITALIC_FONT	"6x10"
+#define ITALIC_FONT2	"-*-clean-bold-r-normal--10-100-75-75-c-60-*"
+#define BIG_FONT	"-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*"
+#define IND_FONT        "-*-clean-bold-r-normal--10-100-75-75-c-60-*"
+/*#define BOLD_FONT2	"-schumacher-clean-bold-r-normal--10-100-75-75-c-60-iso8859-1"
+#define ITALIC_FONT2	"-misc-fixed-medium-i-normal--10-100-75-75-c-60-iso8859-1"
+#define BIG_FONT	"-adobe-helvetica-bold-r-normal--34-*-*-*-*-*-*-*"
+*/
+
+static char *_nfonts[] = {
+    NORMAL_FONT,
+    "-*-clean-medium-r-normal--10-100-75-75-c-60-*",
+    "fixed",
+    NULL,
+};
+static char *_bfonts[] = {
+    BOLD_FONT,
+    "-*-clean-bold-r-normal--10-100-75-75-c-60-*",
+    "fixed",
+    NULL,
+};
+static char *_ifonts[] = {
+    ITALIC_FONT,
+    "-*-clean-bold-r-normal--10-100-75-75-c-60-*",
+    "fixed",
+    NULL,
+};
+static char *_bgfonts[] = {
+    BIG_FONT,
+    "-*-lucidatypewriter-*-*-*-*-40-*-*-*-*-*-*-*",
+    "fixed",
+    NULL,
+};
+
+#define FONTS 4
+#define BITGC 4
+
+#define WHITE   0
+#define BLACK   1
+#define RED     2
+#define GREEN   3
+#define YELLOW  4
+#define CYAN    5
+#define GREY	6
+
+static int zero = 0;
+static int one = 1;
+static int two = 2;
+static int three = 3;
+
+int     controlkey = 0;
+#define	BillsScrewyAltMask	(Mod1Mask|Mod2Mask|Mod3Mask|Mod4Mask|Mod5Mask)
+int     altkey = 0;
+int     W_FastClear = 0;
+#ifdef CONTINUOUS_MOUSE
+int     buttonDown = 0;
+#endif				/* CONTINUOUS_MOUSE */
+Display *W_Display;
+Window  W_Root;
+Colormap W_Colormap;
+int     W_Screen;
+#ifdef FOURPLANEFIX
+Visual *W_Visual;
+#endif
+W_Font  W_BigFont = (W_Font) & zero, W_RegularFont = (W_Font) & one;
+W_Font  W_HighlightFont = (W_Font) & two, W_UnderlineFont = (W_Font) & three;
+W_Color W_White = WHITE, W_Black = BLACK, W_Red = RED, W_Green = GREEN;
+W_Color W_Yellow = YELLOW, W_Cyan = CYAN, W_Grey = GREY;
+int     W_Textwidth, W_Textheight;
+char   *getdefault();
+char   *strdup();
+
+int     W_in_message = 0;	/* jfy -- for Jerry's warp message hack */
+
+#ifdef RJC
+extern W_Window baseWin;
+static XClassHint class_hint = {
+    "netrek", "Netrek",
+};
+
+static XWMHints wm_hint = {
+    InputHint | StateHint,
+    True,
+    WithdrawnState,
+    None,
+    None,
+    0, 0,
+    None,
+    None,
+};
+
+static XSizeHints wm_size_hint;
+#endif				/* RJC */
+
+static W_Event W_myevent;
+static int W_isEvent = 0;
+
+struct fontInfo {
+    XFontStruct *fontstruct;
+    int     baseline;
+};
+
+struct colors {
+    char   *name;
+    GC      contexts[FONTS + 1];
+    Pixmap  pixmap;
+    long    pixelValue;
+};
+
+struct icon {
+    Window  window;
+    Pixmap  bitmap;
+    int     width, height;
+    Pixmap  pixmap;
+};
+
+#define WIN_GRAPH	1
+#define WIN_TEXT	2
+#define WIN_MENU	3
+#define WIN_SCROLL	4
+
+struct window {
+    Window  window;
+    int     type;
+    char   *data;
+    int     mapped;
+    int     width, height;
+    char   *name;
+    Cursor  cursor;
+#ifdef SHORT_PACKETS
+    int     insensitive;
+#endif
+#if 0
+    W_Callback handle_keydown;
+    W_Callback handle_keyup;
+    W_Callback handle_button;
+    W_Callback handle_expose;
+#endif				/* 0 */
+};
+
+struct stringList {
+    char   *string;
+    W_Color color;
+    struct stringList *next;
+};
+
+struct menuItem {
+    char   *string;
+    W_Color color;
+    W_Font  font;
+};
+
+struct colors colortable[] = {
+    {"white"},
+    {"black"},
+    {"red"},
+    {"green"},
+    {"yellow"},
+    {"cyan"},
+    {"light grey"}
+};
+
+struct windowlist {
+    struct window *window;
+    struct windowlist *next;
+};
+
+#define HASHSIZE 29
+#define hash(x) (((int) (x)) % HASHSIZE)
+
+struct windowlist *hashtable[HASHSIZE];
+struct fontInfo fonts[FONTS];
+
+struct window *newWindow();
+#ifndef NeXT
+#ifndef __STDC__
+char   *malloc();
+#endif
+#endif				/* NeXT */
+short  *x11tox10bits();
+
+struct window myroot;
+
+#define NCOLORS (sizeof(colortable)/sizeof(colortable[0]))
+#define W_Void2Window(win) ((win) ? (struct window *) (win) : &myroot)
+#define W_Window2Void(window) ((W_Window) (window))
+#define W_Void2Icon(bit) ((struct icon *) (bit))
+#define W_Icon2Void(bit) ((W_Icon) (bit))
+#define fontNum(font) (*((int *) font))
+#define TILESIDE 16
+
+#define WIN_EDGE 5		/* border on l/r edges of text windows */
+#define MENU_PAD 4		/* border on t/b edges of text windows */
+#define MENU_BAR 2		/* width of menu bar */
+
+static unsigned char gray[] = {
+    0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+    0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+    0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55,
+    0xaa, 0xaa, 0x55, 0x55, 0xaa, 0xaa, 0x55, 0x55
+};
+
+static unsigned char striped[] = {
+    0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,
+    0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
+    0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00,
+    0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0
+};
+
+static unsigned char solid[] = {
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+};
+
+/* Prototypes */
+/*static int _myerror P((Display *d , XErrorEvent *e ));*/
+static void GetFonts P((void));
+static XFontStruct *find_font P((char *oldf, char **fonts));
+static void GetColors P((void));
+static void FlushClearAreaCache P((Window win));
+static int W_SpNextEvent P((W_Event * wevent));
+static void FlushLineCache P((Window win, int color));
+static void FlushPointCache P((Window win, int color));
+static struct window *findWindow P((Window window));
+static void addToHash P((struct window * win));
+static void AddToScrolling P((struct window * win, W_Color color, char *str, int len));
+static void redrawScrolling P((struct window * win));
+static void resizeScrolling P((struct window * win, int width, int height));
+static void redrawMenu P((struct window * win));
+static void redrawMenuItem P((struct window * win, int n));
+static void changeMenuItem P((struct window * win, int n, W_Color color, char *str, int len, W_Font font));
+/*static void W_SetTransientForHint P((W_Window w , W_Window pw ));*/
+static void checkGeometry P((char *name, int *x, int *y, int *width, int *height));
+static void checkParent P((char *name, W_Window * parent));
+static void checkCursor P((char *name, char *cursname, Cursor * cursor));
+static void findMouse P((int *x, int *y));
+#ifdef AUTOKEY
+static void W_Flush P((void));
+#endif				/* AUTOKEY */
+static void deleteWindow P((struct window * window));
+
+/* X debugging */
+#if 0
+static int
+_myerror(d, e)
+    Display *d;
+    XErrorEvent *e;
+{
+    abort();
+}
+#endif				/* 0 */
+
+void
+W_Initialize(str)
+    char   *str;
+{
+    int     i;
+
+#ifdef DEBUG
+    printf("Initializing...\n");
+#endif
+    for (i = 0; i < HASHSIZE; i++) {
+	hashtable[i] = NULL;
+    }
+    if ((W_Display = XOpenDisplay(str)) == NULL) {
+	fprintf(stderr, "Cannot open display \"%s\"\n", str ? str : "(null)");
+	EXIT(1);
+    }
+#if 0
+    /* tmp */
+    XSynchronize(W_Display, True);
+    XSetErrorHandler(_myerror);
+#endif
+
+    W_Root = DefaultRootWindow(W_Display);
+#ifdef FOURPLANEFIX
+    W_Visual = DefaultVisual(W_Display, DefaultScreen(W_Display));
+#endif
+    W_Screen = DefaultScreen(W_Display);
+    W_Colormap = DefaultColormap(W_Display, W_Screen);
+    myroot.window = W_Root;
+    myroot.type = WIN_GRAPH;
+    GetFonts();
+    GetColors();
+}
+
+static void
+GetFonts()
+{
+    Font    regular, italic, bold, big;
+    int     i;
+    XGCValues values;
+    XFontStruct *fontinfo;
+    char   *fontname;
+
+    fontname = getdefault("font");
+    if (fontname == NULL)
+	fontname = NORMAL_FONT;
+    fontinfo = XLoadQueryFont(W_Display, fontname);
+    if (fontinfo == NULL) {
+	fontinfo = find_font(fontname, _nfonts);
+    }
+    if (fontinfo == NULL) {
+	printf("netrek: Can't find any fonts!\n");
+	EXIT(1);
+    }
+    regular = fontinfo->fid;
+    W_Textwidth = fontinfo->max_bounds.width;
+    W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
+    fonts[1].baseline = fontinfo->max_bounds.ascent;
+    fonts[1].fontstruct = fontinfo;
+
+    fontname = getdefault("boldfont");
+    if (fontname == NULL) {
+	if (DisplayCells(W_Display, W_Screen) <= 4)
+	    fontname = BOLD_FONT2;
+	else
+	    fontname = BOLD_FONT;
+    }
+    fontinfo = XLoadQueryFont(W_Display, fontname);
+    if (fontinfo == NULL) {
+	fontinfo = find_font(fontname, _bfonts);
+    }
+    if (fontinfo == NULL) {
+	bold = regular;
+	fonts[2].baseline = fonts[1].baseline;
+	fonts[2].fontstruct = fonts[1].fontstruct;
+    } else {
+	bold = fontinfo->fid;
+	fonts[2].baseline = fontinfo->max_bounds.ascent;
+	fonts[2].fontstruct = fontinfo;
+	if (fontinfo->max_bounds.width > W_Textwidth)
+	    W_Textwidth = fontinfo->max_bounds.width;
+	if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight)
+	    W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
+    }
+
+    fontname = getdefault("italicfont");
+    if (fontname == NULL) {
+	if (DisplayCells(W_Display, W_Screen) <= 4)
+	    fontname = ITALIC_FONT2;
+	else
+	    fontname = ITALIC_FONT;
+    }
+    fontinfo = XLoadQueryFont(W_Display, fontname);
+    if (fontinfo == NULL) {
+	fontinfo = find_font(fontname, _ifonts);
+    }
+    if (fontinfo == NULL) {
+	italic = regular;
+	fonts[3].baseline = fonts[1].baseline;
+	fonts[3].fontstruct = fonts[1].fontstruct;
+    } else {
+	italic = fontinfo->fid;
+	fonts[3].baseline = fontinfo->max_bounds.ascent;
+	fonts[3].fontstruct = fontinfo;
+	if (fontinfo->max_bounds.width > W_Textwidth)
+	    W_Textwidth = fontinfo->max_bounds.width;
+	if (fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent > W_Textheight)
+	    W_Textheight = fontinfo->max_bounds.descent + fontinfo->max_bounds.ascent;
+    }
+
+    fontname = getdefault("bigfont");
+    if (fontname == NULL)
+	fontname = BIG_FONT;
+    fontinfo = XLoadQueryFont(W_Display, fontname);
+    if (fontinfo == NULL) {
+	fontinfo = find_font(fontname, _bgfonts);
+    }
+    if (fontinfo == NULL) {
+	big = regular;
+	fonts[0].baseline = fonts[1].baseline;
+	fonts[0].fontstruct = fonts[1].fontstruct;
+    } else {
+	big = fontinfo->fid;
+	fonts[0].baseline = fontinfo->max_bounds.ascent;
+	fonts[0].fontstruct = fontinfo;
+    }
+    for (i = 0; i < NCOLORS; i++) {
+	values.font = big;
+	colortable[i].contexts[0] = XCreateGC(W_Display, W_Root, GCFont, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[0], False);
+	values.font = regular;
+	colortable[i].contexts[1] = XCreateGC(W_Display, W_Root, GCFont, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[1], False);
+	values.font = bold;
+	colortable[i].contexts[2] = XCreateGC(W_Display, W_Root, GCFont, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[2], False);
+	values.font = italic;
+	colortable[i].contexts[3] = XCreateGC(W_Display, W_Root, GCFont, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[3], False);
+	{
+	    static char dl[] = {1, 4};
+	    XSetLineAttributes(W_Display, colortable[i].contexts[3],
+			       0, LineOnOffDash, CapButt, JoinMiter);
+	    XSetDashes(W_Display, colortable[i].contexts[3], 0, dl, 2);
+	}
+	values.function = GXor;
+	colortable[i].contexts[BITGC] = XCreateGC(W_Display, W_Root, GCFunction, &values);
+	XSetGraphicsExposures(W_Display, colortable[i].contexts[BITGC], False);
+    }
+}
+
+static XFontStruct *
+find_font(oldf, fonts)
+    char   *oldf, **fonts;
+{
+    XFontStruct *fi;
+    char  **f;
+    fprintf(stderr, "netrek: Can't find font %s.  Trying others...\n",
+	    oldf);
+    for (f = fonts; *f; f++) {
+	if (strcmp(*f, oldf) != 0) {
+	    if ((fi = XLoadQueryFont(W_Display, *f)))
+		return fi;
+	}
+    }
+    printf("Error - can't find any font!\n");
+    return NULL;
+}
+
+#ifdef FOURPLANEFIX
+static unsigned short extrared[8] = {0x00, 0x20, 0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0};
+static unsigned short extragreen[8] = {0x40, 0x60, 0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20};
+static unsigned short extrablue[8] = {0x80, 0xa0, 0xb0, 0xc0, 0x00, 0x20, 0x40, 0x60};
+#endif
+
+int
+W_Mono()
+{
+    return forceMono;
+}
+
+static void
+GetColors()
+{
+    int     i, j;
+    XColor  foo;
+    int     white, black;
+    unsigned long pixel;
+    unsigned long planes[3];
+    char    defaultstring[100];
+    char   *defaults;
+#ifdef FOURPLANEFIX
+    unsigned long extracolors[8];
+    XColor  colordef;
+#endif
+    extern int forceMono;
+    forceMono = booleanDefault("forcemono", forceMono);
+
+    if ((DisplayCells(W_Display, W_Screen) <= 4) || forceMono) {
+	forceMono = 1;
+	white = WhitePixel(W_Display, W_Screen);
+	black = BlackPixel(W_Display, W_Screen);
+	for (i = 0; i < NCOLORS; i++) {
+	    if (i != W_Black) {
+		colortable[i].pixelValue = white;
+	    } else {
+		colortable[i].pixelValue = black;
+	    }
+	    if (i == W_Red) {
+		colortable[i].pixmap = XCreatePixmapFromBitmapData
+		    (W_Display,
+		     W_Root, (char *) striped, TILESIDE, TILESIDE,
+		     white, black,
+		     DefaultDepth(W_Display, W_Screen));
+	    } else if (i == W_Yellow) {
+		colortable[i].pixmap = XCreatePixmapFromBitmapData
+		    (W_Display,
+		     W_Root, (char *) gray, TILESIDE, TILESIDE,
+		     white, black,
+		     DefaultDepth(W_Display, W_Screen));
+	    } else {
+		colortable[i].pixmap = XCreatePixmapFromBitmapData
+		    (W_Display,
+		     W_Root, (char *) solid, TILESIDE, TILESIDE,
+		     colortable[i].pixelValue,
+		     colortable[i].pixelValue,
+		     DefaultDepth(W_Display, W_Screen));
+	    }
+
+	    /*
+	       We assume white is 0 or 1, and black is 0 or 1. We adjust
+	       graphics function based upon who is who.
+	    */
+	    if (white == 0) {	/* Black is 1 */
+		XSetFunction(W_Display, colortable[i].contexts[BITGC], GXand);
+	    }
+	}
+    } else if (DefaultVisual(W_Display, W_Screen)->class == TrueColor) {
+/* Stuff added by sheldon@iastate.edu 5/28/93
+ * This is supposed to detect a TrueColor display, and then do a lookup of
+ * the colors in default colormap, instead of creating new colormap
+ */
+	for (i = 0; i < NCOLORS; i++) {
+	    sprintf(defaultstring, "color.%s", colortable[i].name);
+
+	    defaults = getdefault(defaultstring);
+	    if (defaults == NULL)
+		defaults = colortable[i].name;
+	    XParseColor(W_Display, W_Colormap, defaults, &foo);
+	    XAllocColor(W_Display, W_Colormap, &foo);
+	    colortable[i].pixelValue = foo.pixel;
+	    colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
+	    W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel,
+					 DefaultDepth(W_Display, W_Screen));
+	}
+    } else {
+#ifdef FOURPLANEFIX
+	if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3,
+			      &pixel, 1)) {
+	    /* couldn't allocate 3 planes, make a new colormap */
+	    W_Colormap = XCreateColormap(W_Display, W_Root, W_Visual, AllocNone);
+	    if (!XAllocColorCells(W_Display, W_Colormap, False, planes, 3,
+				  &pixel, 1)) {
+		fprintf(stderr, "Cannot create new colormap\n");
+		EXIT(1);
+	    }
+	    /*
+	       and fill it with at least 8 more colors so when mouse is
+	       inside netrek windows, use might be able to see his other
+	       windows
+	    */
+	    if (XAllocColorCells(W_Display, W_Colormap, False, NULL, 0,
+				 extracolors, 8)) {
+		colordef.flags = DoRed | DoGreen | DoBlue;
+		for (i = 0; i < 8; i++) {
+		    colordef.pixel = extracolors[i];
+		    colordef.red = extrared[i] << 8;
+		    colordef.green = extragreen[i] << 8;
+		    colordef.blue = extrablue[i] << 8;
+		    XStoreColor(W_Display, W_Colormap, &colordef);
+		}
+	    }
+	}
+#else
+	XAllocColorCells(W_Display, W_Colormap, False, planes, 3, &pixel, 1);
+#endif
+	for (i = 0; i < NCOLORS; i++) {
+	    /*
+	       strcpy(defaultstring, "color.%s", colortable[i].name);
+	    */
+	    sprintf(defaultstring, "color.%s", colortable[i].name);
+
+	    defaults = getdefault(defaultstring);
+	    if (defaults == NULL)
+		defaults = colortable[i].name;
+	    XParseColor(W_Display, W_Colormap, defaults, &foo);
+	    /*
+	       Black must be the color with all the planes off. That is the
+	       only restriction I concerned myself with in the following case
+	       statement.
+	    */
+	    switch (i) {
+	    case WHITE:
+		foo.pixel = pixel | planes[0] | planes[1] | planes[2];
+		break;
+	    case BLACK:
+		foo.pixel = pixel;
+		break;
+	    case RED:
+		foo.pixel = pixel | planes[0];
+		break;
+	    case CYAN:
+		foo.pixel = pixel | planes[1];
+		break;
+	    case YELLOW:
+		foo.pixel = pixel | planes[2];
+		break;
+	    case GREY:
+		foo.pixel = pixel | planes[0] | planes[1];
+		break;
+	    case GREEN:
+		foo.pixel = pixel | planes[1] | planes[2];
+		break;
+	    }
+	    XStoreColor(W_Display, W_Colormap, &foo);
+	    colortable[i].pixelValue = foo.pixel;
+	    colortable[i].pixmap = XCreatePixmapFromBitmapData(W_Display,
+	    W_Root, (char *) solid, TILESIDE, TILESIDE, foo.pixel, foo.pixel,
+					 DefaultDepth(W_Display, W_Screen));
+	}
+    }
+    for (i = 0; i < NCOLORS; i++) {
+	for (j = 0; j < FONTS + 1; j++) {
+	    XSetForeground(W_Display, colortable[i].contexts[j],
+			   colortable[i].pixelValue);
+	    XSetBackground(W_Display, colortable[i].contexts[j],
+			   colortable[W_Black].pixelValue);
+	}
+    }
+}
+
+void
+W_RenameWindow(window, str)
+    W_Window window;
+    char   *str;
+{
+    XStoreName(W_Display, ((struct window *) window)->window, str);
+}
+
+static  W_Window
+w_MakeWindow(name, x, y, width, height, parent,
+	     cursname, border, color, wsort)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    char   *cursname;
+    int     border;
+    W_Color color;
+    int     wsort;		/* WIN_? */
+{
+    int     gx, gy;
+    struct window *newwin;
+    Window  wparent;
+    Cursor  cursor;
+    XSetWindowAttributes attrs;
+    int     pwidth, pheight;	/* pixel width and height */
+
+
+    checkGeometry(name, &gx, &gy, &width, &height);
+    if (gx != INVALID_POSITION)
+	x = gx;
+    if (gy != INVALID_POSITION)
+	y = gy;
+
+    checkParent(name, &parent);
+    wparent = W_Void2Window(parent)->window;
+
+    checkCursor(name, cursname, &cursor);
+    attrs.cursor = cursor;
+
+    attrs.border_pixel = colortable[color].pixelValue;
+    attrs.background_pixel = colortable[W_Black].pixelValue;
+
+    if (wsort == WIN_TEXT || wsort == WIN_SCROLL || wsort == WIN_MENU) {
+	pwidth = width * W_Textwidth + WIN_EDGE * 2;
+	if (wsort == WIN_MENU)
+	    pheight = height * (W_Textheight + MENU_PAD * 2 + MENU_BAR) - MENU_BAR;
+	else
+	    pheight = height * W_Textheight + MENU_PAD * 2;
+    } else {
+	pwidth = width;
+	pheight = height;
+    }
+
+    switch (wsort) {
+    case WIN_TEXT:
+    case WIN_MENU:
+	attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | ButtonReleaseMask;
+	attrs.do_not_propagate_mask = ExposureMask | KeyPressMask | ButtonPressMask;
+	break;
+    case WIN_GRAPH:
+	attrs.event_mask = KeyPressMask | ButtonPressMask | ExposureMask | LeaveWindowMask | ButtonReleaseMask | ButtonMotionMask;
+	attrs.do_not_propagate_mask = ExposureMask;
+	break;
+    case WIN_SCROLL:
+	attrs.event_mask = ResizeRedirectMask | ExposureMask | KeyPressMask | ButtonReleaseMask | ButtonPressMask;
+	attrs.do_not_propagate_mask = ResizeRedirectMask | ExposureMask;
+	break;
+    default:
+	fprintf(stderr, "x11window.c: w_MakeWindow: unknown wsort %d\n", wsort);
+    }
+
+#ifdef AUTOKEY
+    if (attrs.event_mask & KeyPressMask)
+	attrs.event_mask |= KeyReleaseMask;
+#endif				/* AUTOKEY */
+
+    if (strcmp(name, "netrek_icon") == 0)	/* icon should not select for
+						   input */
+	attrs.event_mask = ExposureMask;
+    if (strcmp(name, "wait_icon") == 0)	/* same here [BDyess] */
+	attrs.event_mask = ExposureMask;
+
+    if (strcmp(name, "info") == 0)	/* make info window passthru [BDyess] */
+	attrs.event_mask = ExposureMask;
+
+    newwin = newWindow
+	(XCreateWindow(W_Display, wparent, x, y, pwidth, pheight, border,
+		       CopyFromParent, InputOutput, CopyFromParent,
+		       CWBackPixel | CWBorderPixel | CWEventMask |
+		       (cursor ? CWCursor : 0),
+		       &attrs),
+	 wsort);
+
+    newwin->cursor = cursor;
+
+    {
+	char   *s;
+
+	if (0 == strcmp(name, "wait"))
+	    s = serverName;
+	else if (0 == strcmp(name, "Motd"))
+	    s = "Motd - [f] forward, [b] back, [tab] sysdefs, [space] unmap";
+	else if (0 == strcmp(name, "netrek")) {
+	    if (!title) {
+		char    buf[80];
+		sprintf(buf, "Netrek  @  %s", serverName);
+		s = buf;
+	    } else {
+		/* but title on command line will override */
+		/* from -h arg */
+		s = title;
+	    }
+	} else
+	    s = name;
+
+	XStoreName(W_Display, newwin->window, s);
+    }
+
+    wm_size_hint.width = wm_size_hint.min_width =
+	wm_size_hint.max_width = wm_size_hint.base_width = pwidth;
+    wm_size_hint.min_height = wm_size_hint.height =
+	wm_size_hint.max_height = wm_size_hint.base_height = pheight;
+    wm_size_hint.flags = USSize | PMinSize | PMaxSize | PBaseSize;
+    if (gx > INVALID_POSITION || gy > INVALID_POSITION) {
+	wm_size_hint.flags |= USPosition;
+	wm_size_hint.x = x;
+	wm_size_hint.y = y;
+    }
+    XSetWMNormalHints(W_Display, newwin->window, &wm_size_hint);
+
+    class_hint.res_name = name;
+    class_hint.res_class = "Netrek";
+    XSetClassHint(W_Display, newwin->window, &class_hint);
+
+    XSetWMHints(W_Display, newwin->window, &wm_hint);
+
+    if (((wparent == W_Root &&
+	  baseWin != NULL &&
+	  strcmp(name, "wait") != 0)
+	 || wsort == WIN_MENU) &&
+	strcmp(name, "MetaServer List") != 0 &&
+	strcmp(name, "Motd") != 0) {
+	XSetTransientForHint(W_Display, newwin->window,
+			     W_Void2Window(baseWin)->window);
+    }
+    newwin->name = strdup(name);
+    newwin->width = width;
+    newwin->height = height;
+    if (wsort == WIN_MENU) {
+	int     i;
+	struct menuItem *items;
+	items = (struct menuItem *) malloc(height * sizeof(struct menuItem));
+	for (i = 0; i < height; i++) {
+	    items[i].string = NULL;
+	    items[i].color = W_White;
+	    items[i].font = W_RegularFont;
+	}
+	newwin->data = (char *) items;
+    } else {
+	newwin->data = 0;
+    }
+
+    if (wparent != W_Root)
+	if (checkMapped(name))
+	    W_MapWindow(W_Window2Void(newwin));
+
+#ifdef DEBUG
+    printf("New graphics window %d, child of %d\n", newwin, parent);
+#endif
+
+#ifdef FOURPLANEFIX
+    XSetWindowColormap(W_Display, newwin->window, W_Colormap);
+#endif
+
+    return (W_Window2Void(newwin));
+}
+
+
+
+
+W_Window
+W_MakeWindow(name, x, y, width, height, parent, cursname, border, color)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    char   *cursname;
+    int     border;
+    W_Color color;
+{
+    return w_MakeWindow(name, x, y, width, height, parent,
+			cursname, border, color, WIN_GRAPH);
+}
+
+void
+W_ChangeBorder(window, color)
+    W_Window window;
+    int     color;
+{
+#ifdef DEBUG
+    printf("Changing border of %d\n", window);
+#endif
+
+    /* fix inexplicable color bug */
+    if (DisplayCells(W_Display, W_Screen) <= 2)
+	XSetWindowBorderPixmap(W_Display, W_Void2Window(window)->window,
+			       colortable[color].pixmap);
+    else
+	XSetWindowBorder(W_Display, W_Void2Window(window)->window,
+			 colortable[color].pixelValue);
+}
+
+void
+W_MapWindow(window)
+    W_Window window;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Mapping %d\n", window);
+#endif
+    win = W_Void2Window(window);
+    if (win->mapped)
+	return;
+    win->mapped = 1;
+    XMapRaised(W_Display, win->window);
+}
+
+void
+W_UnmapWindow(window)
+    W_Window window;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("UnMapping %d\n", window);
+#endif
+    win = W_Void2Window(window);
+    if (win->mapped == 0)
+	return;
+    win->mapped = 0;
+    XUnmapWindow(W_Display, win->window);
+}
+
+int
+W_IsMapped(window)
+    W_Window window;
+{
+    struct window *win;
+
+    win = W_Void2Window(window);
+    if (win == NULL)
+	return (0);
+    return (win->mapped);
+}
+
+void
+W_FillArea(window, x, y, width, height, color)
+    W_Window window;
+    int     x, y, width, height;
+    W_Color color;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height,
+	   color, window);
+#endif
+    win = W_Void2Window(window);
+    switch (win->type) {
+    case WIN_GRAPH:
+	XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
+		       x, y, width, height);
+	break;
+    default:
+	XFillRectangle(W_Display, win->window, colortable[color].contexts[0],
+		    WIN_EDGE + x * W_Textwidth, MENU_PAD + y * W_Textheight,
+		       width * W_Textwidth, height * W_Textheight);
+    }
+}
+
+/* XFIX */
+
+static XRectangle _rcache[MAXCACHE];
+static int _rcache_index;
+
+static void
+FlushClearAreaCache(win)
+    Window  win;
+{
+    XFillRectangles(W_Display, win, colortable[backColor].contexts[0],
+		    _rcache, _rcache_index);
+    _rcache_index = 0;
+}
+
+/* local window only */
+void
+W_CacheClearArea(window, x, y, width, height)
+    W_Window window;
+    int     x, y, width, height;
+{
+    Window  win = W_Void2Window(window)->window;
+    register XRectangle *r;
+
+    if (_rcache_index == MAXCACHE)
+	FlushClearAreaCache(win);
+
+    r = &_rcache[_rcache_index++];
+    r->x = (short) x;
+    r->y = (short) y;
+    r->width = (unsigned short) width;
+    r->height = (unsigned short) height;
+}
+
+void
+W_FlushClearAreaCache(window)
+    W_Window window;
+{
+    Window  win = W_Void2Window(window)->window;
+
+    if (_rcache_index)
+	FlushClearAreaCache(win);
+}
+
+/* XFIX: clears now instead of filling. */
+void
+W_ClearArea(window, x, y, width, height)
+    W_Window window;
+    int     x, y, width, height;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Clearing (%d %d) x (%d %d) with %d on %d\n", x, y, width, height,
+	   color, window);
+#endif
+    win = W_Void2Window(window);
+    switch (win->type) {
+    case WIN_GRAPH:
+	/* XFIX: changed */
+	XClearArea(W_Display, win->window, x, y, width, height, False);
+	break;
+    default:
+	/* XFIX: changed */
+	XClearArea(W_Display, win->window, WIN_EDGE + x * W_Textwidth,
+		   MENU_PAD + y * W_Textheight, width * W_Textwidth, height * W_Textheight, False);
+	break;
+    }
+}
+
+void
+W_ClearWindow(window)
+    W_Window window;
+{
+#ifdef DEBUG
+    printf("Clearing %d\n", window);
+#endif
+    XClearWindow(W_Display, W_Void2Window(window)->window);
+}
+
+void
+W_GetEvent(wevent)
+    W_Event *wevent;
+{
+/* blocks until an event is received [BDyess] */
+    XEvent  event;
+
+    if (W_isEvent) {
+	*wevent = W_myevent;
+	W_isEvent = 0;
+	return;
+    }
+    XNextEvent(W_Display, &event);
+    XPutBackEvent(W_Display, &event);
+    W_SpNextEvent(wevent);
+}
+
+int
+W_EventsPending()
+{
+    if (W_isEvent)
+	return (1);
+    while (XPending(W_Display) || buttonDown) {
+	if (W_SpNextEvent(&W_myevent)) {
+	    W_isEvent = 1;
+	    return (1);
+	}
+    }
+    return (0);
+}
+
+void
+W_NextEvent(wevent)
+    W_Event *wevent;
+{
+    if (W_isEvent) {
+	*wevent = W_myevent;
+	W_isEvent = 0;
+	return;
+    }
+    while (W_SpNextEvent(wevent) == 0);
+}
+
+static int
+W_SpNextEvent(wevent)
+    W_Event *wevent;
+{
+    XEvent  event;
+    XKeyEvent *key;
+    XButtonEvent *button;
+    XExposeEvent *expose;
+    XResizeRequestEvent *resize;
+    char    ch;
+    struct window *win;
+#ifdef CONTINUOUS_MOUSE
+    static W_Event buttonEvent;
+    static int delay, cupd = -1;
+#endif				/* CONTINUOUS_MOUSE */
+
+#ifdef DEBUG
+    printf("Getting an event...\n");
+#endif
+    key = (XKeyEvent *) & event;
+    button = (XButtonEvent *) & event;
+    expose = (XExposeEvent *) & event;
+    resize = (XResizeRequestEvent *) & event;
+    for (;;) {
+	if (XPending(W_Display))
+	    XNextEvent(W_Display, &event);
+#ifdef CONTINUOUS_MOUSE
+	else if (buttonDown) {
+	    if (continuousMouse && allowContinuousMouse) {
+		if (cupd != udcounter) {
+		    cupd = udcounter;
+		    if (delay == 0) {
+			bcopy(&buttonEvent, wevent, sizeof(W_Event));
+			delay = clickDelay;
+		    } else {
+			delay--;
+			wevent->type = -1;
+		    }
+		} else
+		    wevent->type = -1;
+		exitInputLoop = 1;
+	    } else {
+		wevent->type = -1;
+		buttonDown = 0;
+	    }
+	    return (1);
+	}
+#endif
+	else
+	    return (0);
+	/*
+	   printf("read an event %d\n", event.type);
+	*/
+	win = findWindow(key->window);
+	if (win == NULL)
+	    return (0);
+	if ((event.type == KeyPress || event.type == ButtonPress) &&
+	    win->type == WIN_MENU) {
+	    if (key->y % (W_Textheight + MENU_PAD * 2 + MENU_BAR) >=
+		W_Textheight + MENU_PAD * 2)
+		return (0);
+	    key->y = key->y / (W_Textheight + MENU_PAD * 2 + MENU_BAR);
+	}
+	switch ((int) event.type) {
+	case LeaveNotify:	/* for message window -- jfy */
+	    if (win == (struct window *) messagew) {
+		W_in_message = 0;
+	    }
+	    return (0);
+	    break;
+	case KeyPress:
+	    if (key->state & ControlMask) {
+		controlkey = 1;
+		key->state &= ~ControlMask;
+	    } else
+		controlkey = 0;
+	    if (key->state & BillsScrewyAltMask) {
+		altkey = 1;
+		key->state &= ~BillsScrewyAltMask;
+	    } else
+		altkey = 0;
+	    if (XLookupString(key, &ch, 1, NULL, NULL) > 0) {
+		wevent->type = W_EV_KEY;
+		wevent->Window = W_Window2Void(win);
+		wevent->x = key->x;
+		wevent->y = key->y;
+		if (controlkey)
+		    wevent->key = (int) ch + 128;
+		else if (altkey)
+		    wevent->key = (int) ch + 256;
+		else
+		    wevent->key = ch;
+		return (1);
+	    }
+	    return (0);
+	    break;
+#ifdef AUTOKEY
+	case KeyRelease:
+	    if (XLookupString(key, &ch, 1, NULL, NULL) > 0) {
+		wevent->type = W_EV_KEY_OFF;
+		wevent->Window = W_Window2Void(win);
+		wevent->x = key->x;
+		wevent->y = key->y;
+		wevent->key = ch;
+		return (1);
+	    }
+	    return (0);
+	    break;
+#endif				/* AUTOKEY */
+	case ButtonPress:
+	    wevent->type = W_EV_BUTTON;
+	    wevent->Window = W_Window2Void(win);
+	    wevent->x = button->x;
+	    wevent->y = button->y;
+	    switch (button->button & 0xf) {
+	    case Button3:
+		wevent->key = W_RBUTTON;
+		break;
+	    case Button1:
+		wevent->key = W_LBUTTON;
+		break;
+	    case Button2:
+		wevent->key = W_MBUTTON;
+		break;
+	    }
+	    if (key->state & ControlMask)
+		wevent->key += 6;
+	    if (key->state & ShiftMask)
+		wevent->key += 3;
+	    if (key->state & BillsScrewyAltMask)
+		wevent->key += 12;	/* alt */
+#ifdef CONTINUOUS_MOUSE
+	    if (continuousMouse && allowContinuousMouse &&
+		(wevent->Window == w || wevent->Window == mapw) &&
+	    /*
+	       buttonRepeatMask allows only certain buttons to repeat
+	       [BDyess]
+	    */
+		(1 << (wevent->key) & buttonRepeatMask)) {
+		buttonDown = 1;
+		exitInputLoop = 1;
+		delay = clickDelay;
+		bcopy(wevent, &buttonEvent, sizeof(W_Event));
+	    }
+	    return (1);
+	case ButtonRelease:
+	    /* bcopy(&buttonEvent,wevent,sizeof(W_Event)); */
+	    wevent->type = -1;
+	    buttonDown = 0;
+	    return (1);
+	case MotionNotify:
+	    /*
+	       the !buttonDown ensures that if you press a button and then
+	       press another, release just the second, and then move the
+	       mouse that nothing happens.
+	    */
+	    if (!(continuousMouse && allowContinuousMouse) || !buttonDown) {
+		wevent->type = -1;
+		return (1);
+	    }
+	    wevent->type = W_EV_BUTTON;
+	    wevent->Window = W_Window2Void(win);
+	    wevent->x = button->x;
+	    wevent->y = button->y;
+	    wevent->key = buttonEvent.key;
+	    bcopy(wevent, &buttonEvent, sizeof(W_Event));
+	    if (cupd == udcounter)
+		wevent->type = -1;
+	    else
+		cupd = udcounter;
+
+	    return (1);
+#else
+	    return (1);
+#endif				/* CONTINUOUS_MOUSE */
+	case Expose:
+	    if (expose->count != 0)
+		return (0);
+	    if (win->type == WIN_SCROLL) {
+		redrawScrolling(win);
+		return (0);
+	    }
+	    if (win->type == WIN_MENU) {
+		redrawMenu(win);
+		return (0);
+	    }
+	    wevent->type = W_EV_EXPOSE;
+	    wevent->Window = W_Window2Void(win);
+	    return (1);
+	case ResizeRequest:
+	    resizeScrolling(win, resize->width, resize->height);
+	    break;
+	default:
+	    return (0);
+	    break;
+	}
+    }
+}
+
+void
+W_MakeLine(window, x0, y0, x1, y1, color)
+    W_Window window;
+    int     x0, y0, x1, y1;
+    W_Color color;
+{
+    Window  win;
+
+#ifdef DEBUG
+    printf("Line on %d\n", window);
+#endif
+    win = W_Void2Window(window)->window;
+    XDrawLine(W_Display, win, colortable[color].contexts[0], x0, y0, x1, y1);
+}
+
+void
+W_DrawPoint(window, x, y, color)
+    W_Window window;
+    int     x, y;
+    W_Color color;
+{
+    Window  win;
+
+#ifdef DEBUG
+    printf("Point on %d\n", window);
+#endif
+    win = W_Void2Window(window)->window;
+    XDrawPoint(W_Display, win, colortable[color].contexts[0], x, y);
+}
+
+/* XFIX */
+
+static XSegment _lcache[NCOLORS][MAXCACHE];
+static int _lcache_index[NCOLORS];
+
+static void
+FlushLineCache(win, color)
+    Window  win;
+    int     color;
+{
+    XDrawSegments(W_Display, win, colortable[color].contexts[0],
+		  _lcache[color], _lcache_index[color]);
+    _lcache_index[color] = 0;
+}
+
+/* for local window only */
+void
+W_CacheLine(window, x0, y0, x1, y1, color)
+    W_Window window;
+    int     x0, y0, x1, y1, color;
+{
+    Window  win = W_Void2Window(window)->window;
+    register XSegment *s;
+
+    if (_lcache_index[color] == MAXCACHE)
+	FlushLineCache(win, color);
+
+    s = &_lcache[color][_lcache_index[color]++];
+    s->x1 = (short) x0;
+    s->y1 = (short) y0;
+    s->x2 = (short) x1;
+    s->y2 = (short) y1;
+}
+
+void
+W_FlushLineCaches(window)
+    W_Window window;
+{
+    Window  win = W_Void2Window(window)->window;
+    register i;
+    for (i = 0; i < NCOLORS; i++) {
+	if (_lcache_index[i])
+	    FlushLineCache(win, i);
+    }
+}
+
+static XPoint _pcache[NCOLORS][MAXCACHE];
+static int _pcache_index[NCOLORS];
+
+static void
+FlushPointCache(win, color)
+    Window  win;
+    int     color;
+{
+    XDrawPoints(W_Display, win, colortable[color].contexts[0],
+		_pcache[color], _pcache_index[color], CoordModeOrigin);
+    _pcache_index[color] = 0;
+}
+
+void
+W_CachePoint(window, x, y, color)
+    W_Window window;
+    int     x, y, color;
+{
+    Window  win = W_Void2Window(window)->window;
+    register XPoint *p;
+
+    if (_pcache_index[color] == MAXCACHE)
+	FlushPointCache(win, color);
+
+    p = &_pcache[color][_pcache_index[color]++];
+    p->x = (short) x;
+    p->y = (short) y;
+}
+
+void
+W_FlushPointCaches(window)
+    W_Window window;
+{
+    Window  win = W_Void2Window(window)->window;
+    register i;
+    for (i = 0; i < NCOLORS; i++) {
+	if (_pcache_index[i])
+	    FlushPointCache(win, i);
+    }
+}
+
+void
+W_MakeTractLine(window, x0, y0, x1, y1, color)
+    W_Window window;
+    int     x0, y0, x1, y1;
+    W_Color color;
+{
+    Window  win;
+
+#ifdef DEBUG
+    printf("Line on %d\n", window);
+#endif
+    win = W_Void2Window(window)->window;
+    XDrawLine(W_Display, win, colortable[color].contexts[3], x0, y0, x1, y1);
+}
+
+void
+W_DrawSectorHighlight(window, x, y, w, h, color)
+    W_Window window;
+    int     x, y, w, h;
+    W_Color color;
+{
+    Window  win;
+#ifdef YUCK
+    XRectangle r[2];
+
+    r[0].x = (short) x;
+    r[0].y = (short) y;
+    r[0].width = (unsigned short) w;
+    r[0].height = (unsigned short) h;
+    r[1].x = (short) x + 2;
+    r[1].y = (short) y + 2;
+    r[1].width = (unsigned short) w - 4;
+    r[1].height = (unsigned short) h - 4;
+
+    win = W_Void2Window(window)->window;
+    XDrawRectangles(W_Display, win, colortable[color].contexts[3],
+		    r, 2);
+#else
+    XRectangle r[1];
+
+    r[0].x = (short) x + 2;
+    r[0].y = (short) y + 2;
+    r[0].width = (unsigned short) w - 4;
+    r[0].height = (unsigned short) h - 4;
+
+    win = W_Void2Window(window)->window;
+    XDrawRectangles(W_Display, win, colortable[color].contexts[3],
+		    r, 1);
+#endif
+}
+
+void
+W_WriteTriangle(window, x, y, s, t, color)
+    W_Window window;
+    int     x, y, s;
+    int     t;
+    W_Color color;
+{
+    struct window *win = W_Void2Window(window);
+    XPoint  points[3];
+
+    if (t == 0) {
+	points[0].x = x;
+	points[0].y = y;
+	points[1].x = x + s;
+	points[1].y = y - s;
+	points[2].x = x - s;
+	points[2].y = y - s;
+    } else {
+	points[0].x = x;
+	points[0].y = y;
+	points[1].x = x + s;
+	points[1].y = y + s;
+	points[2].x = x - s;
+	points[2].y = y + s;
+    }
+
+
+    XFillPolygon(W_Display, win->window, colortable[color].contexts[0],
+		 points, 3, Convex, CoordModeOrigin);
+}
+
+void
+W_WriteText(window, x, y, color, str, len, font)
+    W_Window window;
+    int     x, y, len;
+    W_Color color;
+    W_Font  font;
+    char   *str;
+{
+    struct window *win;
+    int     addr;
+
+    if (!font)
+	font = W_RegularFont;
+#ifdef DEBUG
+    printf("Text for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str);
+#endif
+    win = W_Void2Window(window);
+    switch (win->type) {
+    case WIN_GRAPH:
+	addr = fonts[fontNum(font)].baseline;
+	XDrawImageString(W_Display, win->window,
+	  colortable[color].contexts[fontNum(font)], x, y + addr, str, len);
+	break;
+    case WIN_SCROLL:
+	if (y<0) {
+	  XCopyArea(W_Display, win->window, win->window,
+
+		    colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD,
+		    win->width * W_Textwidth, (win->height - 1) * W_Textheight,
+		    WIN_EDGE, MENU_PAD+W_Textheight);
+	  XClearArea(W_Display, win->window,
+		     WIN_EDGE, MENU_PAD,
+		     W_Textwidth * win->width, W_Textheight, False);
+	  XDrawImageString(W_Display, win->window,
+			   colortable[color].contexts[1],
+			   WIN_EDGE, MENU_PAD + fonts[1].baseline,
+			   str, len);
+	} else {
+	  XCopyArea(W_Display, win->window, win->window,
+		    colortable[W_White].contexts[0], WIN_EDGE, MENU_PAD + W_Textheight,
+		    win->width * W_Textwidth, (win->height - 1) * W_Textheight,
+		    WIN_EDGE, MENU_PAD);
+	  XClearArea(W_Display, win->window,
+		     WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1),
+		     W_Textwidth * win->width, W_Textheight, False);
+	  XDrawImageString(W_Display, win->window,
+			   colortable[color].contexts[1],
+			   WIN_EDGE, MENU_PAD + W_Textheight * (win->height - 1) + fonts[1].baseline,
+			   str, len);
+	}
+	AddToScrolling(win, color, str, len);
+	break;
+    case WIN_MENU:
+	changeMenuItem(win, y, color, str, len, font);
+	break;
+    default:
+	addr = fonts[fontNum(font)].baseline;
+	XDrawImageString(W_Display, win->window,
+			 colortable[color].contexts[fontNum(font)],
+	     x * W_Textwidth + WIN_EDGE, MENU_PAD + y * W_Textheight + addr,
+			 str, len);
+	break;
+    }
+}
+
+void
+W_MaskText(window, x, y, color, str, len, font)
+    W_Window window;
+    int     x, y, len;
+    W_Color color;
+    W_Font  font;
+    char   *str;
+{
+    struct window *win;
+    int     addr;
+
+    addr = fonts[fontNum(font)].baseline;
+#ifdef DEBUG
+    printf("TextMask for %d @ (%d, %d) in %d: [%s]\n", window, x, y, color, str);
+#endif
+    win = W_Void2Window(window);
+    XDrawString(W_Display, win->window,
+	  colortable[color].contexts[fontNum(font)], x, y + addr, str, len);
+}
+
+W_Icon
+W_StoreBitmap(width, height, data, window)
+    int     width, height;
+    W_Window window;
+    char   *data;
+{
+    struct icon *newicon;
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Storing bitmap for %d (%d x %d)\n", window, width, height);
+    fflush(stdout);
+#endif
+    win = W_Void2Window(window);
+    newicon = (struct icon *) malloc(sizeof(struct icon));
+    newicon->width = width;
+    newicon->height = height;
+    newicon->bitmap = XCreateBitmapFromData(W_Display, win->window,
+					    data, width, height);
+    newicon->window = win->window;
+    newicon->pixmap = 0;
+    return (W_Icon2Void(newicon));
+}
+
+void
+W_FreeBitmap(bit)
+    W_Icon  bit;
+{
+    struct icon *icon;
+    icon = W_Void2Icon(bit);
+    XFreePixmap(W_Display, icon->bitmap);
+    free(icon);
+}
+
+void
+W_WriteBitmap(x, y, bit, color)
+    int     x, y;
+    W_Icon  bit;
+    W_Color color;
+{
+    struct icon *icon;
+
+    icon = W_Void2Icon(bit);
+#ifdef DEBUG
+    printf("Writing bitmap to %d\n", icon->window);
+#endif
+
+    XCopyPlane(W_Display, icon->bitmap, icon->window,
+	 colortable[color].contexts[BITGC], 0, 0, icon->width, icon->height,
+	       x, y, 1);
+
+}
+
+void
+W_WriteWinBitmap(win, x, y, bit, color)
+    W_Window win;
+    int     x, y;
+    W_Icon  bit;
+    W_Color color;
+{
+    struct icon *icon;
+    Window  original;
+
+    icon = W_Void2Icon(bit);
+    original = icon->window;
+    icon->window = W_Void2Window(win)->window;
+    W_WriteBitmap(x, y, bit, color);
+    icon->window = original;
+    return;
+}
+
+void
+W_TileWindow(window, bit)
+    W_Window window;
+    W_Icon  bit;
+{
+    Window  win;
+    struct icon *icon;
+
+#ifdef DEBUG
+    printf("Tiling window %d\n", window);
+#endif
+    icon = W_Void2Icon(bit);
+    win = W_Void2Window(window)->window;
+
+    if (icon->pixmap == 0) {
+	icon->pixmap = XCreatePixmap(W_Display, W_Root,
+	      icon->width, icon->height, DefaultDepth(W_Display, W_Screen));
+	XCopyPlane(W_Display, icon->bitmap, icon->pixmap,
+	   colortable[W_White].contexts[0], 0, 0, icon->width, icon->height,
+		   0, 0, 1);
+    }
+    XSetWindowBackgroundPixmap(W_Display, win, icon->pixmap);
+    XClearWindow(W_Display, win);
+
+    /*
+       if (icon->pixmap==0) { icon->pixmap=XMakePixmap(icon->bitmap,
+       colortable[W_White].pixelValue, colortable[W_Black].pixelValue); }
+       XChangeBackground(win, icon->pixmap); XClear(win);
+    */
+}
+
+void
+W_UnTileWindow(window)
+    W_Window window;
+{
+    Window  win;
+
+#ifdef DEBUG
+    printf("Untiling window %d\n", window);
+#endif
+    win = W_Void2Window(window)->window;
+
+    XSetWindowBackground(W_Display, win, colortable[W_Black].pixelValue);
+    XClearWindow(W_Display, win);
+}
+
+W_Window
+W_MakeTextWindow(name, x, y, width, height, parent, cursname, border)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    char   *cursname;
+    int     border;
+{
+    return w_MakeWindow(name, x, y, width, height,
+			parent, cursname, border, W_White, WIN_TEXT);
+}
+
+struct window *
+newWindow(window, type)
+    Window  window;
+    int     type;
+{
+    struct window *newwin;
+
+    newwin = (struct window *) malloc(sizeof(struct window));
+    newwin->window = window;
+    newwin->type = type;
+    newwin->mapped = 0;
+    newwin->insensitive = 0;
+    addToHash(newwin);
+    return (newwin);
+}
+
+
+static struct window *
+findWindow(window)
+    Window  window;
+{
+    struct windowlist *entry;
+
+    entry = hashtable[hash(window)];
+    while (entry != NULL) {
+	if (entry->window->window == window)
+	    return (entry->window);
+	entry = entry->next;
+    }
+    return (NULL);
+}
+
+static void
+addToHash(win)
+    struct window *win;
+{
+    struct windowlist **new;
+
+#ifdef DEBUG
+    printf("Adding to %d\n", hash(win->window));
+#endif
+    new = &hashtable[hash(win->window)];
+    while (*new != NULL) {
+	new = &((*new)->next);
+    }
+    *new = (struct windowlist *) malloc(sizeof(struct windowlist));
+    (*new)->next = NULL;
+    (*new)->window = win;
+}
+
+W_Window
+W_MakeScrollingWindow(name, x, y, width, height, parent, cursname, border)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    char   *cursname;
+    int     border;
+{
+    return w_MakeWindow(name, x, y, width, height, parent, cursname,
+			border, W_White, WIN_SCROLL);
+}
+
+/* Add a string to the string list of the scrolling window.
+ */
+static void
+AddToScrolling(win, color, str, len)
+    struct window *win;
+    W_Color color;
+    char   *str;
+    int     len;
+{
+    struct stringList **strings;
+    char   *newstring;
+    int     count;
+
+    strings = (struct stringList **) & (win->data);
+    count = 0;
+    while ((*strings) != NULL) {
+	count++;
+	strings = &((*strings)->next);
+    }
+    (*strings) = (struct stringList *) malloc(sizeof(struct stringList));
+    (*strings)->next = NULL;
+    (*strings)->color = color;
+    newstring = (char *) malloc(len + 1);
+    strncpy(newstring, str, len);
+    newstring[len] = 0;
+    (*strings)->string = newstring;
+    if (count >= 100) {		/* Arbitrary large size. */
+	struct stringList *temp;
+
+	temp = (struct stringList *) win->data;
+	free(temp->string);
+	temp = temp->next;
+	free((char *) win->data);
+	win->data = (char *) temp;
+    }
+}
+
+#ifdef SHORT_PACKETS
+void
+W_SetSensitive(w, v)
+    W_Window w;
+    int     v;
+{
+    struct window *win = W_Void2Window(w);
+
+    win->insensitive = !v;
+
+    if (win->type == WIN_SCROLL)
+	redrawScrolling(win);
+}
+#endif
+
+static void
+redrawScrolling(win)
+    struct window *win;
+{
+    int     count;
+    struct stringList *list;
+    int     y;
+
+    XClearWindow(W_Display, win->window);
+    count = 0;
+    list = (struct stringList *) win->data;
+    while (list != NULL) {
+	list = list->next;
+	count++;
+    }
+    list = (struct stringList *) win->data;
+    while (count > win->height) {
+	list = list->next;
+	count--;
+    }
+    y = (win->height - count) * W_Textheight + fonts[1].baseline;
+    if (count == 0)
+	return;
+    while (list != NULL) {
+	XDrawImageString(W_Display, win->window,
+			 colortable[list->color].contexts[1],
+		WIN_EDGE, MENU_PAD + y, list->string, strlen(list->string));
+	list = list->next;
+	y = y + W_Textheight;
+    }
+}
+
+static void
+resizeScrolling(win, width, height)
+    struct window *win;
+    int     width, height;
+{
+    win->height = (height - MENU_PAD * 2) / W_Textheight;
+    win->width = (width - WIN_EDGE * 2) / W_Textwidth;
+    XResizeWindow(W_Display, win->window, win->width * W_Textwidth + WIN_EDGE * 2,
+		  win->height * W_Textheight + MENU_PAD * 2);
+}
+
+W_Window
+W_MakeMenu(name, x, y, width, height, parent, border)
+    char   *name;
+    int     x, y, width, height;
+    W_Window parent;
+    int     border;
+{
+    return w_MakeWindow(name, x, y, width, height, parent,
+			"left_ptr", border, W_White, WIN_MENU);
+}
+
+static void
+redrawMenu(win)
+    struct window *win;
+{
+    int     count;
+
+    for (count = 1; count < win->height; count++) {
+	XFillRectangle(W_Display, win->window,
+		       colortable[W_Grey].contexts[0],
+	  0, count * (W_Textheight + MENU_PAD * 2) + (count - 1) * MENU_BAR,
+		       win->width * W_Textwidth + WIN_EDGE * 2, MENU_BAR);
+    }
+    for (count = 0; count < win->height; count++) {
+	redrawMenuItem(win, count);
+    }
+}
+
+static void
+redrawMenuItem(win, n)
+    struct window *win;
+    int     n;
+{
+    struct menuItem *items;
+    int     addr;
+
+    items = (struct menuItem *) win->data;
+
+    XFillRectangle(W_Display, win->window,
+		   colortable[W_Black].contexts[0],
+	  WIN_EDGE, n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD,
+		   win->width * W_Textwidth, W_Textheight);
+    if (items[n].string) {
+	addr = fonts[fontNum(items[n].font)].baseline;
+	XDrawImageString(W_Display, win->window,
+		colortable[items[n].color].contexts[fontNum(items[n].font)],
+			 WIN_EDGE,
+	     n * (W_Textheight + MENU_PAD * 2 + MENU_BAR) + MENU_PAD + addr,
+			 items[n].string, strlen(items[n].string));
+    }
+}
+
+static void
+changeMenuItem(win, n, color, str, len, font)
+    struct window *win;
+    int     n;
+    W_Color color;
+    char   *str;
+    int     len;
+    W_Font  font;
+{
+    struct menuItem *items;
+    char   *news;
+
+    items = (struct menuItem *) win->data;
+    if (items[n].string) {
+	free(items[n].string);
+    }
+    news = malloc(len + 1);
+    strncpy(news, str, len);
+    news[len] = 0;
+    items[n].string = news;
+    items[n].color = color;
+    items[n].font = font;
+    redrawMenuItem(win, n);
+    XFlush(W_Display);
+}
+
+static  Cursor
+make_cursor(bits, mask, width, height, xhot, yhot)
+    char   *bits, *mask;
+    int     width, height, xhot, yhot;
+{
+    Pixmap  cursbits;
+    Pixmap  cursmask;
+    XColor  whiteCol, blackCol;
+    Cursor  curs;
+
+    whiteCol.pixel = colortable[W_White].pixelValue;
+    XQueryColor(W_Display, W_Colormap, &whiteCol);
+    blackCol.pixel = colortable[W_Black].pixelValue;
+    XQueryColor(W_Display, W_Colormap, &blackCol);
+
+    cursbits = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display),
+				     bits, width, height);
+    cursmask = XCreateBitmapFromData(W_Display, DefaultRootWindow(W_Display),
+				     mask, width, height);
+
+    curs = XCreatePixmapCursor(W_Display, cursbits, cursmask,
+			       &whiteCol, &blackCol, xhot, yhot);
+
+    XFreePixmap(W_Display, cursbits);
+    XFreePixmap(W_Display, cursmask);
+    return curs;
+}
+
+#ifdef TCURSORS
+#if 1
+
+void
+W_DefineTCrossCursor(window)
+    W_Window window;
+{
+    return;
+}
+
+void
+W_DefineTextCursor(window)
+    W_Window window;
+{
+    static Cursor new = 0;
+    struct window *win = W_Void2Window(window);
+    XColor  f, b;
+
+    if (!new) {
+	f.pixel = colortable[W_Yellow].pixelValue;
+	b.pixel = colortable[W_Black].pixelValue;
+
+	XQueryColor(W_Display, W_Colormap, &f);
+	XQueryColor(W_Display, W_Colormap, &b);
+
+	new = XCreateFontCursor(W_Display, XC_xterm);
+
+	XRecolorCursor(W_Display, new, &f, &b);
+    }
+    XDefineCursor(W_Display, win->window, new);
+
+    return;
+}
+
+void
+W_RevertCursor(window)
+    W_Window window;
+{
+    struct window *win = W_Void2Window(window);
+
+    XDefineCursor(W_Display, win->window, win->cursor);
+
+    return;
+}
+
+void
+W_DefineCursor(window, width, height, bits, mask, xhot, yhot)
+    W_Window window;
+    int     width, height, xhot, yhot;
+    char   *bits, *mask;
+{
+    return;
+}
+
+#else
+
+#ifdef YUCK
+void
+W_DefineTCrossCursor(window)
+    W_Window window;
+{
+    static
+    Cursor  new;
+    struct window *win = W_Void2Window(window);
+    static
+    XColor  f, b;
+
+    if (new) {
+	XDefineCursor(W_Display, win->window, new);
+	return;
+    }
+    f.pixel = colortable[W_White].pixelValue;
+    b.pixel = colortable[W_Black].pixelValue;
+
+    XQueryColor(W_Display, W_Colormap, &f);
+    XQueryColor(W_Display, W_Colormap, &b);
+
+    new = XCreateFontCursor(W_Display, XC_tcross);
+    XRecolorCursor(W_Display, new, &f, &b);
+    XDefineCursor(W_Display, win->window, new);
+}
+
+#else
+W_DefineTCrossCursor(window)
+    W_Window window;
+{
+    W_DefineCursor(window, cross_width, cross_height,
+		   cross_bits, crossmask_bits, cross_x_hot, cross_y_hot);
+}
+
+#endif
+
+void
+W_DefineTextCursor(window)
+    W_Window window;
+{
+    static
+    Cursor  new;
+    struct window *win = W_Void2Window(window);
+    XColor  f, b;
+
+    if (new) {
+	XDefineCursor(W_Display, win->window, new);
+	return;
+    }
+    f.pixel = colortable[W_Yellow].pixelValue;
+    b.pixel = colortable[W_Black].pixelValue;
+
+    XQueryColor(W_Display, W_Colormap, &f);
+    XQueryColor(W_Display, W_Colormap, &b);
+
+    new = XCreateFontCursor(W_Display, XC_xterm);
+    XRecolorCursor(W_Display, new, &f, &b);
+    XDefineCursor(W_Display, win->window, new);
+}
+
+void
+W_DefineCursor(window, width, height, bits, mask, xhot, yhot)
+    W_Window window;
+    int     width, height, xhot, yhot;
+    char   *bits, *mask;
+{
+    static char *oldbits = NULL;
+    static Cursor curs;
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Defining cursor for %d\n", window);
+#endif
+    win = W_Void2Window(window);
+    if (!oldbits || oldbits != bits) {
+	oldbits = bits;
+	curs = make_cursor(bits, mask, width, height, xhot, yhot);
+    }
+    XDefineCursor(W_Display, win->window, curs);
+}
+#endif
+#endif
+
+void
+W_Beep()
+{
+    XBell(W_Display, 0);
+}
+
+int
+W_WindowWidth(window)
+    W_Window window;
+{
+    return (W_Void2Window(window)->width);
+}
+
+int
+W_WindowHeight(window)
+    W_Window window;
+{
+    return (W_Void2Window(window)->height);
+}
+
+int
+W_Socket()
+{
+    return (ConnectionNumber(W_Display));
+}
+
+void
+W_DestroyWindow(window)
+    W_Window window;
+{
+    struct window *win;
+
+#ifdef DEBUG
+    printf("Destroying %d\n", window);
+#endif
+    win = W_Void2Window(window);
+    deleteWindow(win);
+    XDestroyWindow(W_Display, win->window);
+    free((char *) win);
+}
+
+static void
+deleteWindow(window)
+    struct window *window;
+{
+    struct windowlist **rm;
+    struct windowlist *temp;
+
+    rm = &hashtable[hash(window->window)];
+    while (*rm != NULL && (*rm)->window != window) {
+	rm = &((*rm)->next);
+    }
+    if (*rm == NULL) {
+	printf("Attempt to delete non-existent window!\n");
+	return;
+    }
+    temp = *rm;
+    *rm = temp->next;
+    free((char *) temp);
+}
+
+void
+W_SetIconWindow(main, icon)
+    W_Window main;
+    W_Window icon;
+{
+    XWMHints hints;
+
+    XSetIconName(W_Display, W_Void2Window(icon)->window, W_Void2Window(main)->name);
+
+    hints.flags = IconWindowHint;
+    hints.icon_window = W_Void2Window(icon)->window;
+    XSetWMHints(W_Display, W_Void2Window(main)->window, &hints);
+}
+
+static void
+checkGeometry(name, x, y, width, height)
+    char   *name;
+    int    *x, *y, *width, *height;
+/* fixed so that it handles negative positions 12/21/93          */
+/* note that this is NOT standard X syntax, but it was requested */
+/* and it's how BRM-Hadley works.                       [BDyess] */
+{
+    char   *adefault;
+    char    buf[100];
+    char   *s;
+
+#ifdef RJC
+    *x = *y = INVALID_POSITION;
+#endif				/* RJC */
+
+    sprintf(buf, "%s.geometry", name);
+    adefault = getdefault(buf);
+    if (adefault == NULL)
+	return;
+    /* geometry should be of the form 502x885+1+1, 502x885, or +1+1 */
+    s = adefault;
+    if (*s != '+' && *s != '-') {
+	while (*s != 'x' && *s != 0)
+	    s++;
+	*width = atoi(adefault);
+	if (*s == 0)
+	    return;
+	s++;
+	adefault = s;
+	while (*s != '+' && *s != '-' && *s != 0)
+	    s++;
+	*height = atoi(adefault);
+	if (*s == 0)
+	    return;
+    }
+    adefault = s;
+    s++;
+    if (*s == '-')
+	s++;			/* for the case where they have wxh+-x+y */
+    while (*s != '+' && *s != '-' && *s != 0)
+	s++;
+    *x = atoi(adefault + 1);
+    if (*adefault == '-')
+	*x = -*x;
+    if (*s == 0)
+	return;
+    *y = atoi(s + 1);
+    if (*s == '-')
+	*y = -*y;
+    /* printf("width: %d, height: %d, x: %d, y: %d\n",*width, *height,*x,*y); */
+    return;
+}
+
+static void
+checkParent(name, parent)
+    char   *name;
+    W_Window *parent;
+{
+    char   *adefault;
+    char    buf[100];
+    int     i;
+    struct windowlist *windows;
+
+    sprintf(buf, "%s.parent", name);
+    adefault = getdefault(buf);
+    if (adefault == NULL)
+	return;
+    /* parent must be name of other window or "root" */
+    if (strcmpi(adefault, "root") == 0) {
+	*parent = W_Window2Void(&myroot);
+	return;
+    }
+    for (i = 0; i < HASHSIZE; i++) {
+	windows = hashtable[i];
+	while (windows != NULL) {
+	    if (strcmpi(adefault, windows->window->name) == 0) {
+		*parent = W_Window2Void(windows->window);
+		return;
+	    }
+	    windows = windows->next;
+	}
+    }
+}
+
+#ifdef YUCK
+#define cross_width 15
+#define cross_height 15
+#define cross_x_hot 7
+#define cross_y_hot 7
+static unsigned char cross_bits[] = {
+    0x00, 0x00, 0xc0, 0x01, 0xa0, 0x02, 0x00, 0x00, 0x80, 0x00, 0x04, 0x10, 0x82, 0x20, 0x56,
+0x35, 0x82, 0x20, 0x04, 0x10, 0x80, 0x00, 0x00, 0x00, 0xa0, 0x02, 0xc0, 0x01, 0x00, 0x00};
+static unsigned char crossmask_bits[] = {
+    0xe0, 0x03, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xce, 0x39, 0xcf, 0x79, 0xff, 0x7f, 0xff,
+0x7f, 0xff, 0x7f, 0xcf, 0x79, 0xce, 0x39, 0xf0, 0x07, 0xf0, 0x07, 0xf0, 0x07, 0xe0, 0x03};
+#else
+#define cross_width 16
+#define cross_height 16
+#define cross_x_hot 7
+#define cross_y_hot 7
+static unsigned char cross_bits[] = {
+    0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00,
+    0x10, 0x04, 0x3f, 0x7e, 0x10, 0x04, 0x80, 0x00, 0xc0, 0x01, 0x80, 0x00,
+0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00};
+static unsigned char crossmask_bits[] = {
+    0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0xe0, 0x03, 0xd0, 0x05,
+    0xbf, 0x7e, 0x7f, 0x7f, 0xbf, 0x7e, 0xd0, 0x05, 0xe0, 0x03, 0xc0, 0x01,
+0xc0, 0x01, 0xc0, 0x01, 0xc0, 0x01, 0x00, 0x00};
+#endif
+
+static void
+checkCursor(name, cursname, cursor)
+    char   *name;
+    char   *cursname;
+    Cursor *cursor;
+{
+    char    buf[100];
+    unsigned cnum;
+    char   *adefault;
+
+    *cursor = 0;
+
+    sprintf(buf, "%s.cursor", name);
+    adefault = getdefault(buf);
+    if (adefault == NULL)
+	adefault = cursname;
+    if (adefault == NULL)
+	return;
+
+#ifdef RFCURSORS
+    cnum = XmuCursorNameToIndex(adefault);
+    if (cnum != -1) {
+	XColor  f, b;
+	*cursor = XCreateFontCursor(W_Display, cnum);
+	if (cnum == XC_xterm) {
+
+	    f.pixel = colortable[W_Yellow].pixelValue;
+	    b.pixel = colortable[W_Black].pixelValue;
+
+	    XQueryColor(W_Display, W_Colormap, &f);
+	    XQueryColor(W_Display, W_Colormap, &b);
+
+	    XRecolorCursor(W_Display, *cursor, &f, &b);
+	} else if (cnum == XC_pirate) {
+	    f.pixel = colortable[W_Red].pixelValue;
+	    b.pixel = colortable[W_Black].pixelValue;
+
+	    XQueryColor(W_Display, W_Colormap, &f);
+	    XQueryColor(W_Display, W_Colormap, &b);
+
+	    XRecolorCursor(W_Display, *cursor, &f, &b);
+	}
+    } else
+#endif
+    if (0 == strcmp("bomb here", adefault)) {
+	static Cursor bomb_here = 0;
+	if (bomb_here == 0) {
+	    bomb_here = make_cursor(cross_bits, crossmask_bits,
+				    cross_width, cross_height,
+				    cross_x_hot, cross_y_hot);
+	}
+	*cursor = bomb_here;
+    }
+}
+
+int
+checkMapped(name)
+    char   *name;
+{
+    char    buf[100];
+
+    sprintf(buf, "%s.mapped", name);
+    return (booleanDefault(buf, 0));
+}
+
+void
+W_WarpPointer(window, x, y)
+    W_Window window;
+    int     x, y;
+{
+    static int warped_from_x = 0, warped_from_y = 0;
+
+    if (window == NULL) {
+	if (W_in_message) {
+	    XWarpPointer(W_Display, None, W_Root, 0, 0, 0, 0, warped_from_x, warped_from_y);
+	    W_in_message = 0;
+	}
+    } else {
+	findMouse(&warped_from_x, &warped_from_y);
+	XWarpPointer(W_Display, None, W_Void2Window(window)->window, 0, 0, 0, 0, 0, 0);
+	W_in_message = 1;
+    }
+}
+
+static void
+findMouse(x, y)
+    int    *x, *y;
+{
+    Window  theRoot, theChild;
+    int     wX, wY, rootX, rootY, status;
+    unsigned int wButtons;
+
+    status = XQueryPointer(W_Display, W_Root, &theRoot, &theChild, &rootX, &rootY, &wX, &wY, &wButtons);
+    if (status == True) {
+	*x = wX;
+	*y = wY;
+    } else {
+	*x = 0;
+	*y = 0;
+    }
+}
+
+int
+findMouseInWin(x, y, w)
+    int    *x, *y;
+    W_Window w;
+{
+    Window  theRoot, theChild;
+    int     wX, wY, rootX, rootY, status;
+    unsigned int wButtons;
+    struct window *win = W_Void2Window(w);
+    Window  thisWin = win->window;
+
+    status = XQueryPointer(W_Display, thisWin, &theRoot, &theChild,
+			   &rootX, &rootY, &wX, &wY, &wButtons);
+    if (status == True) {
+	/*
+	   if it's in the window we specified then the values returned should
+	   be within the with and height of the window
+	*/
+	if (wX <= win->width && wY <= win->height) {
+	    *x = wX;
+	    *y = wY;
+	    return 1;
+	}
+    }
+    *x = 0;
+    *y = 0;
+    return 0;
+}
+
+#ifdef AUTOKEY
+static void
+W_Flush()
+{
+    XFlush(W_Display);
+}
+
+W_AutoRepeatOff()
+{
+    XAutoRepeatOff(W_Display);
+    W_Flush();
+}
+
+W_AutoRepeatOn()
+{
+    XAutoRepeatOn(W_Display);
+    W_Flush();
+}
+#endif				/* AUTOKEY */
+
+/* find the width of a font */
+int
+W_StringWidth(string, font)
+    char    string[];
+    W_Font  font;
+{
+    int     x, y;
+
+    y = strlen(string);
+    x = XTextWidth(fonts[fontNum(font)].fontstruct, string, y);
+    return (x);			/* just a guess ?? old never returned! WHS
+				   4/6/93 */
+}
+
+void
+W_TranslatePoints(w, x, y)
+    int    *x, *y;
+    W_Window w;
+{
+    struct window *win;
+    win = W_Void2Window(w);
+
+    if (win->type == WIN_TEXT) {
+	*y = (*y - MENU_PAD) / W_Textheight;
+	*x = (*x - MENU_PAD) / W_Textwidth;
+    }
+    return;
+}
+
+#if 0
+#define MAKE_WINDOW_GETTER(name, part) \
+  W_Callback name(w) \
+       W_Window w; \
+ { \
+     return W_Void2Window(w)->part; \
+ }
+
+#define MAKE_WINDOW_SETTER(name, port) \
+   W_Callback name(w, c) \
+      W_Window w; \
+      W_Callback c; \
+   { \
+      W_Void2Window(w)->port = c; \
+   }
+
+MAKE_WINDOW_GETTER(W_GetWindowKeyDownHandler, handle_keydown);
+MAKE_WINDOW_SETTER(W_SetWindowKeyDownHandler, handle_keydown);
+
+MAKE_WINDOW_GETTER(W_GetWindowKeyUpHandler, handle_keyup);
+MAKE_WINDOW_SETTER(W_SetWindowKeyUpHandler, handle_keyup);
+
+MAKE_WINDOW_GETTER(W_GetWindowButtonHandler, handle_button);
+MAKE_WINDOW_SETTER(W_SetWindowButtonHandler, handle_button);
+
+MAKE_WINDOW_GETTER(W_GetWindowExposeHandler, handle_expose);
+MAKE_WINDOW_SETTER(W_SetWindowExposeHandler, handle_expose);
+#endif				/* 0 */
+
+void
+W_ResizeWindow(window, neww, newh)	/* TSH 2/93 */
+    W_Window window;
+    int     neww, newh;
+{
+    Window  win = W_Void2Window(window)->window;
+
+    XResizeWindow(W_Display, win, (unsigned int) neww, (unsigned int) newh);
+}
+
+void
+W_ResizeMenu(window, neww, newh)/* TSH 2/93 */
+    W_Window window;
+    int     neww, newh;
+{
+    W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2,
+	      newh * (W_Textheight + MENU_PAD * 2) + (newh - 1) * MENU_BAR);
+}
+
+void
+W_ResizeText(window, neww, newh)/* TSH 2/93 */
+    W_Window window;
+    int     neww, newh;
+{
+    W_ResizeWindow(window, neww * W_Textwidth + WIN_EDGE * 2,
+		   newh * W_Textheight + MENU_PAD * 2);
+}
+
+void
+W_Deiconify(window)
+    W_Window window;
+{
+    struct window *win;
+    win = W_Void2Window(window);
+    /* according to ICCCM 4.1.4, this is how you deiconify a window. */
+    XMapWindow(W_Display, win->window);
+}
+
+W_Icon
+W_MakeShieldBitmap(width, height, window)
+    int     width, height;
+    W_Window window;
+{
+    static GC pen = 0;
+    struct window *win;
+    struct icon *newicon;
+
+    win = W_Void2Window(window);
+
+    newicon = (struct icon *) malloc(sizeof(struct icon));
+    newicon->width = width;
+    newicon->height = height;
+    newicon->bitmap = XCreatePixmap(W_Display, win->window, width, height, 1);
+    newicon->window = win->window;
+    newicon->pixmap = 0;
+
+    pen = XCreateGC(W_Display, newicon->bitmap, 0L, 0);
+    XSetForeground(W_Display, pen, 0L);
+    XFillRectangle(W_Display, newicon->bitmap, pen, 0, 0, width, height);
+    XSetForeground(W_Display, pen, 1L);
+    XDrawArc(W_Display, newicon->bitmap, pen, 0, 0, width - 1, height - 1, 0, 360 * 64);
+    XFreeGC(W_Display, pen);
+
+    return W_Icon2Void(newicon);
+}
+
+#ifdef BEEPLITE
+void 
+W_OverlayBitmap(x, y, bit, color)
+    int     x, y;
+    W_Icon  bit;
+    W_Color color;
+{
+    struct icon *icon = W_Void2Icon(bit);
+#ifdef DEBUG
+    printf("Overlaying bitmap to %d\n", icon->window);
+#endif
+    XCopyPlane(W_Display, icon->bitmap, icon->window,
+	     colortable[color].contexts[0], 0, 0, icon->width, icon->height,
+	       x, y, 1);
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/ChangeLog	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,92 @@
+		ChangeLog file for zlib
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+  was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+  pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+  is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+  (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+  TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+  (one's complement) is now done inside crc32(). WARNING: this is
+  incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+  not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+  if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+  user-provided history buffer. This is supported only in deflateInit2
+  and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/Makefile	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,72 @@
+# Makefile for zlib
+# Copyright (C) 1995 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h 
+
+CC=cc
+CFLAGS=-O
+#use -O3 for gcc to take advantage of inlining
+#CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+#CFLAGS=-g -DDEBUG
+LDFLAGS=-L. -lgz
+
+RANLIB=ranlib
+
+prefix=/usr/local
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+       zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example minigzip
+
+test: all
+	./example
+	echo hello world | ./minigzip | ./minigzip -d 
+
+install: libgz.a
+	-@mkdir $(prefix)/include
+	-@mkdir $(prefix)/lib
+	cp zlib.h zconf.h $(prefix)/include
+	chmod 644 $(prefix)/include/zlib.h $(prefix)/include/zconf.h
+	cp libgz.a $(prefix)/lib
+	chmod 644 $(prefix)/lib/libgz.a
+
+libgz.a: $(OBJS)
+	ar rc $@ $(OBJS)
+	$(RANLIB) $@
+
+example: example.o libgz.a
+	$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip: minigzip.o libgz.a
+	$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+clean:
+	rm -f *.o example minigzip libgz.a foo.gz
+
+zip:
+	zip -ul9 zlib README ChangeLog Makefile Makefile.??? Makefile.?? *.[ch]
+
+tgz:
+	cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
+		zlib/Makefile.??? zlib/Makefile.?? zlib/*.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zutil.h zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zutil.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+infblock.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+infcodes.o: zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h infblock.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+infutil.o: zutil.h zlib.h zconf.h inftrees.h infutil.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/Makefile.bor	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,101 @@
+# Makefile for zlib
+# Borland C++   ************ UNTESTED ***********
+
+# To use, do "make -fmakefile.bor"
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. If you wish to reduce the memory
+# requirements (default 256K for big objects plus a few K), you can add
+# to CFLAGS below: -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Turbo C++, Borland C++ -------------
+MODEL=-ml
+CFLAGS=-O2 -Z $(MODEL)
+CC=bcc
+LD=bcc
+LIB=tlib
+#   replace bcc with tcc for Turbo C++ 1.0
+LDFLAGS=$(MODEL)
+O=.obj
+
+# variables
+OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
+  trees$(O)
+OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
+  trees$(O)
+OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
+  infutil$(O) inffast$(O)
+OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
+  infutil$(O)+inffast$(O)
+
+all: test
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
+   infcodes.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
+   infcodes.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+example.obj: example.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+zlib.lib: $(OBJ1) $(OBJ2)
+	$(LIB) zlib +$(OBJP1)
+	$(LIB) zlib +$(OBJP2)
+
+example.exe: example.obj zlib.lib
+	$(LD) $(LDFLAGS) example.obj zlib.lib
+
+minigzip.exe: minigzip.obj zlib.lib
+	$(LD) $(LDFLAGS) minigzip.obj zlib.lib
+
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d 
+
+#clean:
+#	del *.obj
+#	del *.exe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/Makefile.msc	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,98 @@
+# Makefile for zlib
+# Microsoft C 5.1 or later
+
+# To use, do "make makefile.msc"
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. If you wish to reduce the memory
+# requirements (default 256K for big objects plus a few K), you can add
+# to CFLAGS below: -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Microsoft C 5.1 and later -------------
+MODEL=-AL
+CFLAGS=-Oait -Gs -nologo -W3 $(MODEL)
+#-Ox generates bad code with MSC 5.1
+CC=cl
+LD=link
+LDFLAGS=/e/st:0x1000/noe
+O=.obj
+
+# variables
+OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
+  trees$(O)
+OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
+  trees$(O)
+OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
+  infutil$(O) inffast$(O)
+OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
+  infutil$(O)+inffast$(O)
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
+   infcodes.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
+   infcodes.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+example.obj: example.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+zlib.lib: $(OBJ1) $(OBJ2)
+	lib zlib $(OBJ1);
+	lib zlib $(OBJ2);
+
+example.exe: example.obj zlib.lib
+	$(LD) $(LDFLAGS) example.obj,,,zlib.lib;
+
+minigzip.exe: minigzip.obj zlib.lib
+	$(LD) $(LDFLAGS) minigzip.obj,,,zlib.lib;
+
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d 
+
+#clean:
+#	del *.obj
+#	del *.exe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/Makefile.tc	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,100 @@
+# Makefile for zlib
+# TurboC 2.0
+
+# To use, do "make -fmakefile.tc"
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. If you wish to reduce the memory
+# requirements (default 256K for big objects plus a few K), you can add
+# to CFLAGS below: -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Turbo C 2.0 -------------
+MODEL=-ml
+CFLAGS=-O2 -Z $(MODEL)
+CC=tcc
+LD=tcc
+LIB=tlib
+LDFLAGS=$(MODEL)
+O=.obj
+
+# variables
+OBJ1 = adler32$(O) compress$(O) crc32$(O) gzio$(O) uncompr$(O) deflate$(O) \
+  trees$(O)
+OBJP1 = adler32$(O)+compress$(O)+crc32$(O)+gzio$(O)+uncompr$(O)+deflate$(O)+\
+  trees$(O)
+OBJ2 = zutil$(O) inflate$(O) infblock$(O) inftrees$(O) infcodes$(O) \
+  infutil$(O) inffast$(O)
+OBJP2 = zutil$(O)+inflate$(O)+infblock$(O)+inftrees$(O)+infcodes$(O)+\
+  infutil$(O)+inffast$(O)
+
+all: test
+
+adler32.obj: adler32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+compress.obj: compress.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+crc32.obj: crc32.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+gzio.obj: gzio.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infblock.obj: infblock.c zutil.h zlib.h zconf.h infblock.h inftrees.h\
+   infcodes.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infcodes.obj: infcodes.c zutil.h zlib.h zconf.h inftrees.h infutil.h\
+   infcodes.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h infblock.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+	$(CC) -c $(CFLAGS) $*.c
+
+infutil.obj: infutil.c zutil.h zlib.h zconf.h inftrees.h infutil.h
+	$(CC) -c $(CFLAGS) $*.c
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+	$(CC) -c $(CFLAGS) $*.c
+
+trees.obj: trees.c deflate.h zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+example.obj: example.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: minigzip.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+# we must cut the command line to fit in the MS/DOS 128 byte limit:
+zlib.lib: $(OBJ1) $(OBJ2)
+	$(LIB) zlib +$(OBJP1)
+	$(LIB) zlib +$(OBJP2)
+
+example.exe: example.obj zlib.lib
+	$(LD) $(LDFLAGS) -eexample.exe example.obj zlib.lib
+
+minigzip.exe: minigzip.obj zlib.lib
+	$(LD) $(LDFLAGS) -eminigzip.exe minigzip.obj zlib.lib
+
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d 
+
+#clean:
+#	del *.obj
+#	del *.exe
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/README	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,62 @@
+zlib 0.92 is a beta version of a general purpose compression library.
+
+The data format used by the zlib library is described in the
+files zlib-3.1.doc, deflate-1.1.doc and gzip-4.1.doc, available
+in ftp.uu.net:/pub/archiving/zip/doc.
+
+All functions of the compression library are documented in the file
+zlib.h. A usage example of the library is given in the file example.c
+which also tests that the library is working correctly.
+
+To compile all files and run the test program, just type: make test
+(For MSDOS, use one of the special makefiles such as Makefile.msc.)
+To install the zlib library (libgz.a) in /usr/local/lib, type: make install
+To install in a different directory, use for example: make install prefix=$HOME
+This will install in $HOME/lib instead of /usr/local/lib.
+
+The changes made in version 0.92 are documented in the file ChangeLog.
+The main changes since 0.9 are:
+- don't assume that char is signed (problem on SGI)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- added support for DJGPP and Pyramid
+- fix an inflate bug for stored blocks.
+- various speedups
+
+On MSDOS, this version works in both large and small model. However
+small model compression works only for small values of MAX_MEM_LEVEL
+and MAX_WBITS (see zconf.h). Small model decompression should work up
+to MAX_WBITS=15.  This version of zlib does not support small or
+medium model with far allocation of big objects.
+
+
+  Copyright (C) 1995 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  gzip@prep.ai.mit.edu    madler@cco.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind.  The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/adler32.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,46 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* $Id: adler32.c,v 1.1.1.1 1997/12/06 05:41:35 darius Exp $ */
+
+#include "zutil.h"
+
+#define BASE 65521 /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf)  {s1 += *buf++; s2 += s1;}
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+#define DO16(buf) DO8(buf); DO8(buf);
+
+/* ========================================================================= */
+uLong adler32(adler, buf, len)
+    uLong adler;
+    Byte *buf;
+    uInt len;
+{
+    unsigned long s1 = adler & 0xffff;
+    unsigned long s2 = (adler >> 16) & 0xffff;
+    int k;
+
+    if (buf == Z_NULL) return 1L;
+
+    while (len > 0) {
+        k = len < NMAX ? len : NMAX;
+        len -= k;
+        while (k >= 16) {
+            DO16(buf);
+            k -= 16;
+        }
+        if (k != 0) do {
+            DO1(buf);
+        } while (--k);
+        s1 %= BASE;
+        s2 %= BASE;
+    }
+    return (s2 << 16) | s1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/compress.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,55 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* $Id: compress.c,v 1.1.1.1 1997/12/06 05:41:35 darius Exp $ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least 0.1% larger than
+   sourceLen plus 8 bytes. Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+int compress (dest, destLen, source, sourceLen)
+    Byte *dest;
+    uLong *destLen;
+    Byte *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/crc32.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,113 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* $Id: crc32.c,v 1.1.1.1 1997/12/06 05:41:35 darius Exp $ */
+
+#include "zlib.h"
+
+extern uLong crc_table[];   /* crc table, defined below */
+
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong crc32(crc, buf, len)
+    uLong crc;
+    Byte *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0L;
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}
+
+/* =========================================================================
+ * Make the crc table. This function is needed only if you want to compute
+ * the table dynamically.
+ */
+#ifdef DYNAMIC_CRC_TABLE
+
+local void make_crc_table()
+{
+  uLong c;
+  int n, k;
+ 
+  for (n = 0; n &lt; 256; n++)
+  {
+    c = (uLong)n;
+    for (k = 0; k &lt; 8; k++)
+      c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1;
+    crc_table[n] = c;
+  }
+}
+#endif
+
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+uLong crc_table[] = {
+  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+  0x2d02ef8dL
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/deflate.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,963 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* $Id: deflate.c,v 1.1.1.1 1997/12/06 05:41:35 darius Exp $ */
+
+#include "deflate.h"
+
+char copyright[] = " deflate Copyright 1995 Jean-loup Gailly ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+} config;
+
+local config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0},  /* store only */
+/* 1 */ {4,    4,  8,    4},  /* maximum speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8},
+/* 3 */ {4,    6, 32,   32},
+
+/* 4 */ {4,    4, 16,   16},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32},
+/* 6 */ {8,   16, 128, 128},
+/* 7 */ {8,   32, 128, 256},
+/* 8 */ {32, 128, 258, 1024},
+/* 9 */ {32, 258, 258, 4096}}; /* maximum compression */
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+
+/* ===========================================================================
+ *  Prototypes for local functions.
+ */
+
+local void fill_window   __P((deflate_state *s));
+local int  deflate_fast  __P((deflate_state *s, int flush));
+local int  deflate_slow  __P((deflate_state *s, int flush));
+local void lm_init       __P((deflate_state *s));
+local int  longest_match __P((deflate_state *s, IPos cur_match));
+local void putShortMSB   __P((deflate_state *s, uInt b));
+local void flush_pending __P((z_stream *strm));
+local int read_buf       __P((z_stream *strm, char *buf, unsigned size));
+#ifdef ASMV
+      void match_init __P((void)); /* asm code initialization */
+#endif
+
+#ifdef DEBUG
+local  void check_match __P((deflate_state *s, IPos start, IPos match,
+                             int length));
+#endif
+
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + MIN_MATCH-1]), \
+    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (str))
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((char*)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int deflateInit (strm, level)
+    z_stream *strm;
+    int level;
+{
+    return deflateInit2 (strm, level, DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, 0);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int deflateInit2 (strm, level, method, windowBits, memLevel, strategy)
+    z_stream *strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+{
+    deflate_state *s;
+    int noheader = 0;
+
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == Z_NULL) strm->zalloc = zcalloc;
+    if (strm->zfree == Z_NULL) strm->zfree = zcfree;
+
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+
+    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+        noheader = 1;
+        windowBits = -windowBits;
+    }
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 1 || level > 9) {
+        return Z_STREAM_ERROR;
+    }
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state *)s;
+    s->strm = strm;
+
+    s->noheader = noheader;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Byte*) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Pos*)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Pos*)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    s->pending_buf = (uch*) ZALLOC(strm, s->lit_bufsize, 2*sizeof(ush));
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        strm->msg = z_errmsg[1-Z_MEM_ERROR];
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = (ush*) &(s->pending_buf[s->lit_bufsize]);
+    s->l_buf = (uch*) &(s->pending_buf[3*s->lit_bufsize]);
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 32 bits (worst case
+     * is 15+15+13=33).
+     */
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int deflateReset (strm)
+    z_stream *strm;
+{
+    deflate_state *s;
+    
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+    s->adler = 1;
+
+    ct_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* =========================================================================
+ * Put a short the pending_out buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * the pending_out buffer.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}   
+
+/* =========================================================================
+ * Flush as much pending output as possible.
+ */
+local void flush_pending(strm)
+    z_stream *strm;
+{
+    unsigned len = strm->state->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, strm->state->pending_out, len);
+    strm->next_out  += len;
+    strm->state->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    strm->state->pending -= len;
+    if (strm->state->pending == 0) {
+        strm->state->pending_out = strm->state->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int deflate (strm, flush)
+    z_stream *strm;
+    int flush;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    
+    if (strm->next_out == Z_NULL || strm->next_in == Z_NULL) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    strm->state->strm = strm; /* just in case */
+
+    /* Write the zlib header */
+    if (strm->state->status == INIT_STATE) {
+
+        uInt header = (DEFLATED + ((strm->state->w_bits-8)<<4)) << 8;
+        uInt level_flags = (strm->state->level-1) >> 1;
+
+        if (level_flags > 3) level_flags = 3;
+        header |= (level_flags << 6);
+        header += 31 - (header % 31);
+
+        strm->state->status = BUSY_STATE;
+        putShortMSB(strm->state, header);
+    }
+
+    /* Flush as much pending output as possible */
+    if (strm->state->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) return Z_OK;
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (strm->state->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 ||
+        (flush == Z_FINISH && strm->state->status != FINISH_STATE)) {
+        int quit;
+        
+        if (flush == Z_FINISH) {
+            strm->state->status = FINISH_STATE;
+        }
+        if (strm->state->level <= 3) {
+            quit = deflate_fast(strm->state, flush);
+        } else {
+            quit = deflate_slow(strm->state, flush);
+        }
+        if (flush == Z_FULL_FLUSH) {
+            ct_stored_block(strm->state, (char*)0, 0L, 0); /* special marker */
+            flush_pending(strm);
+            CLEAR_HASH(strm->state);             /* forget history */
+            if (strm->avail_out == 0) return Z_OK;
+        }
+        if (quit) return Z_OK;
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (strm->state->noheader) return Z_STREAM_END;
+
+    /* Write the zlib trailer (adler32) */
+    putShortMSB(strm->state, (uInt)(strm->state->adler >> 16));
+    putShortMSB(strm->state, (uInt)(strm->state->adler & 0xffff));
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    strm->state->noheader = 1; /* write the trailer only once! */
+    return strm->state->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int deflateEnd (strm)
+    z_stream *strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    TRY_FREE(strm, strm->state->window);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->pending_buf);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int deflateCopy (dest, source)
+    z_stream *dest;
+    z_stream *source;
+{
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+    *dest = *source;
+    return Z_STREAM_ERROR; /* to be implemented */
+#if 0
+    dest->state = (struct internal_state *)
+        (*dest->zalloc)(1, sizeof(deflate_state));
+    if (dest->state == Z_NULL) return Z_MEM_ERROR;
+
+    *(dest->state) = *(source->state);
+    return Z_OK;
+#endif
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.
+ */
+local int read_buf(strm, buf, size)
+    z_stream *strm;
+    char *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (!strm->state->noheader) {
+        strm->state->adler = adler32(strm->state->adler, strm->next_in, len);
+    }
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    register unsigned j;
+
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = MIN_MATCH-1;
+    s->match_available = 0;
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+
+    s->ins_h = 0;
+    for (j=0; j<MIN_MATCH-1; j++) UPDATE_HASH(s, s->ins_h, s->window[j]);
+    /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
+     * not important since only literal bytes will be emitted.
+     */
+}
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local INLINE int longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Byte *scan = s->window + s->strstart; /* current string */
+    register Byte *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Pos *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Byte *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ush*)scan;
+    register ush scan_end   = *(ush*)(scan+best_len-1);
+#else
+    register Byte *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    Assert(s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2:
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ush*)(match+best_len-1) != scan_end ||
+            *(ush*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        scan++, match++;
+        do {
+        } while (*(ush*)(scan+=2) == *(ush*)(match+=2) &&
+                 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
+                 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
+                 *(ush*)(scan+=2) == *(ush*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= s->nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ush*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    return best_len;
+}
+#endif /* ASMV */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (memcmp((char*)s->window + match,
+                (char*)s->window + start, length) != EQUAL) {
+        fprintf(stderr,
+            " start %d, match %d, length %d\n",
+            start, match, length);
+        z_error("invalid match");
+    }
+    if (verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Pos *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+            more = wsize;
+        } else if (more == (unsigned)(-1)) {
+            /* Very unlikely, but possible on 16 bit machine if strstart == 0
+             * and lookahead == 1 (input done one byte at time)
+             */
+            more--;
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            /* By the IN assertion, the window is not empty so we can't confuse
+             * more == 0 with more == 64K on a 16 bit machine.
+             */
+            zmemcpy((char*)s->window, (char*)s->window+wsize,
+                   (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage):
+             */
+            n = s->hash_size;
+            p = &s->head[n-1];
+            do {
+                m = *p;
+                *p-- = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+            p = &s->prev[n-1];
+            do {
+                m = *p;
+                *p-- = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, (char*)s->window + s->strstart + s->lookahead,
+                     more);
+        s->lookahead += n;
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+   ct_flush_block(s, (s->block_start >= 0L ? \
+               (char*)&s->window[(unsigned)s->block_start] : \
+               (char*)Z_NULL), (long)s->strstart - s->block_start, (eof)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+   FLUSH_BLOCK_ONLY(s, eof); \
+   if (s->strm->avail_out == 0) return 1; \
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return true if
+ * processing was terminated prematurely (no more input or output space).
+ * This function does not perform lazy evaluationof matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local int deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head; /* head of the hash chain */
+    int bflush;     /* set if current block must be flushed */
+
+    s->prev_length = MIN_MATCH-1;
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        INSERT_STRING(s, s->strstart, hash_head);
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+
+            if (s->match_length > s->lookahead) s->match_length = s->lookahead;
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            bflush = ct_tally(s, s->strstart - s->match_start,
+                              s->match_length - MIN_MATCH);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+            if (s->match_length <= s->max_insert_length) {
+                s->match_length--; /* string at strstart already in hash table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
+                     * these bytes are garbage, but it does not matter since
+                     * the next lookahead bytes will be emitted as literals.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++; 
+            } else {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            bflush = ct_tally (s, 0, s->window[s->strstart]);
+            s->lookahead--;
+            s->strstart++; 
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return 0; /* normal exit */
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local int deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;          /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) return 1;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        INSERT_STRING(s, s->strstart, hash_head);
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+            if (s->match_length > s->lookahead) s->match_length = s->lookahead;
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+                 (s->match_length == MIN_MATCH &&
+                  s->strstart - s->match_start > TOO_FAR))) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            bflush = ct_tally(s, s->strstart -1 - s->prev_match,
+                              s->prev_length - MIN_MATCH);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                s->strstart++;
+                INSERT_STRING(s, s->strstart, hash_head);
+                /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
+                 * these bytes are garbage, but it does not matter since the
+                 * next lookahead bytes will always be emitted as literals.
+                 */
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            if (ct_tally (s, 0, s->window[s->strstart-1])) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return 1;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    if (s->match_available) {
+        ct_tally (s, 0, s->window[s->strstart-1]);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/deflate.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,272 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* $Id: deflate.h,v 1.1.1.1 1997/12/06 05:41:36 darius Exp $ */
+
+#include "zutil.h"
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+/* Data type */
+#define BINARY  0
+#define ASCII   1
+#define UNKNOWN 2
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} tree_desc;
+
+typedef ush Pos;
+typedef unsigned IPos;
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_stream *strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Byte *pending_buf;   /* output still pending */
+    Byte *pending_out;   /* next pending byte to output to the stream */
+    int   pending;       /* nb of bytes in the pending buffer */
+    uLong adler;         /* adler32 of uncompressed data */
+    int   noheader;      /* suppress zlib header and adler32 */
+    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Byte *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Pos *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Pos *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+     int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+
+    ct_data dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    ct_data dyn_dtree[2*D_CODES+1]; /* distance tree */
+    ct_data bl_tree[2*BL_CODES+1];  /* Huffman tree for the bit lengths */
+
+    tree_desc l_desc;               /* descriptor for literal tree */
+    tree_desc d_desc;               /* descriptor for distance tree */
+    tree_desc bl_desc;              /* descriptor for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uch *l_buf;           /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ush *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    ulg compressed_len; /* total bit length of compressed file */
+    uInt matches;       /* number of string matches in current block */
+
+#ifdef DEBUG
+    ulg bits_sent;      /* bit length of the compressed data */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+} deflate_state;
+
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+        /* in trees.c */
+void ct_init       __P((deflate_state *s));
+int  ct_tally      __P((deflate_state *s, int dist, int lc));
+ulg ct_flush_block __P((deflate_state *s, char *buf, ulg stored_len, int eof));
+void ct_stored_block __P((deflate_state *s, char *buf, ulg stored_len,
+                          int eof));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/example.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,290 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* $Id: example.c,v 1.1.1.1 1997/12/06 05:41:36 darius Exp $ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+#  include <string.h>
+#endif
+
+#ifndef __GO32__
+extern void exit  __P((int));
+#endif
+
+#define BUFLEN 4096
+
+#define local static
+/* For MSDOS and other systems with limitation on stack size. For Unix,
+    #define local
+   works also.
+ */
+
+#define CHECK_ERR(err, msg) { \
+    if (err != Z_OK) { \
+        fprintf(stderr, "%s error: %d\n", msg, err); \
+        exit(1); \
+    } \
+}
+
+char *hello = "hello world";
+
+void test_compress __P((void));
+void test_gzio     __P((char *out, char *in));
+void test_deflate  __P((Byte compr[]));
+void test_inflate  __P((Byte compr[]));
+void main          __P((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress()
+{
+    local Byte compr[BUFLEN];
+    uLong comprLen = sizeof(compr);
+    local Byte uncompr[BUFLEN];
+    uLong uncomprLen = sizeof(uncompr);
+    int err;
+    uLong len = strlen(hello)+1;
+
+    err = compress(compr, &comprLen, (Byte*)hello, len);
+    CHECK_ERR(err, "compress");
+
+    strcpy((char*)uncompr, "garbage");
+
+    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+    CHECK_ERR(err, "uncompress");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad uncompress\n");
+    } else {
+        printf("uncompress(): %s\n", uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(out, in)
+    char *out; /* output file */
+    char *in;  /* input file */
+{
+    local Byte uncompr[BUFLEN];
+    int uncomprLen = sizeof(uncompr);
+    int err;
+    int len = strlen(hello)+1;
+    gzFile file;
+
+    file = gzopen(out, "wb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+
+    if (gzwrite(file, hello, len) != len) {
+        fprintf(stderr, "gzwrite err: %s\n", gzerror(file, &err));
+    }
+    gzclose(file);
+
+    file = gzopen(in, "rb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+    }
+    strcpy((char*)uncompr, "garbage");
+
+    uncomprLen = gzread(file, uncompr, uncomprLen);
+    if (uncomprLen != len) {
+        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+    }
+    gzclose(file);
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad gzread\n");
+    } else {
+        printf("gzread(): %s\n", uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr)
+    Byte compr[];
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    int len = strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Byte*)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != (uLong)len) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = deflate(&c_stream, Z_NO_FLUSH);
+        CHECK_ERR(err, "deflate");
+    }
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = deflate(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "deflate");
+    }
+
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr)
+    Byte compr[];
+{
+    local Byte uncompr[BUFLEN];
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_in  = compr;
+    d_stream.next_out = uncompr;
+
+    for (;;) {
+        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate\n");
+    } else {
+        printf("inflate(): %s\n", uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr)
+    Byte compr[];
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    int len = strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Byte*)hello;
+    c_stream.next_out = compr;
+    c_stream.avail_in = 3;
+    c_stream.avail_out = BUFLEN;
+    err = deflate(&c_stream, Z_FULL_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    compr[3]++; /* force an error in first compressed block */
+    c_stream.avail_in = len - 3;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        CHECK_ERR(err, "deflate");
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr)
+    Byte compr[];
+{
+    local Byte uncompr[BUFLEN];
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_in  = compr;
+    d_stream.next_out = uncompr;
+    d_stream.avail_in = 2; /* just read the zlib header */
+    d_stream.avail_out = sizeof(uncompr);
+
+    inflate(&d_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "inflate");
+
+    d_stream.avail_in = BUFLEN-2; /* let inflate read all compressed data */
+    err = inflateSync(&d_stream); /* skip the damaged part */
+    CHECK_ERR(err, "inflateSync");
+
+    err = inflate(&d_stream, Z_FINISH);
+    if (err != Z_DATA_ERROR) {
+        fprintf(stderr, "inflate should report DATA_ERROR\n");
+        /* Because of incorrect adler32 */
+    }
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    printf("after inflateSync(): hel%s\n", uncompr);
+}
+
+/* ===========================================================================
+ * Usage:  example [output.gz  [input.gz]]
+ */
+
+void main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    local Byte compr[BUFLEN];
+
+    if (zlib_version[0] != ZLIB_VERSION[0]) {
+        fprintf(stderr, "incompatible zlib version\n");
+        exit(1);
+
+    } else if (strcmp(zlib_version, ZLIB_VERSION) != 0) {
+        fprintf(stderr, "warning: different zlib version\n");
+    }
+    test_compress();
+
+    test_gzio((argc > 1 ? argv[1] : "foo.gz"),
+              (argc > 2 ? argv[2] : "foo.gz"));
+
+    test_deflate(compr);
+    test_inflate(compr);
+
+    test_flush(compr);
+    test_sync(compr);
+
+    exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/gzio.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,469 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* $Id: gzio.c,v 1.1.1.1 1997/12/06 05:41:36 darius Exp $ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#define Z_BUFSIZE 4096
+
+#define ALLOC(size) zcalloc((voidp)0, 1, size)
+#define TRYFREE(p) {if (p) zcfree((voidp)0, p);}
+
+#define GZ_MAGIC_1 0x1f
+#define GZ_MAGIC_2 0x8b
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+#ifndef SEEK_CUR
+#  define SEEK_CUR 1
+#endif
+
+typedef struct gz_stream {
+    z_stream stream;
+    int      z_err;   /* error code for last stream operation */
+    int      z_eof;   /* set if end of input file */
+    FILE     *file;   /* .gz file */
+    Byte     *inbuf;  /* input buffer */
+    Byte     *outbuf; /* output buffer */
+    uLong    crc;     /* crc32 of uncompressed data */
+    char     *msg;    /* error message */
+    char     *path;   /* path name for debugging only */
+    int      transparent; /* 1 if input file is not a .gz file */
+    char     mode;    /* 'w' or 'r' */
+} gz_stream;
+
+
+local int    destroy __P((gz_stream *s));
+local gzFile gz_open __P((char *path, char *mode, int  fd));
+local void   putLong __P((FILE *file, uLong x));
+local uLong  getLong __P((Byte *buf));
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+ */
+local int destroy (s)
+    gz_stream *s;
+{
+    int err = Z_OK;
+
+    if (!s) return Z_STREAM_ERROR;
+
+    TRYFREE(s->inbuf);
+    TRYFREE(s->outbuf);
+    TRYFREE(s->path);
+    TRYFREE(s->msg);
+
+    if (s->stream.state != NULL) {
+       if (s->mode == 'w') {
+           err = deflateEnd(&(s->stream));
+       } else if (s->mode == 'r') {
+           err = inflateEnd(&(s->stream));
+       }
+    }
+    if (s->file != NULL && fclose(s->file)) {
+        err = Z_ERRNO;
+    }
+    if (s->z_err < 0) err = s->z_err;
+    zcfree((voidp)0, s);
+    return err;
+}
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb"). The file is given either by file descritor
+   or path name (if fd == -1).
+     gz_open return NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+    char *path;
+    char *mode;
+    int  fd;
+{
+    int err;
+    char *p = mode;
+    gz_stream *s = (gz_stream *)ALLOC(sizeof(gz_stream));
+
+    if (!s) return Z_NULL;
+
+    s->stream.zalloc = (alloc_func)0;
+    s->stream.zfree = (free_func)0;
+    s->stream.next_in = s->inbuf = Z_NULL;
+    s->stream.next_out = s->outbuf = Z_NULL;
+    s->stream.avail_in = s->stream.avail_out = 0;
+    s->file = NULL;
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->crc = crc32(0L, Z_NULL, 0);
+    s->msg = NULL;
+    s->transparent = 0;
+
+    s->path = (char*)ALLOC(strlen(path)+1);
+    if (s->path == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    strcpy(s->path, path); /* do this early for debugging */
+
+    s->mode = '\0';
+    do {
+        if (*p == 'r') s->mode = 'r';
+        if (*p == 'w') s->mode = 'w';
+    } while (*p++);
+    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+    
+    if (s->mode == 'w') {
+        err = deflateInit2(&(s->stream), Z_DEFAULT_COMPRESSION,
+                           DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, 0);
+        /* windowBits is passed < 0 to suppress zlib header */
+
+        s->stream.next_out = s->outbuf = ALLOC(Z_BUFSIZE);
+
+        if (err != Z_OK || s->outbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    } else {
+        err = inflateInit2(&(s->stream), -MAX_WBITS);
+        s->stream.next_in  = s->inbuf = ALLOC(Z_BUFSIZE);
+
+        if (err != Z_OK || s->inbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    }
+    s->stream.avail_out = Z_BUFSIZE;
+
+    errno = 0;
+    s->file = fd < 0 ? FOPEN(path, mode) : fdopen(fd, mode);
+
+    if (s->file == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    if (s->mode == 'w') {
+        /* Write a very simple .gz header:
+         */
+        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", GZ_MAGIC_1, GZ_MAGIC_2,
+               DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+    } else {
+        /* Check and skip the header:
+         */
+        Byte c1 = 0, c2 = 0;
+        Byte method = 0;
+        Byte flags = 0;
+        Byte xflags = 0;
+        Byte time[4];
+        Byte osCode;
+        int c;
+
+        s->stream.avail_in = fread(s->inbuf, 1, 2, s->file);
+        if (s->stream.avail_in != 2 || s->inbuf[0] != GZ_MAGIC_1
+            || s->inbuf[1] != GZ_MAGIC_2) {
+            s->transparent = 1;
+            return (gzFile)s;
+        }
+        s->stream.avail_in = 0;
+        fscanf(s->file,"%c%c%4c%c%c", &method, &flags, time, &xflags, &osCode);
+
+        if (method != DEFLATED || feof(s->file) || (flags & RESERVED) != 0) {
+            s->z_err = Z_DATA_ERROR;
+            return (gzFile)s;
+        }
+        if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+            long len;
+            fscanf(s->file, "%c%c", &c1, &c2);
+            len = c1 + ((long)c2<<8);
+            fseek(s->file, len, SEEK_CUR);
+        }
+        if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+            while ((c = getc(s->file)) != 0 && c != EOF) ;
+        }
+        if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
+            while ((c = getc(s->file)) != 0 && c != EOF) ;
+        }
+        if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
+            fscanf(s->file, "%c%c", &c1, &c2);
+        }
+        if (feof(s->file)) {
+            s->z_err = Z_DATA_ERROR;
+        }
+    }
+    return (gzFile)s;
+}
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile gzopen (path, mode)
+    char *path;
+    char *mode;
+{
+    return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+     Associate a gzFile with the file descriptor fd.
+*/
+gzFile gzdopen (fd, mode)
+    int fd;
+    char *mode;
+{
+    char name[20];
+    sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+    return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+     Reads the given number of uncompressed bytes from the compressed file.
+   gzread returns the number of bytes actually read (0 for end of file).
+*/
+int gzread (file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+    if (s->transparent) {
+        unsigned n = 0;
+        Byte *b = (Byte*)buf;
+        /* Copy the first two (non-magic) bytes if not done already */
+        while (s->stream.avail_in > 0 && len > 0) {
+            *b++ = *s->stream.next_in++;
+            s->stream.avail_in--;
+            len--; n++;
+        }
+        if (len == 0) return n;
+        return n + fread(b, 1, len, s->file);
+    }
+    if (s->z_err == Z_DATA_ERROR) return -1; /* bad .gz file */
+    if (s->z_err == Z_STREAM_END) return 0;  /* don't read crc as data */
+
+    s->stream.next_out = buf;
+    s->stream.avail_out = len;
+
+    while (s->stream.avail_out != 0) {
+
+        if (s->stream.avail_in == 0 && !s->z_eof) {
+
+            errno = 0;
+            s->stream.avail_in =
+                fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+            if (s->stream.avail_in == 0) {
+                s->z_eof = 1;
+            } else if (s->stream.avail_in == (uInt)EOF) {
+                s->stream.avail_in = 0;
+                s->z_eof = 1;
+                s->z_err = Z_ERRNO;
+                break;
+            }
+            s->stream.next_in = s->inbuf;
+        }
+        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+
+        if (s->z_err == Z_STREAM_END ||
+            s->z_err != Z_OK  || s->z_eof) break;
+    }
+    len -= s->stream.avail_out;
+    s->crc = crc32(s->crc, buf, len);
+    return len;
+}
+
+/* ===========================================================================
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int gzwrite (file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.next_in = buf;
+    s->stream.avail_in = len;
+
+    while (s->stream.avail_in != 0) {
+
+        if (s->stream.avail_out == 0) {
+
+            s->stream.next_out = s->outbuf;
+            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+                s->z_err = Z_ERRNO;
+                break;
+            }
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+
+        if (s->z_err != Z_OK) break;
+    }
+    s->crc = crc32(s->crc, buf, len);
+
+    return len - s->stream.avail_in;
+}
+
+/* ===========================================================================
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+int gzflush (file, flush)
+    gzFile file;
+    int flush;
+{
+    uInt len;
+    int done = 0;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.avail_in = 0; /* should be zero already anyway */
+
+    for (;;) {
+        len = Z_BUFSIZE - s->stream.avail_out;
+
+        if (len != 0) {
+            if (fwrite(s->outbuf, 1, len, s->file) != len) {
+                s->z_err = Z_ERRNO;
+                return Z_ERRNO;
+            }
+            s->stream.next_out = s->outbuf;
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        if (done) break;
+        s->z_err = deflate(&(s->stream), flush);
+
+        /* deflate has finished flushing only when it hasn't used up
+         * all the available space in the output buffer: 
+         */
+        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+ 
+        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+    }
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+/* ===========================================================================
+   Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+    FILE *file;
+    uLong x;
+{
+    int n;
+    for (n = 0; n < 4; n++) {
+        fputc((int)(x & 0xff), file);
+        x >>= 8;
+    }
+}
+
+/* ===========================================================================
+   Reads a long in LSB order from the given buffer
+*/
+local uLong getLong (buf)
+    Byte *buf;
+{
+    uLong x = 0;
+    Byte *p = buf+4;
+
+    do {
+        x <<= 8;
+        x |= *--p; 
+    } while (p != buf);
+    return x;
+}
+
+/* ===========================================================================
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state.
+*/
+int gzclose (file)
+    gzFile file;
+{
+    uInt n;
+    int err;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) return Z_STREAM_ERROR;
+
+    if (s->mode == 'w') {
+        err = gzflush (file, Z_FINISH);
+        if (err != Z_OK) return destroy(file);
+
+        putLong (s->file, s->crc);
+        putLong (s->file, s->stream.total_in);
+
+    } else if (s->mode == 'r' && s->z_err == Z_STREAM_END) {
+
+        /* slide CRC and original size if they are at the end of inbuf */
+        if ((n = s->stream.avail_in) < 8  && !s->z_eof) {
+            Byte *p = s->inbuf;
+            Byte *q = s->stream.next_in;
+            while (n--) { *p++ = *q++; };
+
+            n = s->stream.avail_in;
+            n += fread(p, 1, 8, s->file);
+            s->stream.next_in = s->inbuf;
+        }
+        /* check CRC and original size */
+        if (n < 8 ||
+            getLong(s->stream.next_in) != s->crc ||
+            getLong(s->stream.next_in + 4) != s->stream.total_out) {
+
+            s->z_err = Z_DATA_ERROR;
+        }
+    }
+    return destroy(file);
+}
+
+/* ===========================================================================
+     Returns the error message for the last error which occured on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occured in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+char*  gzerror (file, errnum)
+    gzFile file;
+    int *errnum;
+{
+    char *m;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) {
+        *errnum = Z_STREAM_ERROR;
+        return z_errmsg[1-Z_STREAM_ERROR];
+    }
+    *errnum = s->z_err;
+    if (*errnum == Z_OK) return "";
+
+    m =  *errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg;
+
+    if (m == NULL || *m == '\0') m = z_errmsg[1-s->z_err];
+
+    TRYFREE(s->msg);
+    s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+    strcpy(s->msg, s->path);
+    strcat(s->msg, ": ");
+    strcat(s->msg, m);
+    return s->msg;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/infblock.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,375 @@
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local uInt border[] = { /* Order of the bit length code lengths */
+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+   Notes beyond the 1.93a appnote.txt:
+
+   1. Distance pointers never point before the beginning of the output
+      stream.
+   2. Distance pointers can point back across blocks, up to 32k away.
+   3. There is an implied maximum of 7 bits for the bit length table and
+      15 bits for the actual data.
+   4. If only one code exists, then it is encoded using one bit.  (Zero
+      would be more efficient, but perhaps a little confusing.)  If two
+      codes exist, they are coded using one bit each (0 and 1).
+   5. There is no way of sending zero distance codes--a dummy must be
+      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+      store blocks with no distance codes, but this was discovered to be
+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+      zero distance codes, which is sent as one code of zero bits in
+      length.
+   6. There are up to 286 literal/length codes.  Code 256 represents the
+      end-of-block.  Note however that the static length tree defines
+      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+      cannot be used though, since there is no length base or extra bits
+      defined for them.  Similarily, there are up to 30 distance codes.
+      However, static trees define 32 codes (all 5 bits) to fill out the
+      Huffman codes, but the last two had better not show up in the data.
+   7. Unzip can check dynamic Huffman blocks for complete code sets.
+      The exception is that a single code would not be complete (see #4).
+   8. The five bits following the block type is really the number of
+      literal codes sent minus 257.
+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+      (1+6+6).  Therefore, to output three times the length, you output
+      three codes (1+1+1), whereas to output four times the same length,
+      you only need two codes (1+3).  Hmm.
+  10. In the tree reconstruction algorithm, Code = Code + Increment
+      only if BitLength(i) is not zero.  (Pretty obvious.)
+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+  12. Note: length code 284 can represent 227-258, but length code 285
+      really is 258.  The last length deserves its own, short code
+      since it gets used a lot in very redundant files.  The length
+      258 is special since 258 - 3 (the min match length) is 255.
+  13. The literal/length and distance code bit lengths are read as a
+      single stream of lengths.  It is possible (and advantageous) for
+      a repeat code (16, 17, or 18) to go across the boundary between
+      the two sets of lengths.
+ */
+
+
+void inflate_blocks_reset(s, z, c)
+struct inflate_blocks_state *s;
+z_stream *z;
+uLong *c;
+{
+  if (s->checkfn != Z_NULL)
+    *c = s->check;
+  if (s->mode == BTREE || s->mode == DTREE)
+    ZFREE(z, s->sub.trees.blens);
+  if (s->mode == CODES)
+    inflate_codes_free(s->sub.codes, z);
+  s->mode = TYPE;
+  s->bitk = 0;
+  s->bitb = 0;
+  s->read = s->write = s->window;
+  if (s->checkfn != Z_NULL)
+    s->check = (*s->checkfn)(0L, Z_NULL, 0);
+  Trace((stderr, "inflate:   blocks reset\n"));
+}
+
+
+struct inflate_blocks_state *inflate_blocks_new(z, c, w)
+z_stream *z;
+check_func c;
+uInt w;
+{
+  struct inflate_blocks_state *s;
+
+  if ((s = (struct inflate_blocks_state *)ZALLOC
+       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+    return s;
+  if ((s->window = (Byte *)ZALLOC(z, 1, w)) == Z_NULL)
+  {
+    ZFREE(z, s);
+    return Z_NULL;
+  }
+  s->end = s->window + w;
+  s->checkfn = c;
+  s->mode = TYPE;
+  Trace((stderr, "inflate:   blocks allocated\n"));
+  inflate_blocks_reset(s, z, &s->check);
+  return s;
+}
+
+
+int inflate_blocks(s, z, r)
+struct inflate_blocks_state *s;
+z_stream *z;
+int r;
+{
+  uInt t;               /* temporary storage */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Byte *p;              /* input data pointer */
+  uInt n;               /* bytes available there */
+  Byte *q;              /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input based on current state */
+  while (1) switch (s->mode)
+  {
+    case TYPE:
+      NEEDBITS(3)
+      t = (uInt)b & 7;
+      s->last = t & 1;
+      switch (t >> 1)
+      {
+        case 0:                         /* stored */
+          Trace((stderr, "inflate:     stored block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          t = k & 7;                    /* go to byte boundary */
+          DUMPBITS(t)
+          s->mode = LENS;               /* get length of stored block */
+          break;
+        case 1:                         /* fixed */
+          Trace((stderr, "inflate:     fixed codes block%s\n",
+                 s->last ? " (last)" : ""));
+          {
+            uInt bl, bd;
+            inflate_huft *tl, *td;
+
+            inflate_trees_fixed(&bl, &bd, &tl, &td);
+            s->sub.codes = inflate_codes_new(bl, bd, tl, td, z);
+            if (s->sub.codes == Z_NULL)
+            {
+              r = Z_MEM_ERROR;
+              LEAVE
+            }
+          }
+          DUMPBITS(3)
+          s->mode = CODES;
+          break;
+        case 2:                         /* dynamic */
+          Trace((stderr, "inflate:     dynamic codes block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          s->mode = TABLE;
+          break;
+        case 3:                         /* illegal */
+          DUMPBITS(3)
+          s->mode = BAD;
+          z->msg = "invalid block type";
+          r = Z_DATA_ERROR;
+          LEAVE
+      }
+      break;
+    case LENS:
+      NEEDBITS(32)
+      if ((~b) >> 16 != (b & 0xffff))
+      {
+        s->mode = BAD;
+        z->msg = "invalid stored block lengths";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+      s->sub.left = (uInt)b & 0xffff;
+      k = b = 0;                      /* dump bits */
+      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
+      s->mode = s->sub.left ? STORED : TYPE;
+      break;
+    case STORED:
+      if (n == 0)
+        LEAVE
+      NEEDOUT
+      t = s->sub.left;
+      if (t > n) t = n;
+      if (t > m) t = m;
+      zmemcpy(q, p, t);
+      p += t;  n -= t;
+      q += t;  m -= t;
+      if ((s->sub.left -= t) != 0)
+        break;
+      Tracev((stderr, "inflate:       stored end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      s->mode = s->last ? DRY : TYPE;
+      break;
+    case TABLE:
+      NEEDBITS(14)
+      s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+      {
+        s->mode = BAD;
+        z->msg = "too many length or distance symbols";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+#endif
+      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+      if (t < 19)
+        t = 19;
+      if ((s->sub.trees.blens = (uInt*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+      {
+        r = Z_MEM_ERROR;
+        LEAVE
+      }
+      DUMPBITS(14)
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       table sizes ok\n"));
+      s->mode = BTREE;
+    case BTREE:
+      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+      {
+        NEEDBITS(3)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+        DUMPBITS(3)
+      }
+      while (s->sub.trees.index < 19)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+      s->sub.trees.bb = 7;
+      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+                             &s->sub.trees.tb, z);
+      if (t != Z_OK)
+      {
+        r = t;
+        if (r == Z_DATA_ERROR)
+          s->mode = BAD;
+        LEAVE
+      }
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       bits tree ok\n"));
+      s->mode = DTREE;
+    case DTREE:
+      while (t = s->sub.trees.table,
+             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+      {
+        inflate_huft *h;
+        uInt i, j, c;
+
+        t = s->sub.trees.bb;
+        NEEDBITS(t)
+        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+        t = h->word.what.Bits;
+        c = h->more.Base;
+        if (c < 16)
+        {
+          DUMPBITS(t)
+          s->sub.trees.blens[s->sub.trees.index++] = c;
+        }
+        else /* c == 16..18 */
+        {
+          i = c == 18 ? 7 : c - 14;
+          j = c == 18 ? 11 : 3;
+          NEEDBITS(t + i)
+          DUMPBITS(t)
+          j += (uInt)b & inflate_mask[i];
+          DUMPBITS(i)
+          i = s->sub.trees.index;
+          t = s->sub.trees.table;
+          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+              (c == 16 && i < 1))
+          {
+            s->mode = BAD;
+            z->msg = "invalid bit length repeat";
+            r = Z_DATA_ERROR;
+            LEAVE
+          }
+          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+          do {
+            s->sub.trees.blens[i++] = c;
+          } while (--j);
+          s->sub.trees.index = i;
+        }
+      }
+      inflate_trees_free(s->sub.trees.tb, z);
+      s->sub.trees.tb = Z_NULL;
+      {
+        uInt bl, bd;
+        inflate_huft *tl, *td;
+        struct inflate_codes_state *c;
+
+        bl = 9;
+        bd = 6;
+        t = s->sub.trees.table;
+        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+                                  s->sub.trees.blens, &bl, &bd, &tl, &td, z);
+        if (t != Z_OK)
+        {
+          if (t == (uInt)Z_DATA_ERROR)
+            s->mode = BAD;
+          r = t;
+          LEAVE
+        }
+        Tracev((stderr, "inflate:       trees ok\n"));
+        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+        {
+          inflate_trees_free(td, z);
+          inflate_trees_free(tl, z);
+          r = Z_MEM_ERROR;
+          LEAVE
+        }
+        ZFREE(z, s->sub.trees.blens);
+        s->sub.codes = c;
+      }
+      s->mode = CODES;
+    case CODES:
+      UPDATE
+      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+        return inflate_flush(s, z, r);
+      r = Z_OK;
+      inflate_codes_free(s->sub.codes, z);
+      LOAD
+      Tracev((stderr, "inflate:       codes end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      if (!s->last)
+      {
+        s->mode = TYPE;
+        break;
+      }
+      if (k > 7)              /* return unused byte, if any */
+      {
+        Assert(k < 16, "inflate_codes grabbed too many bytes")
+        k -= 8;
+        n++;
+        p--;                    /* can always return one */
+      }
+      s->mode = DRY;
+    case DRY:
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      s->mode = DONE;
+    case DONE:
+      r = Z_STREAM_END;
+      LEAVE
+    case BAD:
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+int inflate_blocks_free(s, z, c)
+struct inflate_blocks_state *s;
+z_stream *z;
+uLong *c;
+{
+  inflate_blocks_reset(s, z, c);
+  ZFREE(z, s->window);
+  ZFREE(z, s);
+  Trace((stderr, "inflate:   blocks freed\n"));
+  return Z_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/infblock.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,31 @@
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+
+extern struct inflate_blocks_state * inflate_blocks_new __P((
+    z_stream *,
+    check_func,                 /* check function */
+    uInt));                     /* window size */
+
+extern int inflate_blocks __P((
+    struct inflate_blocks_state *,
+    z_stream *,
+    int));                      /* initial return code */
+
+extern void inflate_blocks_reset __P((
+    struct inflate_blocks_state *,
+    z_stream *,
+    uLong *));                  /* check value on output */
+
+extern int inflate_blocks_free __P((
+    struct inflate_blocks_state *,
+    z_stream *,
+    uLong *));                  /* check value on output */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/infcodes.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,238 @@
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infutil.h"
+#include "inffast.h"
+#include "infcodes.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+  /* mode */
+  enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+      START,    /* x: set up for LEN */
+      LEN,      /* i: get length/literal/eob next */
+      LENEXT,   /* i: getting length extra (have base) */
+      DIST,     /* i: get distance next */
+      DISTEXT,  /* i: getting distance extra */
+      COPY,     /* o: copying bytes in window, waiting for space */
+      LIT,      /* o: got literal, waiting for output space */
+      WASH,     /* o: got eob, possibly still output waiting */
+      END,      /* x: got eob and all data flushed */
+      BADCODE}  /* x: got error */
+    mode;               /* current inflate_codes mode */
+
+  /* mode dependent information */
+  uInt len;
+  union {
+    struct {
+      inflate_huft *tree;       /* pointer into tree */
+      uInt need;                /* bits needed */
+    } code;             /* if LEN or DIST, where in tree */
+    uInt lit;           /* if LIT, literal */
+    struct {
+      uInt get;                 /* bits to get for extra */
+      uInt dist;                /* distance back to copy from */
+    } copy;             /* if EXT or COPY, where and how much */
+  } sub;                /* submode */
+
+  /* mode independent information */
+  Byte lbits;           /* ltree bits decoded per branch */
+  Byte dbits;           /* dtree bits decoder per branch */
+  inflate_huft *ltree;          /* literal/length/eob tree */
+  inflate_huft *dtree;          /* distance tree */
+
+};
+
+
+struct inflate_codes_state *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl, *td;
+z_stream *z;
+{
+  struct inflate_codes_state *c;
+
+  if ((c = (struct inflate_codes_state *)
+       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+  {
+    c->mode = START;
+    c->lbits = (Byte)bl;
+    c->dbits = (Byte)bd;
+    c->ltree = tl;
+    c->dtree = td;
+    Tracev((stderr, "inflate:       codes new\n"));
+  }
+  return c;
+}
+
+
+int inflate_codes(s, z, r)
+struct inflate_blocks_state *s;
+z_stream *z;
+int r;
+{
+  uInt j;               /* temporary storage */
+  inflate_huft *t;      /* temporary pointer */
+  int e;                /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Byte *p;              /* input data pointer */
+  uInt n;               /* bytes available there */
+  Byte *q;              /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  Byte *f;              /* pointer to copy strings from */
+  struct inflate_codes_state *c = s->sub.codes; /* codes state */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input and output based on current state */
+  while (1) switch (c->mode)
+  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+    case START:         /* x: set up for LEN */
+#ifndef SLOW
+      if (m >= 258 && n >= 10)
+      {
+        UPDATE
+        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+        LOAD
+        if (r != Z_OK)
+        {
+          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+          break;
+        }
+      }
+#endif /* !SLOW */
+      c->sub.code.need = c->lbits;
+      c->sub.code.tree = c->ltree;
+      c->mode = LEN;
+    case LEN:           /* i: get length/literal/eob next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      if ((e = (int)(t->exop)) < 0)
+      {
+        if (e == -128)          /* invalid code */
+        {
+          c->mode = BADCODE;
+          z->msg = "invalid literal/length code";
+          r = Z_DATA_ERROR;
+          LEAVE
+        }
+        e = -e;
+        if (e & 64)             /* end of block */
+        {
+          Tracevv((stderr, "inflate:         end of block\n"));
+          c->mode = WASH;
+          break;
+        }
+        c->sub.code.need = e;
+        c->sub.code.tree = t->next;
+        break;
+      }
+      if (e & 16)               /* literal */
+      {
+        c->sub.lit = t->base;
+        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                 "inflate:         literal '%c'\n" :
+                 "inflate:         literal 0x%02x\n", t->base));
+        c->mode = LIT;
+        break;
+      }
+      c->sub.copy.get = e;
+      c->len = t->base;
+      c->mode = LENEXT;
+    case LENEXT:        /* i: getting length extra (have base) */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->len += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      c->sub.code.need = c->dbits;
+      c->sub.code.tree = c->dtree;
+      Tracevv((stderr, "inflate:         length %u\n", c->len));
+      c->mode = DIST;
+    case DIST:          /* i: get distance next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      if ((e = (int)(t->exop)) < 0)
+      {
+        if (e == -128)
+        {
+          c->mode = BADCODE;
+          z->msg = "invalid distance code";
+          r = Z_DATA_ERROR;
+          LEAVE
+        }
+        c->sub.code.need = -e;
+        c->sub.code.tree = t->next;
+        break;
+      }
+      c->sub.copy.dist = t->base;
+      c->sub.copy.get = e;
+      c->mode = DISTEXT;
+    case DISTEXT:       /* i: getting distance extra */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->sub.copy.dist += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
+      c->mode = COPY;
+    case COPY:          /* o: copying bytes in window, waiting for space */
+      f = (uInt)(q - s->window) < c->sub.copy.dist ?
+          s->end - (c->sub.copy.dist - (q - s->window)) :
+          q - c->sub.copy.dist;
+      while (c->len)
+      {
+        NEEDOUT
+        OUTBYTE(*f++)
+        if (f == s->end)
+          f = s->window;
+        c->len--;
+      }
+      c->mode = START;
+      break;
+    case LIT:           /* o: got literal, waiting for output space */
+      NEEDOUT
+      OUTBYTE(c->sub.lit)
+      c->mode = START;
+      break;
+    case WASH:          /* o: got eob, possibly more output */
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      c->mode = END;
+    case END:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADCODE:       /* x: got error */
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+void inflate_codes_free(c, z)
+struct inflate_codes_state *c;
+z_stream *z;
+{
+  inflate_trees_free(c->dtree, z);
+  inflate_trees_free(c->ltree, z);
+  ZFREE(z, c);
+  Tracev((stderr, "inflate:       codes free\n"));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/infcodes.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,25 @@
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+
+extern struct inflate_codes_state *inflate_codes_new __P((
+    uInt, uInt,
+    inflate_huft *, inflate_huft *,
+    z_stream *));
+
+extern int inflate_codes __P((
+    struct inflate_blocks_state *,
+    z_stream *,
+    int));
+
+extern void inflate_codes_free __P((
+    struct inflate_codes_state *,
+    z_stream *));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/inffast.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,156 @@
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infutil.h"
+#include "inffast.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#ifdef DEBUG
+#  undef NEXTBYTE
+#  define NEXTBYTE (n--?0:fprintf(stderr,"inffast underrun\n"),*p++)
+#endif
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {n+=(c=k>>3);p-=c;k&=7;}
+
+/* Called with number of bytes left to write in window at least 258
+   (the maximum string length) and number of input bytes available
+   at least ten.  The ten bytes are six bytes for the longest length/
+   distance pair plus four bytes for overloading the bit buffer. */
+
+int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl, *td;
+struct inflate_blocks_state *s;
+z_stream *z;
+{
+  inflate_huft *t;      /* temporary pointer */
+  int e;                /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Byte *p;              /* input data pointer */
+  uInt n;               /* bytes available there */
+  Byte *q;              /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  uInt ml;              /* mask for literal/length tree */
+  uInt md;              /* mask for distance tree */
+  uInt c;               /* bytes to copy */
+  uInt d;               /* distance back to copy from */
+  Byte *r;              /* copy source pointer */
+
+  /* load input, output, bit values */
+  LOAD
+
+  /* initialize masks in registers */
+  ml = inflate_mask[bl];
+  md = inflate_mask[bd];
+
+  /* do until not enough input or output space for fast loop */
+  do {                          /* assume called with m >= 258 && n >= 10 */
+    /* get literal/length code */
+    GRABBITS(20)                /* max bits for literal/length code */
+    if ((e = (t = tl + ((uInt)b & ml))->exop) < 0)
+      do {
+        if (e == -128)
+        {
+          z->msg = "invalid literal/length code";
+          UNGRAB
+          UPDATE
+          return Z_DATA_ERROR;
+        }
+        DUMPBITS(t->bits)
+        e = -e;
+        if (e & 64)             /* end of block */
+        {
+          Tracevv((stderr, "inflate:         * end of block\n"));
+          UNGRAB
+          UPDATE
+          return Z_STREAM_END;
+        }
+      } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0);
+    DUMPBITS(t->bits)
+
+    /* process literal or length (end of block already trapped) */
+    if (e & 16)                 /* then it's a literal */
+    {
+      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                "inflate:         * literal '%c'\n" :
+                "inflate:         * literal 0x%02x\n", t->base));
+      *q++ = (Byte)t->base;
+      m--;
+    }
+    else                        /* it's a length */
+    {
+      /* get length of block to copy (already have extra bits) */
+      c = t->base + ((uInt)b & inflate_mask[e]);
+      DUMPBITS(e);
+      Tracevv((stderr, "inflate:         * length %u\n", c));
+
+      /* decode distance base of block to copy */
+      GRABBITS(15);             /* max bits for distance code */
+      if ((e = (t = td + ((uInt)b & md))->exop) < 0)
+        do {
+          if (e == -128)
+          {
+            z->msg = "invalid distance code";
+            UNGRAB
+            UPDATE
+            return Z_DATA_ERROR;
+          }
+          DUMPBITS(t->bits)
+          e = -e;
+        } while ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) < 0);
+      DUMPBITS(t->bits)
+
+      /* get extra bits to add to distance base */
+      GRABBITS((uInt)e)         /* get extra bits (up to 13) */
+      d = t->base + ((uInt)b & inflate_mask[e]);
+      DUMPBITS(e)
+      Tracevv((stderr, "inflate:         * distance %u\n", d));
+
+      /* do the copy */
+      m -= c;
+      if ((uInt)(q - s->window) >= d)   /* if offset before destination, */
+      {                                 /*  just copy */
+        r = q - d;
+        *q++ = *r++;  c--;              /* minimum count is three, */
+        *q++ = *r++;  c--;              /*  so unroll loop a little */
+        do {
+          *q++ = *r++;
+        } while (--c);
+      }
+      else                              /* else offset after destination */
+      {
+        e = d - (q - s->window);        /* bytes from offset to end */
+        r = s->end - e;                 /* pointer to offset */
+        if (c > (uInt)e)                /* if source crosses, */
+        {
+          c -= e;                       /* copy to end of window */
+          do {
+            *q++ = *r++;
+          } while (--e);
+          r = s->window;                /* copy rest from start of window */
+        }
+        do {                            /* copy all or what's left */
+          *q++ = *r++;
+        } while (--c);
+      }
+    }
+  } while (m >= 258 && n >= 10);
+
+  /* not enough input or output--restore pointers and return */
+  UNGRAB
+  UPDATE
+  return Z_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/inffast.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,17 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+extern int inflate_fast __P((
+    uInt,
+    uInt,
+    inflate_huft *,
+    inflate_huft *,
+    struct inflate_blocks_state *,
+    z_stream *));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/inflate.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,281 @@
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+
+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
+
+/* inflate private state */
+struct internal_state {
+
+  /* mode */
+  enum {
+      METHOD,   /* waiting for method byte */
+      FLAG,     /* waiting for flag byte */
+      BLOCKS,   /* decompressing blocks */
+      CHECK4,   /* four check bytes to go */
+      CHECK3,   /* three check bytes to go */
+      CHECK2,   /* two check bytes to go */
+      CHECK1,   /* one check byte to go */
+      DONE,     /* finished check, done */
+      BAD}      /* got an error--stay here */
+    mode;               /* current inflate mode */
+
+  /* mode dependent information */
+  union {
+    uInt method;        /* if FLAGS, method byte */
+    struct {
+      uLong was;                /* computed check value */
+      uLong need;               /* stream check value */
+    } check;            /* if CHECK, check values to compare */
+    uInt marker;        /* if BAD, inflateSync's marker bytes count */
+  } sub;        /* submode */
+
+  /* mode independent information */
+  int  nowrap;          /* flag for no wrapper */
+  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
+  struct inflate_blocks_state
+    *blocks;            /* current inflate_blocks state */
+
+};
+
+
+int inflateReset(z)
+z_stream *z;
+{
+  uLong c;
+
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->total_in = z->total_out = 0;
+  z->msg = Z_NULL;
+  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+  inflate_blocks_reset(z->state->blocks, z, &c);
+  Trace((stderr, "inflate: reset\n"));
+  return Z_OK;
+}
+
+
+int inflateEnd(z)
+z_stream *z;
+{
+  uLong c;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->blocks != Z_NULL)
+    inflate_blocks_free(z->state->blocks, z, &c);
+  ZFREE(z, z->state);
+  z->state = Z_NULL;
+  Trace((stderr, "inflate: end\n"));
+  return Z_OK;
+}
+
+
+int inflateInit2(z, w)
+z_stream *z;
+int w;
+{
+  /* initialize state */
+  if (z == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->zalloc == Z_NULL) z->zalloc = zcalloc;
+  if (z->zfree == Z_NULL) z->zfree = zcfree;
+  if ((z->state = (struct internal_state *)
+       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+    return Z_MEM_ERROR;
+  z->state->blocks = Z_NULL;
+
+  /* handle undocumented nowrap option (no zlib header or check) */
+  z->state->nowrap = 0;
+  if (w < 0)
+  {
+    w = - w;
+    z->state->nowrap = 1;
+  }
+
+  /* set window size */
+  if (w < 8 || w > 15)
+  {
+    inflateEnd(z);
+    return Z_STREAM_ERROR;
+  }
+  z->state->wbits = (uInt)w;
+
+  /* create inflate_blocks state */
+  if ((z->state->blocks =
+       inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w))
+      == Z_NULL)
+  {
+    inflateEnd(z);
+    return Z_MEM_ERROR;
+  }
+  Trace((stderr, "inflate: allocated\n"));
+
+  /* reset state */
+  inflateReset(z);
+  return Z_OK;
+}
+
+
+int inflateInit(z)
+z_stream *z;
+{
+  return inflateInit2(z, DEF_WBITS);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int inflate(z, f)
+z_stream *z;
+int f;
+{
+  int r = f;    /* to avoid warning about unused f */
+  uInt b;
+
+  if (z == Z_NULL || z->next_in == Z_NULL)
+    return Z_STREAM_ERROR;
+  r = Z_BUF_ERROR;
+  while (1) switch (z->state->mode)
+  {
+    case METHOD:
+      NEEDBYTE
+      if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED)
+      {
+        z->state->mode = BAD;
+        z->msg = "unknown compression method";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+      {
+        z->state->mode = BAD;
+        z->msg = "invalid window size";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      z->state->mode = FLAG;
+    case FLAG:
+      NEEDBYTE
+      if ((b = NEXTBYTE) & 0x20)
+      {
+        z->state->mode = BAD;
+        z->msg = "invalid reserved bit";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if (((z->state->sub.method << 8) + b) % 31)
+      {
+        z->state->mode = BAD;
+        z->msg = "incorrect header check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Trace((stderr, "inflate: zlib header ok\n"));
+      z->state->mode = BLOCKS;
+    case BLOCKS:
+      r = inflate_blocks(z->state->blocks, z, r);
+      if (r == Z_DATA_ERROR)
+      {
+        z->state->mode = BAD;
+        z->state->sub.marker = 0;       /* can try inflateSync */
+        break;
+      }
+      if (r != Z_STREAM_END)
+        return r;
+      r = Z_OK;
+      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+      if (z->state->nowrap)
+      {
+        z->state->mode = DONE;
+        break;
+      }
+      z->state->mode = CHECK4;
+    case CHECK4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = CHECK3;
+    case CHECK3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = CHECK2;
+    case CHECK2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = CHECK1;
+    case CHECK1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+
+      if (z->state->sub.check.was != z->state->sub.check.need)
+      {
+        z->state->mode = BAD;
+        z->msg = "incorrect data check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Trace((stderr, "inflate: zlib check ok\n"));
+      z->state->mode = DONE;
+    case DONE:
+      return Z_STREAM_END;
+    case BAD:
+      return Z_DATA_ERROR;
+    default:
+      return Z_STREAM_ERROR;
+  }
+}
+
+
+int inflateSync(z)
+z_stream *z;
+{
+  uInt n;       /* number of bytes to look at */
+  Byte *p;      /* pointer to bytes */
+  uInt m;       /* number of marker bytes found in a row */
+  uLong r, w;   /* temporaries to save total_in and total_out */
+
+  /* set up */
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->mode != BAD)
+  {
+    z->state->mode = BAD;
+    z->state->sub.marker = 0;
+  }
+  if ((n = z->avail_in) == 0)
+    return Z_BUF_ERROR;
+  p = z->next_in;
+  m = z->state->sub.marker;
+
+  /* search */
+  while (n && m < 4)
+  {
+    if (*p == (Byte)(m < 2 ? 0 : 0xff))
+      m++;
+    else if (*p)
+      m = 0;
+    else
+      m = 4 - m;
+    p++, n--;
+  }
+
+  /* restore */
+  z->total_in += p - z->next_in;
+  z->next_in = p;
+  z->avail_in = n;
+  z->state->sub.marker = m;
+
+  /* return no joy or set up to restart on a new block */
+  if (m != 4)
+    return Z_DATA_ERROR;
+  r = z->total_in;  w = z->total_out;
+  inflateReset(z);
+  z->total_in = r;  z->total_out = w;
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/inftrees.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,473 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+struct internal_state  {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define base more.Base
+#define next more.Next
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build __P((
+    uInt *,             /* code lengths in bits */
+    uInt,               /* number of codes */
+    uInt,               /* number of "simple" codes */
+    uInt *,             /* list of base values for non-simple codes */
+    uInt *,             /* list of extra bits for non-simple codes */
+    inflate_huft **,    /* result: starting table */
+    uInt *,             /* maximum lookup bits (returns actual) */
+    z_stream *));       /* for zalloc function */
+
+local voidp falloc __P((
+    voidp,              /* opaque pointer (not used) */
+    uInt,               /* number of items */
+    uInt));             /* size of item */
+
+local void ffree __P((
+    voidp q,            /* opaque pointer (not used) */
+    voidp p));          /* what to free (not used) */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+        /* actually lengths - 2; also see note #13 above about 258 */
+local uInt cplext[] = { /* Extra bits for literal codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 128, 128}; /* 128==invalid */
+local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+local uInt cpdext[] = { /* Extra bits for distance codes */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15         /* maximum bit length of any code */
+#define N_MAX 288       /* maximum number of codes in any set */
+
+#ifdef DEBUG
+  uInt inflate_hufts;
+#endif
+
+local int huft_build(b, n, s, d, e, t, m, zs)
+uInt *b;                /* code lengths in bits (all assumed <= BMAX) */
+uInt n;                 /* number of codes (assumed <= N_MAX) */
+uInt s;                 /* number of simple-valued codes (0..s-1) */
+uInt *d;                /* list of base values for non-simple codes */
+uInt *e;                /* list of extra bits for non-simple codes */
+inflate_huft **t;       /* result: starting table */
+uInt *m;                /* maximum lookup bits, returns actual */
+z_stream *zs;           /* for zalloc function */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
+   if the given code set is incomplete (the tables are still built in this
+   case), Z_DATA_ERROR if the input is invalid (all zero length codes or an
+   over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */
+{
+  uInt a;                       /* counter for codes of length k */
+  uInt c[BMAX+1];               /* bit length count table */
+  uInt f;                       /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register uInt i;              /* counter, current code */
+  register uInt j;              /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  register uInt *p;             /* pointer into c[], b[], or v[] */
+  register inflate_huft *q;     /* points to current table */
+  inflate_huft r;               /* table entry for structure assignment */
+  inflate_huft *u[BMAX];        /* table stack */
+  uInt v[N_MAX];                /* values in order of bit length */
+  register int w;               /* bits before this table == (l * h) */
+  uInt x[BMAX+1];               /* bit offsets, then code stack */
+  uInt *xp;                     /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  uInt z;                       /* number of entries in current table */
+
+
+  /* Generate counts for each bit length */
+  p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+  C4                            /* clear c[]--assume BMAX+1 is 16 */
+  p = b;  i = n;
+  do {
+    c[*p++]++;                  /* assume all entries <= BMAX */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (inflate_huft *)Z_NULL;
+    *m = 0;
+    return Z_OK;
+  }
+
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                        /* minimum code length */
+  if ((uInt)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((uInt)l > i)
+    l = i;
+  *m = l;
+
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return Z_DATA_ERROR;
+  if ((y -= c[i]) < 0)
+    return Z_DATA_ERROR;
+  c[i] += y;
+
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;  xp = x + 2;
+  while (--i) {                 /* note that i == g from above */
+    *xp++ = (j += *p++);
+  }
+
+
+  /* Make a table of values in order of bit lengths */
+  p = b;  i = 0;
+  do {
+    if ((j = *p++) != 0)
+      v[x[j]++] = i;
+  } while (++i < n);
+
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                 /* first Huffman code is zero */
+  p = v;                        /* grab values in bit order */
+  h = -1;                       /* no tables yet--level -1 */
+  w = -l;                       /* bits decoded == (l * h) */
+  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
+  q = (inflate_huft *)Z_NULL;   /* ditto */
+  z = 0;                        /* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+    a = c[k];
+    while (a--)
+    {
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = (z = g - w) > (uInt)l ? l : z;      /* table size upper limit */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          if (j < z)
+            while (++j < z)     /* try smaller tables up to z bits */
+            {
+              if ((f <<= 1) <= *++xp)
+                break;          /* enough codes to use up j bits */
+              f -= *xp;         /* else deduct codes from patterns */
+            }
+        }
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate and link in new table */
+        if ((q = (inflate_huft *)ZALLOC
+             (zs,z + 1,sizeof(inflate_huft))) == Z_NULL)
+        {
+          if (h)
+            inflate_trees_free(u[0], zs);
+          return Z_MEM_ERROR;   /* not enough memory */
+        }
+#ifdef DEBUG
+        inflate_hufts += z + 1;
+#endif
+        *t = q + 1;             /* link to list for huft_free() */
+        *(t = &(q->next)) = (inflate_huft *)Z_NULL;
+        u[h] = ++q;             /* table starts after link */
+
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.bits = (Byte)l;     /* bits to dump before this table */
+          r.exop = -(Char)j;    /* bits in this table */
+          r.next = q;           /* pointer to this table */
+          j = i >> (w - l);     /* (get around Turbo C bug) */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+      }
+
+      /* set up table entry in r */
+      r.bits = (Byte)(k - w);
+      if (p >= v + n)
+        r.exop = (Char)(-128);        /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.exop = (Char)(*p < 256 ? 16 : -64);   /* 256 is end-of-block code */
+        r.base = *p++;          /* simple code is just the value */
+      }
+      else
+      {
+        r.exop = (Char)e[*p - s];       /* non-simple--look up in lists */
+        r.base = d[*p++ - s];
+      }
+
+      /* fill code-like entries with r */
+      f = 1 << (k - w);
+      for (j = i >> w; j < z; j += f)
+        q[j] = r;
+
+      /* backwards increment the k-bit code i */
+      for (j = 1 << (k - 1); i & j; j >>= 1)
+        i ^= j;
+      i ^= j;
+
+      /* backup over finished tables */
+      while ((i & ((1 << w) - 1)) != x[h])
+      {
+        h--;                    /* don't need to update q */
+        w -= l;
+      }
+    }
+  }
+
+
+  /* Return Z_BUF_ERROR if we were given an incomplete table */
+  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+int inflate_trees_bits(c, bb, tb, z)
+uInt *c;                /* 19 code lengths */
+uInt *bb;               /* bits tree desired/actual depth */
+inflate_huft **tb;      /* bits tree result */
+z_stream *z;            /* for zfree function */
+{
+  int r;
+
+  r = huft_build(c, 19, 19, (uInt*)Z_NULL, (uInt*)Z_NULL, tb, bb, z);
+  if (r == Z_DATA_ERROR)
+    z->msg = "oversubscribed dynamic bit lengths tree";
+  else if (r == Z_BUF_ERROR)
+  {
+    inflate_trees_free(*tb, z);
+    z->msg = "incomplete dynamic bit lengths tree";
+    r = Z_DATA_ERROR;
+  }
+  return r;
+}
+
+
+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z)
+uInt nl;                /* number of literal/length codes */
+uInt nd;                /* number of distance codes */
+uInt *c;                /* that many (total) code lengths */
+uInt *bl;               /* literal desired/actual bit depth */
+uInt *bd;               /* distance desired/actual bit depth */
+inflate_huft **tl;      /* literal/length tree result */
+inflate_huft **td;      /* distance tree result */
+z_stream *z;            /* for zfree function */
+{
+  int r;
+
+  /* build literal/length tree */
+  if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = "oversubscribed literal/length tree";
+    else if (r == Z_BUF_ERROR)
+    {
+      inflate_trees_free(*tl, z);
+      z->msg = "incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    return r;
+  }
+
+  /* build distance tree */
+  if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = "oversubscribed literal/length tree";
+    else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+      r = Z_OK;
+    }
+#else
+      inflate_trees_free(*td, z);
+      z->msg = "incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    inflate_trees_free(*tl, z);
+    return r;
+#endif
+  }
+
+  /* done */
+  return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+local int fixed_lock = 0;
+local int fixed_built = 0;
+#define FIXEDH 530      /* number of hufts used by fixed tables */
+local uInt fixed_left = FIXEDH;
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+
+
+local voidp falloc(q, n, s)
+voidp q;        /* opaque pointer (not used) */
+uInt n;         /* number of items */
+uInt s;         /* size of item */
+{
+  Assert(s == sizeof(inflate_huft) && n <= fixed_left,
+         "inflate_trees falloc overflow");
+  if (q) s++; /* to make some compilers happy */
+  fixed_left -= n;
+  return (voidp)(fixed_mem + fixed_left);
+}
+
+
+local void ffree(q, p)
+voidp q;
+voidp p;
+{
+  Assert(0, "inflate_trees ffree called!");
+  if (q) q = p; /* to make some compilers happy */
+}
+
+
+int inflate_trees_fixed(bl, bd, tl, td)
+uInt *bl;               /* literal desired/actual bit depth */
+uInt *bd;               /* distance desired/actual bit depth */
+inflate_huft **tl;      /* literal/length tree result */
+inflate_huft **td;      /* distance tree result */
+{
+  /* build fixed tables if not built already--lock out other instances */
+  while (++fixed_lock > 1)
+    fixed_lock--;
+  if (!fixed_built)
+  {
+    int k;              /* temporary variable */
+    unsigned c[288];    /* length list for huft_build */
+    z_stream z;         /* for falloc function */
+
+    /* set up fake z_stream for memory routines */
+    z.zalloc = falloc;
+    z.zfree = ffree;
+    z.opaque = Z_NULL;
+
+    /* literal table */
+    for (k = 0; k < 144; k++)
+      c[k] = 8;
+    for (; k < 256; k++)
+      c[k] = 9;
+    for (; k < 280; k++)
+      c[k] = 7;
+    for (; k < 288; k++)
+      c[k] = 8;
+    fixed_bl = 7;
+    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z);
+
+    /* distance table */
+    for (k = 0; k < 30; k++)
+      c[k] = 5;
+    fixed_bd = 5;
+    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z);
+
+    /* done */
+    fixed_built = 1;
+  }
+  fixed_lock--;
+  *bl = fixed_bl;
+  *bd = fixed_bd;
+  *tl = fixed_tl;
+  *td = fixed_td;
+  return Z_OK;
+}
+
+
+int inflate_trees_free(t, z)
+inflate_huft *t;        /* table to free */
+z_stream *z;            /* for zfree function */
+/* Free the malloc'ed tables built by huft_build(), which makes a linked
+   list of the tables it made, with the links in a dummy first entry of
+   each table. */
+{
+  register inflate_huft *p, *q;
+
+  /* Don't free fixed trees */
+  if (t >= fixed_mem && t <= fixed_mem + FIXEDH)
+    return Z_OK;
+
+  /* Go through linked list, freeing from the malloced (t[-1]) address. */
+  p = t;
+  while (p != Z_NULL)
+  {
+    q = (--p)->next;
+    ZFREE(z,p);
+    p = q;
+  } 
+  return Z_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/inftrees.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,68 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model).
+   Valid extra bits (exop) are 0..13.  exop == -64 is EOB (end of block),
+   exop == 16 means that v is a literal, exop < 0 means that v is a pointer
+   to the next table, which codes -exop bits, and lastly exop == -128
+   indicates an unused code.  If a code with exop == -128 is looked up,
+   this implies an error in the data. */
+
+#if defined(STDC) || defined(sgi)
+typedef signed char Char;
+#else
+typedef char Char; /* just hope that char is signed */
+#endif
+
+typedef struct inflate_huft_s inflate_huft;
+struct inflate_huft_s {
+  union {
+    struct {
+      Char Exop;        /* number of extra bits or operation */
+      Byte Bits;        /* number of bits in this code or subcode */
+    } what;
+    Byte *pad;          /* pad structure to a power of 2 (4 bytes for */
+  } word;               /*  16-bit, 8 bytes for 32-bit machines) */
+  union {
+    uInt Base;          /* literal, length base, or distance base */
+    inflate_huft *Next; /* pointer to next level of table */
+  } more;
+};
+
+#ifdef DEBUG
+  extern uInt inflate_hufts;
+#endif
+
+extern int inflate_trees_bits __P((
+    uInt *,                     /* 19 code lengths */
+    uInt *,                     /* bits tree desired/actual depth */
+    inflate_huft **,            /* bits tree result */
+    z_stream *));               /* for zalloc, zfree functions */
+
+extern int inflate_trees_dynamic __P((
+    uInt,                       /* number of literal/length codes */
+    uInt,                       /* number of distance codes */
+    uInt *,                     /* that many (total) code lengths */
+    uInt *,                     /* literal desired/actual bit depth */
+    uInt *,                     /* distance desired/actual bit depth */
+    inflate_huft **,            /* literal/length tree result */
+    inflate_huft **,            /* distance tree result */
+    z_stream *));               /* for zalloc, zfree functions */
+
+extern int inflate_trees_fixed __P((
+    uInt *,                     /* literal desired/actual bit depth */
+    uInt *,                     /* distance desired/actual bit depth */
+    inflate_huft **,            /* literal/length tree result */
+    inflate_huft **));          /* distance tree result */
+
+extern int inflate_trees_free __P((
+    inflate_huft *,             /* tables to free */
+    z_stream *));               /* for zfree function */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/infutil.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,84 @@
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* And'ing with mask[n] masks the lower n bits */
+uInt inflate_mask[] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+
+/* copy as much as possible from the sliding window to the output area */
+int inflate_flush(s, z, r)
+struct inflate_blocks_state *s;
+z_stream *z;
+int r;
+{
+  uInt n;
+  Byte *p, *q;
+
+  /* local copies of source and destination pointers */
+  p = z->next_out;
+  q = s->read;
+
+  /* compute number of bytes to copy as far as end of window */
+  n = (uInt)((q <= s->write ? s->write : s->end) - q);
+  if (n > z->avail_out) n = z->avail_out;
+  if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+  /* update counters */
+  z->avail_out -= n;
+  z->total_out += n;
+
+  /* update check information */
+  if (s->checkfn != Z_NULL)
+    s->check = (*s->checkfn)(s->check, q, n);
+
+  /* copy as far as end of window */
+  zmemcpy(p, q, n);
+  p += n;
+  q += n;
+
+  /* see if more to copy at beginning of window */
+  if (q == s->end)
+  {
+    /* wrap pointers */
+    q = s->window;
+    if (s->write == s->end)
+      s->write = s->window;
+
+    /* compute bytes to copy */
+    n = (uInt)(s->write - q);
+    if (n > z->avail_out) n = z->avail_out;
+    if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+    /* update counters */
+    z->avail_out -= n;
+    z->total_out += n;
+
+    /* update check information */
+    if (s->checkfn != Z_NULL)
+      s->check = (*s->checkfn)(s->check, q, n);
+
+    /* copy */
+    zmemcpy(p, q, n);
+    p += n;
+    q += n;
+  }
+
+  /* update pointers */
+  z->next_out = p;
+  s->read = q;
+
+  /* done */
+  return r;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/infutil.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,87 @@
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+  /* mode */
+  enum {
+      TYPE,     /* get type bits (3, including end bit) */
+      LENS,     /* get lengths for stored */
+      STORED,   /* processing stored block */
+      TABLE,    /* get table lengths */
+      BTREE,    /* get bit lengths tree for a dynamic block */
+      DTREE,    /* get length, distance trees for a dynamic block */
+      CODES,    /* processing fixed or dynamic block */
+      DRY,      /* output remaining window bytes */
+      DONE,     /* finished last block, done */
+      BAD}      /* got a data error--stuck here */
+    mode;               /* current inflate_block mode */
+
+  /* mode dependent information */
+  union {
+    uInt left;          /* if STORED, bytes left to copy */
+    struct {
+      uInt table;               /* table lengths (14 bits) */
+      uInt index;               /* index into blens (or border) */
+      uInt *blens;              /* bit lengths of codes */
+      uInt bb;                  /* bit length tree depth */
+      inflate_huft *tb;         /* bit length decoding tree */
+    } trees;            /* if DTREE, decoding info for trees */
+    struct inflate_codes_state
+      *codes;           /* if CODES, current state */
+  } sub;                /* submode */
+  uInt last;            /* true if this block is the last block */
+
+  /* mode independent information */
+  uInt bitk;            /* bits in bit buffer */
+  uLong bitb;           /* bit buffer */
+  Byte *window;         /* sliding window */
+  Byte *end;            /* one byte after sliding window */
+  Byte *read;           /* window read pointer */
+  Byte *write;          /* window write pointer */
+  check_func checkfn;   /* check function */
+  uLong check;          /* check on output */
+
+};
+
+/* defines for inflate input/output */
+/*   update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/*   get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/*   output bytes */
+#define WAVAIL (q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/*   load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* masks for lower bits */
+extern uInt inflate_mask[];
+
+/* copy as much as possible from the sliding window to the output area */
+extern int inflate_flush __P((
+    struct inflate_blocks_state *,
+    z_stream *,
+    int));
+
+struct internal_state      {int dummy;}; /* for buggy compilers */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/minigzip.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,227 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* $Id: minigzip.c,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifndef __GO32__
+extern void exit  __P((int));
+#endif
+extern int unlink __P((const char *));
+
+#ifdef STDC
+#  include <string.h>
+#endif
+
+#ifdef MSDOS
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#define BUFLEN 4096
+#define MAX_NAME_LEN 1024
+
+#define local static
+/* For MSDOS and other systems with limitation on stack size. For Unix,
+    #define local
+   works also.
+ */
+
+char *prog;
+
+void error           __P((char *msg));
+void gz_compress     __P((FILE   *in, gzFile out));
+void gz_uncompress   __P((gzFile in, FILE   *out));
+void file_compress   __P((char  *file));
+void file_uncompress __P((char  *file));
+void main            __P((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+    char *msg;
+{
+    fprintf(stderr, "%s: %s\n", prog, msg);
+    exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+void gz_compress(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+    for (;;) {
+        len = fread(buf, 1, sizeof(buf), in);
+        if (ferror(in)) {
+            perror("fread");
+            exit(1);
+        }
+        if (len == 0) break;
+
+        if (gzwrite(out, buf, len) != len) error(gzerror(out, &err));
+    }
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+    gzFile in;
+    FILE   *out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+    for (;;) {
+        len = gzread(in, buf, sizeof(buf));
+        if (len < 0) error (gzerror(in, &err));
+        if (len == 0) break;
+
+        if (fwrite(buf, 1, len, out) != (uInt)len) error("failed fwrite");
+    }
+    if (fclose(out)) error("failed fclose");
+
+    if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file)
+    char  *file;
+{
+    local char outfile[MAX_NAME_LEN];
+    FILE  *in;
+    gzFile out;
+
+    strcpy(outfile, file);
+    strcat(outfile, ".gz");
+
+    in = fopen(file, "rb");
+    if (in == NULL) {
+        perror(file);
+        exit(1);
+    }
+    out = gzopen(outfile, "wb");
+    if (out == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+        exit(1);
+    }
+    gz_compress(in, out);
+
+    unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+    char  *file;
+{
+    local char buf[MAX_NAME_LEN];
+    char *infile, *outfile;
+    FILE  *out;
+    gzFile in;
+    int len = strlen(file);
+
+    strcpy(buf, file);
+
+    if (len > 3 && strcmp(file+len-3, ".gz") == 0) {
+        infile = file;
+        outfile = buf;
+        outfile[len-3] = '\0';
+    } else {
+        outfile = file;
+        infile = buf;
+        strcat(infile, ".gz");
+    }
+    in = gzopen(infile, "rb");
+    if (in == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+        exit(1);
+    }
+    out = fopen(outfile, "wb");
+    if (out == NULL) {
+        perror(file);
+        exit(1);
+    }
+
+    gz_uncompress(in, out);
+
+    unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage:  minigzip [-d] [files...]
+ */
+
+void main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    int uncompr = 0;
+    gzFile file;
+
+    prog = argv[0];
+    argc--, argv++;
+
+    if (argc > 0) {
+        uncompr = (strcmp(*argv, "-d") == 0);
+        if (uncompr) {
+            argc--, argv++;
+        }
+    }
+    if (argc == 0) {
+        SET_BINARY_MODE(stdin);
+        SET_BINARY_MODE(stdout);
+        if (uncompr) {
+            file = gzdopen(fileno(stdin), "rb");
+            if (file == NULL) error("can't gzdopen stdin");
+            gz_uncompress(file, stdout);
+        } else {
+            file = gzdopen(fileno(stdout), "wb");
+            if (file == NULL) error("can't gzdopen stdout");
+            gz_compress(stdin, file);
+        }
+    } else {
+        do {
+            if (uncompr) {
+                file_uncompress(*argv);
+            } else {
+                file_compress(*argv);
+            }
+        } while (argv++, --argc);
+    }
+    exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/trees.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,1060 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* $Id: trees.c,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ * To do: initialize at compile time to be completely reentrant. ???
+ */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see ct_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+local uch dist_code[512];
+/* distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+local uch length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+struct static_tree_desc_s {
+    ct_data *static_tree;        /* static tree or NULL */
+    int     *extra_bits;         /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(ct_data *)0, extra_blbits, 0,      BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void ct_static_init __P((void));
+local void init_block     __P((deflate_state *s));
+local void pqdownheap     __P((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     __P((deflate_state *s, tree_desc *desc));
+local void gen_codes      __P((ct_data *tree, int max_code, ush bl_count[]));
+local void build_tree     __P((deflate_state *s, tree_desc *desc));
+local void scan_tree      __P((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      __P((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  __P((deflate_state *s));
+local void send_all_trees __P((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block __P((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local void set_data_type  __P((deflate_state *s));
+local void send_bits      __P((deflate_state *s, int value, int length));
+local unsigned bi_reverse __P((unsigned value, int length));
+local void bi_windup      __P((deflate_state *s));
+local void copy_block     __P((deflate_state *s, char *buf, unsigned len,
+                               int header));
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (verbose>1) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+#define d_code(dist) \
+   ((dist) < 256 ? dist_code[dist] : dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. dist_code[256] and dist_code[257] are never
+ * used.
+ */
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ * To do: do this at compile time.
+ */
+local void ct_static_init()
+{
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "ct_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "ct_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "ct_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse(n, 5);
+    }
+}
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ct_init(s)
+    deflate_state *s;
+{
+    if (static_dtree[0].Len == 0) {
+        ct_static_init();              /* To do: at compile time */
+    }
+
+    s->compressed_len = 0L;
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree  = desc->dyn_tree;
+    int max_code   = desc->max_code;
+    ct_data *stree = desc->stat_desc->static_tree;
+    int *extra     = desc->stat_desc->extra_bits;
+    int base       = desc->stat_desc->extra_base;
+    int max_length = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if (tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ush bl_count[];            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracec(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree   = desc->dyn_tree;
+    ct_data *stree  = desc->stat_desc->static_tree;
+    int elems       = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node = elems;  /* next internal node of the tree */
+    int new;           /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        new = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[new].Freq = 1;
+        s->depth[new] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[new].Len;
+        /* new is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ct_stored_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    char *buf;        /* input block */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
+    s->compressed_len = (s->compressed_len + 3 + 7) & ~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file. This function
+ * returns the total compressed length for the file so far.
+ */
+ulg ct_flush_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    char *buf;        /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+     /* Check if the file is ascii or binary */
+    if (s->data_type == UNKNOWN) set_data_type(s);
+
+    /* Construct the literal and distance trees */
+    build_tree(s, (tree_desc *)(&(s->l_desc)));
+    Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+            s->static_len));
+
+    build_tree(s, (tree_desc *)(&(s->d_desc)));
+    Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+            s->static_len));
+    /* At this point, opt_len and static_len are the total bit lengths of
+     * the compressed block data, excluding the tree representations.
+     */
+
+    /* Build the bit length tree for the above two trees, and get the index
+     * in bl_order of the last bit length code to send.
+     */
+    max_blindex = build_bl_tree(s);
+
+    /* Determine the best encoding. Compute first the block length in bytes */
+    opt_lenb = (s->opt_len+3+7)>>3;
+    static_lenb = (s->static_len+3+7)>>3;
+
+    Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+            opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+            s->last_lit));
+
+    if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    /* If compression failed and this is the first and last block,
+     * and if the .zip file can be seeked (to rewrite the local header),
+     * the whole file is transformed into a stored file:
+     */
+#ifdef STORED_FILE_OK
+#  ifdef FORCE_STORED_FILE
+    if (eof && compressed_len == 0L) { /* force stored file */
+#  else
+    if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) {
+#  endif
+        /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
+        if (buf == (char*)0) error ("block vanished");
+
+        copy_block(buf, (unsigned)stored_len, 0); /* without header */
+        s->compressed_len = stored_len << 3;
+        s->method = STORED;
+    } else
+#endif /* STORED_FILE_OK */
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        ct_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+eof, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+        s->compressed_len += 3 + s->static_len;
+    } else {
+        send_bits(s, (DYN_TREES<<1)+eof, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+        s->compressed_len += 3 + s->opt_len;
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    init_block(s);
+
+    if (eof) {
+        bi_windup(s);
+        s->compressed_len += 7;  /* align on byte boundary */
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*eof));
+
+    return s->compressed_len >> 3;
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ct_tally (s, dist, lc)
+    deflate_state *s;
+    int dist;  /* distance of matched string */
+    int lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "ct_tally: bad match");
+
+        s->dyn_ltree[length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+    /* Try to guess if it is profitable to stop the current block here */
+    if (s->level > 2 && (s->last_lit & 0xfff) == 0) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)s->strstart - s->block_start;
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+    deflate_state *s;
+{
+    int n = 0;
+    unsigned ascii_freq = 0;
+    unsigned bin_freq = 0;
+    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
+    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
+    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? BINARY : ASCII);
+}
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+#ifdef DEBUG
+    Tracev((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+#endif
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (value << s->bi_valid);
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Write out any remaining bits in an incomplete byte.
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    char     *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);              /* align on byte boundary */
+
+    if (header) {
+        put_short(s, (ush)len);   
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/uncompr.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,58 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* $Id: uncompr.c,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int uncompress (dest, destLen, source, sourceLen)
+    Byte *dest;
+    uLong *destLen;
+    Byte *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        return err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/zconf.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,90 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* $Id: zconf.h,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+     The library does not install any signal handler. It is recommended to
+  add at least a handler for SIGSEGV when decompressing; the library checks
+  the consistency of the input data whenever possible but may go nuts
+  for some forms of corrupted input.
+ */
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(_GNUC__) && !defined(__32BIT__)
+#  define __32BIT__
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if defined(MSDOS) && !defined(__32BIT__)
+#  define MAXSEG_64K
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(__STDC__))
+#  define STDC
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2 */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            1 << (windowBits+2)   +  1 << (memLevel+9)
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef __P /* function prototypes */
+#  ifdef STDC
+#    define __P(args)  args
+#  else
+#    define __P(args)  ()
+#  endif
+#endif
+
+#ifndef Byte
+  typedef unsigned char  Byte;  /* 8 bits */
+#endif
+#ifndef uInt
+  typedef unsigned int   uInt;  /* 16 bits or more */
+#endif
+#ifndef uLong
+  typedef unsigned long  uLong; /* 32 bits or more */
+#endif
+#ifndef voidp
+#  ifdef STDC
+     typedef void *voidp;
+#  else
+     typedef Byte *voidp;
+#  endif
+#endif
+
+#endif /* _ZCONF_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/zlib.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,615 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 0.92 May 3rd, 1995.
+
+  Copyright (C) 1995 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  gzip@prep.ai.mit.edu    madler@cco.caltech.edu
+ */
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "zconf.h"
+
+#define ZLIB_VERSION "0.92"
+
+/* 
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms may be added later and will have the same
+  stream interface.
+
+     For compression the application must provide the output buffer and
+  may optionally provide the input buffer for optimization. For decompression,
+  the application must provide the input buffer and may optionally provide
+  the output buffer for optimization.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+*/
+
+typedef voidp (*alloc_func) __P((voidp opaque, uInt items, uInt size));
+typedef void  (*free_func)  __P((voidp opaque, voidp address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Byte     *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Byte     *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidp      opaque;  /* private data object passed to zalloc and zfree */
+
+    Byte     data_type; /* best guess about the data type: ascii or binary */
+
+} z_stream;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_FULL_FLUSH    2
+#define Z_FINISH        4
+/* See deflate() below for the usage of these constants */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+/* error codes for the compression/decompression functions */
+
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Used to set the data_type field */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+extern char *zlib_version;
+/* The application can compare zlib_version and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+ */
+
+                        /* basic functions */
+
+extern int deflateInit __P((z_stream *strm, int level));
+/* 
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 1 and 9:
+   1 gives best speed, 9 gives best compression. Z_DEFAULT_COMPRESSION requests
+   a default compromise between speed and compression (currently equivalent
+   to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level.
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+extern int deflate __P((z_stream *strm, int flush));
+/*
+  Performs one or both of the following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate().
+
+    If the parameter flush is set to Z_PARTIAL_FLUSH, the current compression
+  block is terminated and flushed to the output buffer so that the
+  decompressor can get all input data available so far. For method 9, a future
+  variant on method 8, the current block will be flushed but not terminated.
+  If flush is set to Z_FULL_FLUSH, the compression block is terminated, a
+  special marker is output and the compression dictionary is discarded; this
+  is useful to allow the decompressor to synchronize if one compressed block
+  has been damaged (see inflateSync below).  Flushing degrades compression and
+  so should be used only when necessary.  Using Z_FULL_FLUSH too often can
+  seriously degrade the compression.
+
+    If the parameter flush is set to Z_FINISH, all pending input is processed,
+  all pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+  
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() may update data_type if it can make a good guess about
+  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
+*/
+
+
+extern int deflateEnd __P((z_stream *strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent. In the error case, msg may be set
+   but then points to a static string (which must not be deallocated).
+*/
+
+
+extern int inflateInit __P((z_stream *strm));
+/* 
+     Initializes the internal stream state for decompression. The fields
+   zalloc and zfree must be initialized before by the caller.  If zalloc and
+   zfree are set to Z_NULL, deflateInit updates them to use default allocation
+   functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory.  msg is set to null if there is no error message.
+   inflateInit does not perform any decompression: this will be done by
+   inflate().
+*/
+
+
+extern int inflate __P((z_stream *strm, int flush));
+/*
+  Performs one or both of the following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() always provides as much output as possible
+    (until no more input data or no more space in the output buffer).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate().
+
+    If the parameter flush is set to Z_PARTIAL_FLUSH, inflate flushes as much
+  output as possible to the output buffer. The flushing behavior of inflate is
+  not specified for values of the flush parameter other than Z_PARTIAL_FLUSH
+  and Z_FINISH, but the current implementation actually flushes as much output
+  as possible anyway.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state.
+
+    inflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if the end of the
+  compressed data has been reached and all uncompressed output has been
+  produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if
+  the stream structure was inconsistent (for example if next_in or next_out
+  was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no
+  progress is possible or if there was not enough room in the output buffer
+  when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then
+  call inflateSync to look for a good compression block.
+*/
+
+
+extern int inflateEnd __P((z_stream *strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+extern int deflateInit2 __P((z_stream *strm,
+                             int  level,
+                             int  method,
+                             int  windowBits,
+                             int  memLevel,
+                             int  strategy));
+/*   
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc and zfree must be initialized before by the caller.
+
+     The method parameter is the compression method. It must be 8 in this
+   version of the library. (Method 9 will allow a 64K history buffer and
+   partial block flushes.)
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library (the value 16 will be allowed for method 9). Larger
+   values of this parameter result in better compression at the expense of
+   memory usage. The default value is 15 if deflateInit is used instead.
+
+    The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use
+   the value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data
+   produced by a filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman
+   encoding only (no string match).  Filtered data consists mostly of small
+   values with a somewhat random distribution. In this case, the
+   compression algorithm is tuned to compress them better. The strategy
+   parameter only affects the compression ratio but not the correctness of
+   the compressed output even if it is not set appropriately.
+
+     If next_in is not null, the library will use this buffer to hold also
+   some history information; the buffer must either hold the entire input
+   data, or have at least 1<<(windowBits+1) bytes and be writable. If next_in
+   is null, the library will allocate its own history buffer (and leave next_in
+   null). next_out need not be provided here but must be provided by the
+   application for the next call of deflate().
+
+     If the history buffer is provided by the application, next_in must
+   must never be changed by the application since the compressor maintains
+   information inside this buffer from call to call; the application
+   must provide more input only by increasing avail_in. next_in is always
+   reset by the library in this case.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
+   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
+   an invalid method). msg is set to null if there is no error message.
+   deflateInit2 does not perform any compression: this will be done by
+   deflate().
+*/
+                            
+extern int deflateCopy __P((z_stream *dest,
+                            z_stream *source));
+/*
+     Sets the destination stream as a complete copy of the source stream.  If
+   the source stream is using an application-supplied history buffer, a new
+   buffer is allocated for the destination stream.  The compressed output
+   buffer is always application-supplied. It's the responsibility of the
+   application to provide the correct values of next_out and avail_out for the
+   next call of deflate.
+
+     This function is useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+      deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+extern int deflateReset __P((z_stream *strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+extern int inflateInit2 __P((z_stream *strm,
+                             int  windowBits));
+/*   
+     This is another version of inflateInit with more compression options. The
+   fields next_out, zalloc and zfree must be initialized before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library (the value 16 will be allowed soon). The
+   default value is 15 if inflateInit is used instead. If a compressed stream
+   with a larger window size is given as input, inflate() will return with
+   the error code Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     If next_out is not null, the library will use this buffer for the history
+   buffer; the buffer must either be large enough to hold the entire output
+   data, or have at least 1<<windowBits bytes.  If next_out is null, the
+   library will allocate its own buffer (and leave next_out null). next_in
+   need not be provided here but must be provided by the application for the
+   next call of inflate().
+
+     If the history buffer is provided by the application, next_out must
+   never be changed by the application since the decompressor maintains
+   history information inside this buffer from call to call; the application
+   can only reset next_out to the beginning of the history buffer when
+   avail_out is zero and all output has been consumed.
+
+      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was
+   not enough memory, Z_STREAM_ERROR if a parameter is invalid (such as
+   windowBits < 8). msg is set to null if there is no error message.
+   inflateInit2 does not perform any compression: this will be done by
+   inflate().
+*/
+
+extern int inflateSync __P((z_stream *strm));
+/* 
+    Skips invalid compressed data until the special marker (see deflate()
+  above) can be found, or until all available input is skipped. No output
+  is provided.
+
+    inflateSync returns Z_OK if the special marker has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no marker has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+extern int inflateReset __P((z_stream *strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level, window size,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+extern int compress __P((Byte *dest,   uLong *destLen,
+                         Byte *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least 0.1% larger than
+   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+extern int uncompress __P((Byte *dest,   uLong *destLen,
+                           Byte *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+
+
+typedef voidp gzFile;
+
+extern gzFile gzopen  __P((char *path, char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb"). gzopen can also be used to read a file
+   which is not in gzip format; in this case gzread will directly read from
+   the file without decompression.
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).
+*/
+
+extern gzFile gzdopen  __P((int fd, char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, or pipe.
+   The mode parameter is as in fopen ("rb" or "wb").
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+extern int    gzread  __P((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+extern int    gzwrite __P((gzFile file, voidp buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+extern int    gzflush __P((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+extern int    gzclose __P((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+extern char*   gzerror __P((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+extern uLong adler32 __P((uLong adler, Byte *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+extern uLong crc32   __P((uLong crc, Byte *buf, uInt len));
+/*
+     Update a running crc with the bytes buf[0..len-1] and return the updated
+   crc. If buf is NULL, this function returns the required initial value
+   for the crc. Pre- and post-conditioning (one's complement) is performed
+   within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+#ifndef _Z_UTIL_H
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+#endif /* _ZLIB_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/zutil.c	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,178 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* $Id: zutil.c,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+#ifndef __GO32__
+extern void exit __P((int));
+#endif
+
+char *zlib_version = ZLIB_VERSION;
+
+char *z_errmsg[] = {
+"stream end",          /* Z_STREAM_END    1 */
+"",                    /* Z_OK            0 */
+"file error",          /* Z_ERRNO        (-1) */
+"stream error",        /* Z_STREAM_ERROR (-2) */
+"data error",          /* Z_DATA_ERROR   (-3) */
+"insufficient memory", /* Z_MEM_ERROR    (-4) */
+"buffer error",        /* Z_BUF_ERROR    (-5) */
+""};
+
+
+void z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+    Byte* dest;
+    Byte* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+void zmemzero(dest, len)
+    Byte* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#if defined(__TURBOC__) && !defined(__SMALL__)
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidp org_ptr;
+    voidp new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidp zcalloc (voidp opaque, unsigned items, unsigned size)
+{
+    voidp buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    if (bsize < 65536L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void  zcfree (voidp opaque, voidp ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    z_error("zcfree: ptr not found");
+}
+#endif /* __TURBOC__ */
+
+#if defined(M_I86CM) || defined(M_I86LM) /* MSC compact or large model */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER < 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidp zcalloc (voidp opaque, unsigned items, unsigned size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void  zcfree (voidp opaque, voidp ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* defined(M_I86CM) || defined(M_I86LM) */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef __GO32__
+extern voidp calloc __P((uInt items, uInt size));
+extern void  free   __P((voidp ptr));
+#endif
+
+voidp zcalloc (opaque, items, size)
+    voidp opaque;
+    unsigned items;
+    unsigned size;
+{
+    return calloc(items, size);
+}
+
+void  zcfree (opaque, ptr)
+    voidp opaque;
+    voidp ptr;
+{
+    free(ptr);
+}
+
+#endif /* MY_ZCALLOC */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zlib/zutil.h	Sat Dec 06 05:41:29 1997 +0000
@@ -0,0 +1,183 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* $Id: zutil.h,v 1.1.1.1 1997/12/06 05:41:38 darius Exp $ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifdef __GNUC__
+#  define INLINE inline
+#else
+#  define INLINE
+#endif
+
+#ifdef MSDOS
+#   include <stddef.h>
+#   include <errno.h>
+#else
+    extern int errno;
+#endif
+#ifdef STDC
+#  include <string.h>
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef unsigned short ush;
+typedef unsigned long  ulg;
+
+extern char *z_errmsg[]; /* indexed by 1-zlib_error */
+
+#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err)
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#define DEFLATED   8
+
+#define DEF_WBITS 15
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+        /* target dependencies */
+
+#ifdef MSDOS
+#  define OS_CODE  0x00
+#  ifdef __TURBOC__
+#    include <alloc.h>
+#  else /* MSC */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#endif
+
+#ifdef WIN32 /* Windows NT */
+#  define OS_CODE  0x0b
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define FOPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef MACOS
+#  define OS_CODE  0x07
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0F
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+        /* Common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef FOPEN
+#  define FOPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#ifdef HAVE_STRERROR
+   extern char *strerror __P((int));
+#  define zstrerror(errnum) strerror(errnum)
+#else
+#  define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr) && !defined(NO_MEMCPY)
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  define zmemcpy memcpy
+#  define zmemzero(dest, len) memset(dest, 0, len)
+#else
+   extern void zmemcpy  __P((Byte* dest, Byte* source, uInt len));
+   extern void zmemzero __P((Byte* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+#  ifndef verbose
+#    define verbose 0
+#  endif
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x ;}
+#  define Tracevv(x) {if (verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+typedef uLong (*check_func) __P((uLong check, Byte *buf, uInt len));
+
+extern void z_error    __P((char *m));
+
+voidp zcalloc __P((voidp opaque, unsigned items, unsigned size));
+void  zcfree  __P((voidp opaque, voidp ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidp)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* _Z_UTIL_H */