[comp.sources.games] v06i014: ega-wanderer - wanderer 2.2 for EGA or curses, Patch1

games@tekred.CNA.TEK.COM (02/25/89)

Submitted-by: Rick Richardson <pcrat!rick@uunet.uu.net>
Posting-number: Volume 6, Issue 14
Archive-name: ega-wanderer/Patch1

	[This is *not* a patch(1) file. Do not feed it to patch. This
	 contains replacement files for some of the existing files of
	 ega-wanderer to add support for VENIX/286 and 386/ix 1.0.6
	 screen mapping. -br]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  README.rer Makefile 386ix.c 386ix_ega.c iAPX286.c
#   venix286.c ega.c bitmap.h m.c save.c scores.c
# Wrapped by rick@pcroe on Mon Feb 20 15:41:47 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'README.rer' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README.rer'\"
else
echo shar: Extracting \"'README.rer'\" \(872 characters\)
sed "s/^X//" >'README.rer' <<'END_OF_FILE'
X
X
X	These are the files I changed from Dave Bodenstab's
X	(...att!iwsl8!imdave) EGA version of wanderer 2.2, with support
X	for VENIX/286 screen mapping, 386/ix 1.0.6 screen mapping,
X	and of course the original V/AT mapping.
X	
X	I split out the stuff I thought would be common to all EGA's,
X	and made a separate file to do the mapping.  I also fixed
X	a couple of bugs.  You have to take Dave's post and replace
X	the files in there with the ones I have here.
X	
X	As Dave said, just to get it working.  I'm not interested in
X	maintaining this.  I sure hope, though, that future posts
X	contain some of these changes.
X	
X	BTW, I messed around with color here, but those changes
X	start to get really unportable.
X	
X	This is an excellent game, and I wonder why Mr. Shipway didn't
X	go commercial with it.  I think it would be racking up quarters
X	in the arcades.
X	
X	-Rick Richardson
X
X
X
END_OF_FILE
if test 872 -ne `wc -c <'README.rer'`; then
    echo shar: \"'README.rer'\" unpacked with wrong size!
fi
# end of 'README.rer'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(2104 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# Makefile for wanderer
X
XCURSESO = m.o save.o jump.o display.o icon.o game.o read.o help.o fall.o \
X	scores.o edit.o
XEGAO = 159x174.o 16x16.o 48x48.o ega.o
X
X# For the EGA version, pick an initialization routine(s)
XEGAINITO= iAPX286.o
XEGAINITO= venix286.o
XEGAINITO= 386ix.o 386ix_ega.o
XEGA = -DEGA
XOBJ = $(CURSESO) $(EGAO) $(EGAINITO)
X# MODEL = -Ml
XSTACK =
X
X# If you just want the curses version, then use
X#EGA =
X#OBJ = $(CURSESO)
X#MODEL =
X#STACK = -k 0x4000
X
X# You're on your own here...
XG = -g
X#O = -O
X#S = -s
XCFLAGS = $(MODEL) $G $O $(EGA)
XLDFLAGS = $(MODEL) $G $S $(STACK)
XLIBS = -lcurses
X
XDEST = /usr/games
XDESTLIB=/usr/games/lib
XSCORE = $(DESTLIB)/.wanderer
XSCREENS = $(DESTLIB)/wanderer
XGUID= games
XGGID= other
X
Xwanderer: $(OBJ)
X	$(CC) $(LDFLAGS) -o wanderer $(OBJ) $(LIBS)
X
Xinstall: wanderer
X	if [ ! -d $(DEST) ]; then \
X		mkdir $(DEST); \
X		chown $(GUID) $(DEST); \
X		chgrp $(GGID) $(DEST); \
X	fi
X	cp wanderer $(DEST)
X	chown $(GUID) $(DEST)/wanderer
X	chgrp $(GGID) $(DEST)/wanderer
X	chmod 2755 $(DEST)/wanderer		# sgid
X	if [ ! -d $(DESTLIB) ]; then \
X		mkdir $(DESTLIB); \
X		chown $(GUID) $(DESTLIB); \
X		chgrp $(GGID) $(DESTLIB); \
X	fi
X	touch $(SCORE)				# score file
X	chown $(GUID) $(SCORE)
X	chgrp $(GGID) $(SCORE)
X	chmod 660 $(SCORE)
X	if [ ! -d $(SCREENS) ]; then \
X		mkdir $(SCREENS); \
X		chown $(GUID) $(SCREENS); \
X		chgrp $(GGID) $(SCREENS); \
X	fi
X	cp screens/screen.[1-9]* $(SCREENS)	# screens
X	chown $(GUID) $(SCREENS)/*
X	chgrp $(GGID) $(SCREENS)/*
X
Xclean:
X	rm -f *.o core tags
Xclobber: clean
X	rm -f wanderer
X
Xdepend:
X	mkdepend -mMakefile *.c
X
X# DO NOT DELETE THIS LINE - make depend DEPENDS ON IT
X# Dependencies generated at: Mon Jan 2 12:08:35 CST 1989
X
Xm.o:	bitmap.h  wand_head.h  
Xsave.o:	wand_head.h  
Xjump.o:	wand_head.h  
Xdisplay.o:	bitmap.h  wand_head.h  
Xicon.o:	bitmap.h  wand_head.h  
Xgame.o:	bitmap.h  wand_head.h  
Xread.o:	wand_head.h  
Xhelp.o:	wand_head.h  
Xfall.o:	bitmap.h  wand_head.h  
Xscores.o:	wand_head.h  
Xedit.o:	bitmap.h  wand_head.h  
X159x174.o:	bitmap.h  
X16x16.o:	bitmap.h  
X48x48.o:	bitmap.h  
XiAPX286.o:	bitmap.h  
X
X# DO NOT ADD ANYTHING HERE - WILL GO AWAY
END_OF_FILE
if test 2104 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f '386ix.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'386ix.c'\"
else
echo shar: Extracting \"'386ix.c'\" \(1431 characters\)
sed "s/^X//" >'386ix.c' <<'END_OF_FILE'
X/*
X *	EGA init/reset for 386/ix 1.0.6
X */
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/at_ansi.h>
X#include <sys/kd.h>
X#include <sys/vt.h>
X#include <signal.h>
X
Xtypedef	unsigned char	uchar;
X
Xextern uchar		*EGAaddr;
Xextern int		EGAifd;
Xextern int		EGAofd;
X
Xegainit()
X{
X	char *tty, *ttyname();
X	struct kd_disparam disparam;
X	struct kd_memloc kd_memloc;
X	struct vt_mode vt_mode;
X	long	vt;
X	char	vtname[16];
X
X	EGAaddr = NULL;
X
X	if ( (tty = ttyname(1)) == NULL || strncmp(tty,"/dev/vt",7) != 0 )
X		return( 0 );
X
X	if (ioctl(1, VT_OPENQRY, &vt) == -1)
X		return( 0 );
X
X	sprintf(vtname, "/dev/vt%02d", vt);
X	EGAifd = EGAofd = open(vtname, 2);
X	if (EGAifd < 0)
X		return(0);
X
X	EGAaddr = (uchar *) malloc(2*65536+4096);
X	while ( ((int) EGAaddr) & 4095) ++EGAaddr;
X
X	if (ioctl(EGAofd, KDDISPTYPE, &disparam) == -1) goto burp;
X	
X	if (ioctl(EGAofd, VT_GETMODE, &vt_mode) == -1) goto burp;
X	vt_mode.mode = VT_PROCESS;
X	if (ioctl(EGAofd, VT_SETMODE, &vt_mode) == -1) goto burp;
X
X	if (ioctl(EGAofd, KDSETMODE, KD_GRAPHICS) == -1) goto burp;
X
X	kd_memloc.vaddr = (char *) EGAaddr;
X	kd_memloc.physaddr = disparam.addr;
X	kd_memloc.length = 65536*2;
X	kd_memloc.ioflg = 1;
X	if (ioctl(EGAofd, KDMAPDISP, &kd_memloc) == -1) goto burp;
X
X	ega_setregs(0x10);	/* 640 x 350 color graphics */
X	ega_enable();
X
X	Clear();
X	return( 1 );
X
Xburp:
X	EGAaddr = NULL;
X	return 0;
X}
X
Xegareset()
X{
X	if ( EGAaddr ) {
X		Clear();
X		ioctl(EGAofd, KDUNMAPDISP, NULL);
X	}
X}
END_OF_FILE
if test 1431 -ne `wc -c <'386ix.c'`; then
    echo shar: \"'386ix.c'\" unpacked with wrong size!
fi
# end of '386ix.c'
fi
if test -f '386ix_ega.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'386ix_ega.c'\"
else
echo shar: Extracting \"'386ix_ega.c'\" \(11250 characters\)
sed "s/^X//" >'386ix_ega.c' <<'END_OF_FILE'
X/*
X *	EGA replacement console driver for VENIX SVR2
X *	Hacked for user mode 386/ix use.
X *
X *	Copyright 1987 PC Research, Inc.  All Rights Reserved.
X *
X *	Modified  June 1988 for use from 386/ix user mode
X *
X *	Hacked again Feb 1989 for use with Wanderer
X *
X *	Permission granted to use this routine in the game
X *	"WANDERER" is hereby granted to everbody.
X *
X *	-Rick Richardson, PC Research, Inc.
X */
X#define	ADDR_6845	0x3d4
X
X#define ega	EGAaddr
X
X#include <sys/inline.h>
Xsplx(){}		/* No way from user mode */
Xspl7(){}
Xextern char	*ega;
X
Xtypedef struct
X{
X	char	cols;		/* Text columns */
X	char	rows;		/* Text Rows */
X	char	pels;		/* Pel rows per character */
X	int	pagelen;	/* Length of text page in bytes */
X	char	seq[5];		/* 5 values for sequencer */
X	char	misc;		/* misc output register */
X	char	crt[25];	/* CRT controller */
X	char	atr[20];	/* Attribute controller */
X	char	graph[9];	/* Graphics controller */
X} CRTC;
X
Xstatic	CRTC	ega_parms[19] =
X{
X	{	/* EGA Mode 0: 25 x 40 sixteen color text */
X	/**/		40, 25, 14, 0x0800,
X	/*seq*/	{ 0x01, 0x0b, 0x03, 0, 0x03 },
X	/*misc*/	0xa7,
X	/*crt*/	{	0x2d, 0x27, 0x2b, 0x2d, 0x28, 0x6d,
X			0x6c, 0x1f, 0, 0x0d, 0x06, 0x07,
X			0, 0, 0, 0, 0x5e, 0x2b,
X			0x5d, 0x14, 0x0f, 0x5e, 0x0a, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b,
X			0x3c, 0x3d, 0x3e, 0x3f, 0x08, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0e, 0, 0xff}
X	},
X
X	{	/* EGA Mode 1: 25 x 40 sixteen color text */
X	/**/		40, 25, 14, 0x0800,
X	/*seq*/	{ 0x01, 0x0b, 0x03, 0, 0x03 },
X	/*misc*/	0xa7,
X	/*crt*/	{	0x2d, 0x27, 0x2b, 0x2d, 0x28, 0x6d,
X			0x6c, 0x1f, 0, 0x0d, 0x06, 0x07,
X			0, 0, 0, 0, 0x5e, 0x2b,
X			0x5d, 0x14, 0x0f, 0x5e, 0x0a, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b,
X			0x3c, 0x3d, 0x3e, 0x3f, 0x08, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0e, 0, 0xff}
X	},
X
X	{	/* EGA Mode 2: 25 x 80 sixteen color text */
X	/**/		80, 25, 14, 0x1000,
X	/*seq*/	{ 0x01, 0x01, 0x03, 0, 0x03 },
X	/*misc*/	0xa7,
X	/*crt*/	{	0x5b, 0x4f, 0x53, 0x37, 0x51, 0x5b,
X			0x6c, 0x1f, 0, 0x0d, 0x06, 0x07,
X			0, 0, 0, 0, 0x5e, 0x2b,
X			0x5d, 0x28, 0x0f, 0x5e, 0x0a, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b,
X			0x3c, 0x3d, 0x3e, 0x3f, 0x08, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0e, 0, 0xff}
X	},
X
X	{	/* EGA Mode 3: 25 x 80 sixteen color text */
X	/**/		80, 25, 14, 0x1000,
X	/*seq*/	{ 0x01, 0x01, 0x03, 0, 0x03 },
X	/*misc*/	0xa7,
X	/*crt*/	{	0x5b, 0x4f, 0x53, 0x37, 0x51, 0x5b,
X			0x6c, 0x1f, 0, 0x0d, 0x0b, 0x0c,
X			0, 0, 0, 0, 0x5e, 0x2b,
X			0x5d, 0x28, 0x0f, 0x5e, 0x0a, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b,
X			0x3c, 0x3d, 0x3e, 0x3f, 0x08, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0e, 0, 0xff}
X	},
X
X	{	/* EGA Mode 4: 320x200 four color graphics */
X	/**/		40, 25, 8, 0x4000,
X	/*seq*/	{ 0x01, 0x0b, 0x03, 0, 0x02 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x37, 0x27, 0x2d, 0x37, 0x30, 0x14,
X			0x04, 0x11, 0, 0x01, 0, 0,
X			0, 0, 0, 0, 0xe1, 0x24,
X			0xc7, 0x14, 0, 0xe0, 0xf0, 0xa2,
X			0xff },
X	/*atr*/	{	0, 0x13, 0x15, 0x17, 0x02, 0x04,
X			0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
X			0x14, 0x15, 0x16, 0x17, 0x01, 0,
X			0x03, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x30,
X			0x0f, 0, 0xff}
X	},
X
X	{	/* EGA Mode 5: 320x200 four color graphics */
X	/**/		40, 25, 8, 0x4000,
X	/*seq*/	{ 0x01, 0x0b, 0x03, 0, 0x02 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x37, 0x27, 0x2d, 0x37, 0x30, 0x14,
X			0x04, 0x11, 0, 0x01, 0, 0,
X			0, 0, 0, 0, 0xe1, 0x24,
X			0xc7, 0x14, 0, 0xe0, 0xf0, 0xa2,
X			0xff },
X	/*atr*/	{	0, 0x13, 0x15, 0x17, 0x02, 0x04,
X			0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
X			0x14, 0x15, 0x16, 0x17, 0x01, 0,
X			0x03, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x30,
X			0x0f, 0, 0xff}
X	},
X
X	{	/* EGA Mode 6: 640x200 two color graphics */
X	/**/		80, 25, 8, 0x4000,
X	/*seq*/	{ 0x01, 0x01, 0x01, 0, 0x06 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x70, 0x4f, 0x59, 0x2d, 0x5e, 0x06,
X			0x04, 0x11, 0, 0x01, 0, 0,
X			0, 0, 0, 0, 0xe0, 0x23,
X			0xc7, 0x28, 0, 0xdf, 0xef, 0xc2,
X			0xff },
X	/*atr*/	{	0, 0x17, 0x17, 0x17, 0x17, 0x17,
X			0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
X			0x17, 0x17, 0x17, 0x17, 0x01, 0,
X			0x01, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0,
X			0x0d, 0, 0xff}
X	},
X
X	{	/* EGA Mode 7: 80x25 monochrome text */
X	/**/		80, 25, 14, 0x1000,
X	/*seq*/	{ 0x01, 0, 0x03, 0, 0x03 },
X	/*misc*/	0xa6,
X	/*crt*/	{	0x60, 0x4f, 0x56, 0x3a, 0x51, 0x60,
X			0x70, 0x01, 0, 0x0d, 0x0b, 0x0c,
X			0, 0, 0, 0, 0x5e, 0x2e,
X			0x5d, 0x28, 0x0d, 0x5e, 0x6e, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x08, 0x08, 0x08, 0x08, 0x08,
X			0x08, 0x08, 0x10, 0x18, 0x18, 0x18,
X			0x18, 0x18, 0x18, 0x18, 0x0e, 0,
X			0x0f, 0x08 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0a, 0, 0xff}
X	},
X
X	{	/* EGA Mode 8: reserved */
X	/**/		40, 25, 8, 0x4000,
X	/*seq*/	{ 0x01, 0, 0, 0, 0x03 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x37, 0x27, 0x2d, 0x37, 0x31, 0x15,
X			0x04, 0x11, 0, 0x07, 0x06, 0x07,
X			0, 0, 0, 0, 0xe1, 0x24,
X			0xc7, 0x14, 0x08, 0xe0, 0xf0, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
X			0x14, 0x15, 0x16, 0x17, 0x08, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0e, 0, 0xff}
X	},
X
X	{	/* EGA Mode 9: reserved */
X	/**/		40, 25, 8, 0x4000,
X	/*seq*/	{ 0x01, 0, 0, 0, 0x03 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x37, 0x27, 0x2d, 0x37, 0x31, 0x15,
X			0x04, 0x11, 0, 0x07, 0x06, 0x07,
X			0, 0, 0, 0, 0xe1, 0x24,
X			0xc7, 0x14, 0x08, 0xe0, 0xf0, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
X			0x14, 0x15, 0x16, 0x17, 0x08, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0e, 0, 0xff}
X	},
X
X	{	/* EGA Mode A: reserved */
X	/**/		40, 25, 8, 0x4000,
X	/*seq*/	{ 0x01, 0, 0, 0, 0x03 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x37, 0x27, 0x2d, 0x37, 0x31, 0x15,
X			0x04, 0x11, 0, 0x07, 0x06, 0x07,
X			0, 0, 0, 0, 0xe1, 0x24,
X			0xc7, 0x14, 0x08, 0xe0, 0xf0, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
X			0x14, 0x15, 0x16, 0x17, 0x08, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0e, 0, 0xff}
X	},
X
X	{	/* EGA Mode B: reserved, internal use */
X	/**/		80, 25, 8, 0x1000,
X	/*seq*/	{ 0x01, 0x01, 0x04, 0, 0x07 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x70, 0x4f, 0x5c, 0x2f, 0x5f, 0x07,
X			0x04, 0x11, 0, 0x07, 0x06, 0x07,
X			0, 0, 0, 0, 0xe1, 0x24,
X			0xc7, 0x28, 0x08, 0xe0, 0xf0, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0, 0, 0, 0, 0,
X			0, 0, 0, 0, 0, 0,
X			0, 0, 0, 0, 0, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0,
X			0x04, 0, 0xff}
X	},
X
X	{	/* EGA Mode C: reserved, internal use */
X	/**/		80, 25, 14, 0x1000,
X	/*seq*/	{ 0x01, 0, 0x04, 0, 0x07 },
X	/*misc*/	0xa6,
X	/*crt*/	{	0x60, 0x4f, 0x56, 0x3a, 0x51, 0x60,
X			0x70, 0x01, 0, 0x0d, 0x0b, 0x0c,
X			0, 0, 0, 0, 0x5e, 0x2e,
X			0x5d, 0x28, 0x0d, 0x5e, 0x6e, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0, 0, 0, 0, 0,
X			0, 0, 0, 0, 0, 0,
X			0, 0, 0, 0, 0x0e, 0,
X			0x0f, 0x08 },
X	/*graf*/{	0, 0, 0, 0, 0, 0,
X			0x04, 0, 0xff}
X	},
X
X	{	/* EGA Mode D: 320 x 200 sixteen color graphics */
X	/**/		40, 25, 8, 0x2000,
X	/*seq*/	{ 0x01, 0x0b, 0x0f, 0, 0x06 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x37, 0x27, 0x2d, 0x37, 0x30, 0x14,
X			0x04, 0x11, 0, 0, 0, 0,
X			0, 0, 0, 0, 0xe1, 0x24,
X			0xc7, 0x14, 0, 0xe0, 0xf0, 0xe3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
X			0x14, 0x15, 0x16, 0x17, 0x01, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0,
X			0x05, 0x0f, 0xff}
X	},
X
X	{	/* EGA Mode E: 640 x 200 sixteen color graphics */
X	/**/		80, 25, 8, 0x4000,
X	/*seq*/	{ 0x01, 0x01, 0x0f, 0, 0x06 },
X	/*misc*/	0x23,
X	/*crt*/	{	0x70, 0x4f, 0x59, 0x2d, 0x5e, 0x06,
X			0x04, 0x11, 0, 0, 0, 0,
X			0, 0, 0, 0, 0xe0, 0x23,
X			0xc7, 0x28, 0, 0xdf, 0xef, 0xe3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x06, 0x07, 0x10, 0x11, 0x12, 0x13,
X			0x14, 0x15, 0x16, 0x17, 0x01, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0,
X			0x05, 0x0f, 0xff}
X	},
X
X	{	/* EGA Mode F: 640 x 350 monochrome graphics */
X	/**/		80, 25, 14, 0x8000,
X	/*seq*/	{ 0x01, 0x05, 0x0f, 0, 0x00 },
X	/*misc*/	0xa2,
X	/*crt*/	{	0x60, 0x4f, 0x56, 0x1a, 0x50, 0xe0,
X			0x70, 0x01, 0, 0, 0, 0,
X			0, 0, 0, 0, 0x5e, 0x2e,
X			0x5d, 0x14, 0x0d, 0x5e, 0x6e, 0x8b,
X			0xff },
X	/*atr*/	{	0, 0x08, 0, 0, 0x18, 0x18,
X			0, 0, 0, 0x08, 0, 0,
X			0, 0x18, 0, 0, 0x0b, 0,
X			0x05, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x07, 0x0f, 0xff}
X	},
X
X	{	/* EGA Mode 10: 640 x 350 sixteen color graphics */
X	/**/		80, 25, 14, 0x8000,
X	/*seq*/	{ 0x01, 0x01, 0x0f, 0, 0x06 },
X	/*misc*/	0xa7,
X	/*crt*/	{	0x5b, 0x4f, 0x53, 0x37, 0x52, 0,
X			0x6c, 0x1f, 0, 0, 0, 0,
X			0, 0, 0, 0, 0x5e, 0x2b,
X			0x5d, 0x28, 0x0f, 0x5f, 0x0a, 0xe3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b,
X			0x3c, 0x3d, 0x3e, 0x3f, 0x01, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0,
X			0x05, 0x0f, 0xff}
X	},
X
X	{	/* EGA Mode 11: 43 x 80 sixteen color text */
X	/**/		80, 42, 8, 0x2000,
X	/*seq*/	{ 0x01, 0x01, 0x03, 0x05, 0x03 },	/* used cgen2 */
X	/*misc*/	0xa7,
X	/*crt*/	{	0x5b, 0x4f, 0x53, 0x37, 0x51, 0x5b,
X			0x6c, 0x1f, 0, 0x07, 0x06, 0x07,
X			0, 0, 0, 0, 0x5e, 0x2b,
X			0x58, 0x28, 0x0f, 0x5e, 0x0a, 0xa3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b,
X			0x3c, 0x3d, 0x3e, 0x3f, 0x08, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0x10,
X			0x0e, 0, 0xff}
X	},
X
X	{	/* EGA Mode 12: 640 x 480 sixteen color graphics */
X		/* PEGA Mode 50: 640 x 480 sixteen color graphics */
X	/**/		80, 29, 16, 0xc800,
X	/*seq*/	{ 0x01, 0x01, 0x0f, 0, 0x06 },
X	/*misc*/	0xab,
X	/*crt*/	{	0x66, 0x4f, 0x53, 0x3d, 0x55, 0x1f,
X			0xfa, 0x1f, 0, 0, 0, 0,
X			0, 0, 0, 0, 0xe1, 0x29,
X			0xdf, 0x28, 0x0f, 0xe0, 0x1a, 0xe3,
X			0xff },
X	/*atr*/	{	0, 0x01, 0x02, 0x03, 0x04, 0x05,
X			0x14, 0x07, 0x38, 0x39, 0x3a, 0x3b,
X			0x3c, 0x3d, 0x3e, 0x3f, 0x01, 0,
X			0x0f, 0x00 },
X	/*graf*/{	0, 0, 0, 0, 0, 0,
X			0x05, 0x0f, 0xff}
X	},
X};
X
X/*
X *	ega_setregs(mode):
X *		program EGA chips for "mode"
X */
Xega_setregs(mode)
X{
X	register CRTC	*cp = &ega_parms[mode];
X	register int	j;
X	register int	x;
X
X	x = spl7();				/* Int's off */
X	for (j = 0; j < 5; ++j)			/* Program sequencer */
X	{
X		outb(0x3c4, j);
X		outb(0x3c4 + 1, cp->seq[j]);
X	}
X	outb(0x3c2, cp->misc );		/* Program misc register */
X	outb(0x3c4, 0); outb(0x3c5, 3);	/* Turn off sequencer reset */
X	splx(x);				/* Int's back on (maybe) */
X	for( j = 0; j < 25; j++ )		/* Program CRT controller */
X	{
X		outb(ADDR_6845, j);
X		outb(ADDR_6845+1, cp->crt[j]);
X	}
X
X	inb(ADDR_6845+6 );			/* Reset Atr ctrl state */
X	for( j = 0; j < 20; j++ )		/* Program Atr controller */
X	{
X		outb(0x3c0, j);
X		outb(0x3c0, cp->atr[j]);
X	}
X	outb(0x3c0, 0 );
X
X	outb(0x3cc, 0 );			/* Program Grafix 1 position */
X	outb(0x3ca, 1 );			/* Program Grafix 2 position */
X
X	for( j = 0; j < 9; j++ )		/* Program Grafix controller */
X	{
X		outb(0x3ce, j);
X		outb(0x3ce+1, cp->graph[j]);
X	}
X}
X
Xega_palset(pal, color)
X{
X	register int x;
X	register int	areg = 0x3c0;
X
X	x = spl7();
X	while ((inb(ADDR_6845+6) & 0x08) == 0)
X		;	/* Wait for vert retrace */
X	outb(areg, pal);
X	outb(areg, color);
X	outb(areg, 0x20);
X	splx(x);
X}
X
X/*
X *	Enable the display, must be called after a ega_setregs();
X */
Xega_enable()
X{
X	inb(ADDR_6845+6 ); outb(0x3c0, 0x20 );	/* Enable display */
X}
END_OF_FILE
if test 11250 -ne `wc -c <'386ix_ega.c'`; then
    echo shar: \"'386ix_ega.c'\" unpacked with wrong size!
fi
# end of '386ix_ega.c'
fi
if test -f 'iAPX286.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'iAPX286.c'\"
else
echo shar: Extracting \"'iAPX286.c'\" \(1112 characters\)
sed "s/^X//" >'iAPX286.c' <<'END_OF_FILE'
X/*
X *	EGA init/reset for uPort V/AT
X */
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/ipc.h>
X#include <sys/shm.h>
X
Xtypedef	unsigned char	uchar;
X
Xextern uchar		*EGAaddr;
Xextern int		EGAifd;
Xextern int		EGAofd;
X
X#define VIDKEY		0xa0000
X#define VIDLEN		65535
X#define	VIDFD		1
X
X
X/*
X * If stdout is one of the console devices (/dev/cons*), then we can
X * use the EGA.  Attach to the EGA shared memory segment.
X */
Xegainit()
X{
X	int shmid;
X	uchar *shmat();
X	char *tty, *ttyname();
X
X	if ( (tty = ttyname(VIDFD)) == NULL || strncmp(tty,"/dev/cons",9) != 0 )
X		/*
X		 * stdout is not the console
X		 */
X		return( 0 );
X
X	if ( (shmid = shmget((key_t)VIDKEY,(int)VIDLEN,0)) != -1 ) {
X		/*
X		 * segment exists (hopefully attached to the EGA)
X		 */
X		if ( (int)(EGAaddr = shmat(shmid,NULL,0)) != -1 ) {
X			EGAifd = 0;
X			EGAofd = VIDFD;
X			write( EGAofd, "\033[=16h", 6 );
X			Clear();
X			return( 1 );
X			}
X		}
X
X	EGAaddr = NULL;
X
X	return( 0 );
X}
X
Xegareset()
X{
X	if ( EGAaddr ) {
X		Clear();
X
X		write( EGAofd, "\033[=h", 4 );
X
X		/* Detach from shared memory segment */
X		if (shmdt(EGAaddr) == -1)
X			perror("shmdt");
X		}
X}
END_OF_FILE
if test 1112 -ne `wc -c <'iAPX286.c'`; then
    echo shar: \"'iAPX286.c'\" unpacked with wrong size!
fi
# end of 'iAPX286.c'
fi
if test -f 'venix286.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'venix286.c'\"
else
echo shar: Extracting \"'venix286.c'\" \(741 characters\)
sed "s/^X//" >'venix286.c' <<'END_OF_FILE'
X/*
X *	EGA init/reset for VENIX/286
X */
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/pc_csl.h>
X
Xtypedef	unsigned char	uchar;
X
Xextern uchar		*EGAaddr;
Xextern int		EGAifd;
Xextern int		EGAofd;
X
X#define	VIDFD		1
X
X#define	PHYS_SEL	((uchar *) 0x170000L)
X#define EGA_PHYS	((unsigned) (0xA0000L/512))
X
Xegainit()
X{
X	char *tty, *ttyname();
X
X	if ( (tty = ttyname(VIDFD)) == NULL || strncmp(tty,"/dev/scrn",9) != 0 )
X		return( 0 );
X
X	if (ioctl(VIDFD, PHYS_MEM, EGA_PHYS) != -1) {
X		EGAaddr = PHYS_SEL;
X		EGAifd = 0;
X		EGAofd = VIDFD;
X		write( EGAofd, "\033[16g", 5 );
X		Clear();
X		return( 1 );
X	}
X
X	EGAaddr = NULL;
X
X	return( 0 );
X}
X
Xegareset()
X{
X	if ( EGAaddr ) {
X		Clear();
X		write(EGAofd, "\033[0g", 4 );
X		ioctl(EGAofd, PHYS_MEM, -1);
X	}
X}
END_OF_FILE
if test 741 -ne `wc -c <'venix286.c'`; then
    echo shar: \"'venix286.c'\" unpacked with wrong size!
fi
# end of 'venix286.c'
fi
if test -f 'ega.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ega.c'\"
else
echo shar: Extracting \"'ega.c'\" \(16849 characters\)
sed "s/^X//" >'ega.c' <<'END_OF_FILE'
X#include <curses.h>
X#include "bitmap.h"
X
Xtypedef	unsigned char	uchar;
X
Xuchar			*EGAaddr;
Xint			EGAifd;
Xint			EGAofd;
X
X#define	POINT(x,y)	&EGAaddr[((((y)<<2)+(y))<<4)+((x)>>3)]
X
Xegaclear(x1,y1, x2,y2)
X{
X	uchar *sp, *p;
X	int j, n, width, fetch;
X	unsigned mask, o, old, bits;
X
X	width = x2 - x1 + 1;
X
X	if ( o = (x1 & 0x07) )
X		if ( width + o <= 8 )
X			/*
X			 * within a single byte
X			 */
X			{
X			mask = ~(((0xff00 >> width) & 0xff) >> o);
X
X			for( sp = POINT(x1,y1); y1++ <= y2; sp += 640/8 )
X				*sp &= mask;
X			}
X		else
X			/*
X			 * extends beyond a byte boundry
X			 */
X			for( sp = POINT(x1,y1); y1++ <= y2; sp += 640/8 )
X				{
X				for( old = *(p=sp) & (0xff00 >> o), j = 0; j < (width+8-o)/8; old = 0, ++j, fetch = *p )
X					*p++ = old;
X
X				if ( (bits = ((width + o) % 8)) != 0 )
X					*p &= ~(0xff00 >> bits);
X				}
X	else
X		for( sp = POINT(x1,y1); y1++ <= y2; sp += 640/8 )
X			{
X			if ( (n = width/8) > 0 )
X				for( p = sp; n-- > 0; )
X					*p++ &= 0;
X
X			if ( (o = width%8) != 0 )
X				sp[n] &= (0xff >> o);
X			}
X}
X
X/*
X * Draw a line from (x0,y0) to (x1,y1), where the 4 arguments are
X * in device coordinates and the 4 arguments must each be a short
X * (since the arithmetic is done using shorts, for speed).
X */
X
X#define PLOT(x,y)	{ \
X			uchar *p = POINT(x,y); \
X			*p |= mask[x]; \
X			}
X#define	ABS(x)		((x) < 0 ? (-(x)) : (x))
X#define SWAP(s1, s2)	{ int tmp; tmp = s1; s1 = s2; s2 = tmp; }
X
Xstatic uchar mask[640] ={ /* x-pixels in range [0,639] */
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X		0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01,
X			};
X
Xegaline(x0, y0, x1, y1)
Xshort	x0, y0, x1, y1;		/* all in device coordinates */
X{
X	register short	d, x, y, incr1, incr2, xend;
X	short		dx, dy, rotate;
X
X	/*
X	 * Now starts Bresenham's algorithm.  See Foley and Van Dam,
X	 * pages 433-436 for some of the details.
X	 * The variable names below are the same as in the text.
X	 *
X	 * Optimized to use short integer arithmetic, and further optimized
X	 * by taking some of the logic tests out of the main loop (making
X	 * 4 copies of the main loop, one for each case - space versus
X	 * time tradeoff).
X	 */
X
X	dy = y1 - y0;
X	dx = x1 - x0;
X
X	/*
X	 * The octants are numbered 1 through 8, counterclockwise,
X	 * starting with octant 1 being east-northeast.
X	 * If we are in octants 2, 3, 6, or 7, then rotate the line
X	 * about the line x=y.  This maps octant 2 into 1,
X	 * octant 3 into 8, octant 6 into 5 and octant 7 into 4.
X	 * We must remember this rotation for later, as we will
X	 * re-rotate the points when we plot them.
X	 */
X
X	if (ABS(dx) >= ABS(dy))
X		rotate = 0;
X	else {
X		rotate = 1;
X		SWAP(x0, y0);
X		SWAP(x1, y1);
X		SWAP(dx, dy);
X	}
X
X	if (dx < 0) {
X		/*
X		 * We're in octants 4 or 5.
X		 * Swap the starting and ending points, mapping
X		 * octant 4 to 8, and octant 5 to 1.
X		 * This will generate the points in reverse order
X		 * for octants 3 and 5 (i.e., we'll go from the end
X		 * to the beginning), but who cares?
X		 */
X
X		SWAP(x0, x1);	/* swap start and end points */
X		SWAP(y0, y1);
X		dx = -dx;		/* dx becomes positive */
X		dy = -dy;		/* dy can be positive or negative */
X	}
X
X	/*
X	 * At this point we're guaranteed that dx >= 0, and x0 < x1.
X	 */
X
X	if (dy < 0) {
X		/*
X		 * Octants 3, 4, 7 or 8.
X		 * x will be: x1, x1-1, x1-2, ..., x0.
X		 */
X
X		xend  = x0;
X		y     = y1;
X
X		incr1 = 2 * (-dy);	/* remember that dy < 0 */
X		d     = incr1 - dx;	/* 2*dy - dx */
X		incr2 = d - dx;		/* 2*dy - 2*dx = 2*(dy - dx) */
X
X		if (rotate) {	/* main loop, octants 3 or 7 */
X
X			for (x = x1; x >= xend; x--) {
X				PLOT(y, x);
X
X				if (d > 0) {
X					y++;
X					d += incr2;
X				} else
X					d += incr1;
X			}
X
X		} else {	/* main loop, octants 4 or 8 */
X
X			for (x = x1; x >= xend; x--) {
X				PLOT(x, y);
X
X				if (d > 0) {
X					y++;
X					d += incr2;
X				} else
X					d += incr1;
X			}
X		}
X
X	} else {
X		/*
X		 * Octants 1, 2, 5 or 6.
X		 * x will be: x0, x0+1, x0+2, ..., x1.
X		 */
X
X		xend  = x1;
X		y     = y0;
X
X		incr1 = 2 * dy;
X		d     = incr1 - dx;	/* 2*dy - dx */
X		incr2 = d - dx;		/* 2*dy - 2*dx = 2*(dy - dx) */
X
X		if (rotate) {	/* main loop, octants 2 or 6 */
X
X			for (x = x0; x <= xend; x++) {
X				PLOT(y, x);
X
X				if (d > 0) {
X					y++;
X					d += incr2;
X				} else
X					d += incr1;
X			}
X		} else {	/* main loop, octants 1 or 5 */
X
X			for (x = x0; x <= xend; x++) {
X				PLOT(x, y);
X
X				if (d > 0) {
X					y++;
X					d += incr2;
X				} else
X					d += incr1;
X			}
X		}
X	}
X}
X
Xstruct	{			/* 8 x 8 */
X	uchar	letter[8];
X	}
X	font[ 0x80 - ' ' ] ={
X	/* sp */{ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
X	/* ! */ { 0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00 },
X	/* " */ { 0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00 },
X	/* # */ { 0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00 },
X	/* $ */ { 0x30,0x7C,0xC0,0x78,0x0C,0xF8,0x30,0x00 },
X	/* % */ { 0x00,0xC6,0xCC,0x18,0x30,0x66,0xC6,0x00 },
X	/* & */ { 0x38,0x6C,0x38,0x76,0xDC,0xCC,0x76,0x00 },
X	/* ' */ { 0x60,0x60,0xC0,0x00,0x00,0x00,0x00,0x00 },
X	/* ( */ { 0x18,0x30,0x60,0x60,0x60,0x30,0x18,0x00 },
X	/* ) */ { 0x60,0x30,0x18,0x18,0x18,0x30,0x60,0x00 },
X	/* * */ { 0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00 },
X	/* + */ { 0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00 },
X	/* , */ { 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60 },
X	/* - */ { 0x00,0x00,0x00,0xFC,0x00,0x00,0x00,0x00 },
X	/* . */ { 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00 },
X	/* / */ { 0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00 },
X	/* 0 */ { 0x7C,0xC6,0xCE,0xDE,0xF6,0xE6,0x7C,0x00 },
X	/* 1 */ { 0x30,0x70,0x30,0x30,0x30,0x30,0xFC,0x00 },
X	/* 2 */ { 0x78,0xCC,0x0C,0x38,0x60,0xCC,0xFC,0x00 },
X	/* 3 */ { 0x78,0xCC,0x0C,0x38,0x0C,0xCC,0x78,0x00 },
X	/* 4 */ { 0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x1E,0x00 },
X	/* 5 */ { 0xFC,0xC0,0xF8,0x0C,0x0C,0xCC,0x78,0x00 },
X	/* 6 */ { 0x38,0x60,0xC0,0xF8,0xCC,0xCC,0x78,0x00 },
X	/* 7 */ { 0xFC,0xCC,0x0C,0x18,0x30,0x30,0x30,0x00 },
X	/* 8 */ { 0x78,0xCC,0xCC,0x78,0xCC,0xCC,0x78,0x00 },
X	/* 9 */ { 0x78,0xCC,0xCC,0x7C,0x0C,0x18,0x70,0x00 },
X	/* : */ { 0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00 },
X	/* ; */ { 0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x60 },
X	/* < */ { 0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x00 },
X	/* = */ { 0x00,0x00,0xFC,0x00,0x00,0xFC,0x00,0x00 },
X	/* > */ { 0x60,0x30,0x18,0x0C,0x18,0x30,0x60,0x00 },
X	/* ? */ { 0x78,0xCC,0x0C,0x18,0x30,0x00,0x30,0x00 },
X	/* @ */ { 0x7C,0xC6,0xDE,0xDE,0xDE,0xC0,0x78,0x00 },
X	/* A */ { 0x30,0x78,0xCC,0xCC,0xFC,0xCC,0xCC,0x00 },
X	/* B */ { 0xFC,0x66,0x66,0x7C,0x66,0x66,0xFC,0x00 },
X	/* C */ { 0x3C,0x66,0xC0,0xC0,0xC0,0x66,0x3C,0x00 },
X	/* D */ { 0xF8,0x6C,0x66,0x66,0x66,0x6C,0xF8,0x00 },
X	/* E */ { 0xFE,0x62,0x68,0x78,0x68,0x62,0xFE,0x00 },
X	/* F */ { 0xFE,0x62,0x68,0x78,0x68,0x60,0xF0,0x00 },
X	/* G */ { 0x3C,0x66,0xC0,0xC0,0xCE,0x66,0x3E,0x00 },
X	/* H */ { 0xCC,0xCC,0xCC,0xFC,0xCC,0xCC,0xCC,0x00 },
X	/* I */ { 0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00 },
X	/* J */ { 0x1E,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00 },
X	/* K */ { 0xE6,0x66,0x6C,0x78,0x6C,0x66,0xE6,0x00 },
X	/* L */ { 0xF0,0x60,0x60,0x60,0x62,0x66,0xFE,0x00 },
X	/* M */ { 0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0x00 },
X	/* N */ { 0xC6,0xE6,0xF6,0xDE,0xCE,0xC6,0xC6,0x00 },
X	/* O */ { 0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x38,0x00 },
X	/* P */ { 0xFC,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00 },
X	/* Q */ { 0x78,0xCC,0xCC,0xCC,0xDC,0x78,0x1C,0x00 },
X	/* R */ { 0xFC,0x66,0x66,0x7C,0x6C,0x66,0xE6,0x00 },
X	/* S */ { 0x78,0xCC,0xE0,0x70,0x1C,0xCC,0x78,0x00 },
X	/* T */ { 0xFC,0xB4,0x30,0x30,0x30,0x30,0x78,0x00 },
X	/* U */ { 0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xFC,0x00 },
X	/* V */ { 0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x00 },
X	/* W */ { 0xC6,0xC6,0xC6,0xD6,0xFE,0xEE,0xC6,0x00 },
X	/* X */ { 0xC6,0xC6,0x6C,0x38,0x38,0x6C,0xC6,0x00 },
X	/* Y */ { 0xCC,0xCC,0xCC,0x78,0x30,0x30,0x78,0x00 },
X	/* Z */ { 0xFE,0xC6,0x8C,0x18,0x32,0x66,0xFE,0x00 },
X	/* [ */ { 0x78,0x60,0x60,0x60,0x60,0x60,0x78,0x00 },
X	/* \ */ { 0xC0,0x60,0x30,0x18,0x0C,0x06,0x02,0x00 },
X	/* ] */ { 0x78,0x18,0x18,0x18,0x18,0x18,0x78,0x00 },
X	/* ^ */ { 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00 },
X	/* _ */ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF },
X	/* ` */ { 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00 },
X	/* a */ { 0x00,0x00,0x78,0x0C,0x7C,0xCC,0x76,0x00 },
X	/* b */ { 0xE0,0x60,0x60,0x7C,0x66,0x66,0xDC,0x00 },
X	/* c */ { 0x00,0x00,0x78,0xCC,0xC0,0xCC,0x78,0x00 },
X	/* d */ { 0x1C,0x0C,0x0C,0x7C,0xCC,0xCC,0x76,0x00 },
X	/* e */ { 0x00,0x00,0x78,0xCC,0xFC,0xC0,0x78,0x00 },
X	/* f */ { 0x38,0x6C,0x60,0xF0,0x60,0x60,0xF0,0x00 },
X	/* g */ { 0x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0xF8 },
X	/* h */ { 0xE0,0x60,0x6C,0x76,0x66,0x66,0xE6,0x00 },
X	/* i */ { 0x30,0x00,0x70,0x30,0x30,0x30,0x78,0x00 },
X	/* j */ { 0x0C,0x00,0x0C,0x0C,0x0C,0xCC,0xCC,0x78 },
X	/* k */ { 0xE0,0x60,0x66,0x6C,0x78,0x6C,0xE6,0x00 },
X	/* l */ { 0x70,0x30,0x30,0x30,0x30,0x30,0x78,0x00 },
X	/* m */ { 0x00,0x00,0xCC,0xFE,0xFE,0xD6,0xC6,0x00 },
X	/* n */ { 0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xCC,0x00 },
X	/* o */ { 0x00,0x00,0x78,0xCC,0xCC,0xCC,0x78,0x00 },
X	/* p */ { 0x00,0x00,0xDC,0x66,0x66,0x7C,0x60,0xF0 },
X	/* q */ { 0x00,0x00,0x76,0xCC,0xCC,0x7C,0x0C,0x1E },
X	/* r */ { 0x00,0x00,0xDC,0x76,0x66,0x60,0xF0,0x00 },
X	/* s */ { 0x00,0x00,0x7C,0xC0,0x78,0x0C,0xF8,0x00 },
X	/* t */ { 0x10,0x30,0x7C,0x30,0x30,0x34,0x18,0x00 },
X	/* u */ { 0x00,0x00,0xCC,0xCC,0xCC,0xCC,0x76,0x00 },
X	/* v */ { 0x00,0x00,0xCC,0xCC,0xCC,0x78,0x30,0x00 },
X	/* w */ { 0x00,0x00,0xC6,0xD6,0xFE,0xFE,0x6C,0x00 },
X	/* x */ { 0x00,0x00,0xC6,0x6C,0x38,0x6C,0xC6,0x00 },
X	/* y */ { 0x00,0x00,0xCC,0xCC,0xCC,0x7C,0x0C,0xF8 },
X	/* z */ { 0x00,0x00,0xFC,0x98,0x30,0x64,0xFC,0x00 },
X	/* { */ { 0x1C,0x30,0x30,0xE0,0x30,0x30,0x1C,0x00 },
X	/* | */ { 0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x00 },
X	/* } */ { 0xE0,0x30,0x30,0x1C,0x30,0x30,0xE0,0x00 },
X	/* ~ */ { 0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00 },
X	/*del*/ { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
X			    };
X
X/*
X * Handle writing text messages to the display.
X *
X * Things are more complicated than they should be, since we must
X * plot the actual bit maps of each character.
X */
Xegaprintf( x, y, fmt )
Xchar *fmt;
X{
X	char buffer[128];
X
X	vsprintf( buffer, fmt, &fmt+1 );
X	egaputs( x, y, buffer );
X}
X
X
Xegaputs(x,y,str)
Xchar	*str;
X{
X	unsigned	c;
X
X	for ( ; c = *str++; x += 8 )
X		egaputc(x,y,c);
X}
X
X
Xegaputc(x,y,c)
Xunsigned c;
X{
X	unsigned	mod, line, fetch;
X	uchar		*fp, *Sp;
X
X	Sp = POINT( x, y );
X
X	fp = font[(c & 0x7f) - ' '].letter;
X
X	/*
X	 * Now comes the fun.  We must take the actual bit map of
X	 * the character and turn on the appropriate bits in the screen.
X	 */
X	if ( mod = x & 0x07 ) {
X		for( line = 0; line < 8*80; line += 80 ) {
X			Sp[line] = (Sp[line] & (0xff00 >> mod)) | ((c = *fp++) >> mod);
X			Sp[line+1] = (c << (8 - mod)) | (Sp[line+1] & (0xff >> mod));
X		}
X	}
X	else {
X		for( line = 0; line < 8*80; line += 80 ) {
X			fetch = Sp[line];
X			Sp[line] = *fp++;
X		}
X	}
X}
X
X
X/*
X * graphic version of gets
X */
X
XBM(8,8) cursor ={ 8, 8, 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00 };
X
Xegagets( x, y, buffer )
Xchar *buffer;
X{
X	unsigned 	c;
X	int		nx = x;
X
X	while( egapaint(nx,y,&cursor), (c = Getch()) != '\n' && c != '\r' )
X		switch( c ) {
X		default:
X			if ( c >= ' ' && c < 127 ) {
X				egaputc( nx, y, *buffer++ = c );
X				nx += 8;
X				}
X			else
X				Beep();
X			break;
X		case '\b':
X			if ( nx > x ) {
X				egaputc( nx, y, ' ' );
X				--buffer;
X				nx -= 8;
X				}
X			break;
X			}
X
X	egaputc( nx, y, ' ' );
X	*buffer = 0;
X}
X
X
X/*
X * Copy a bitmap to the screen
X */
Xegapaint( x, y, map )
Xbitmap *map;
X{
X	uchar *sp, *p, *q, fetch;
X	int i, j, n, width;
X	unsigned mask, o, old, bits;
X
X	width = (map->width + 7) / 8;
X
X	if ( o = (x & 0x07) )
X		if ( map->width + o < 8 )
X			/*
X			 * within a single byte
X			 */
X			{
X			mask = ((0xff00 >> map->width) & 0xff) >> o;
X
X			for( i = 0, sp = POINT(x,y); i < map->height; ++i, sp += 640/8 )
X				*sp = (*sp & ~mask) | ((map->bits[i*width] >> o) & mask);
X			}
X		else
X			/*
X			 * extends upto or beyond a byte boundry
X			 */
X			for( i = 0, sp = POINT(x,y); i < map->height; ++i, sp += 640/8 )
X				{
X				for( old = *(p=sp) & (0xff00 >> o), j = 0; j < (map->width+8-o)/8; ++j, fetch = *p )
X					{
X					*p++ = old | ((bits=map->bits[i*width+j]) >> o);
X					old = bits << (8 - o);
X					}
X
X				if ( (bits = ((map->width + o) % 8)) != 0 )
X					{
X					mask = 0xff00 >> bits;
X
X					*p = (old & mask) | (*p & ~mask);
X					}
X				}
X	else
X		for( i = 0, sp = POINT(x,y); i < map->height; ++i, sp += 640/8 )
X			{
X			if ( (n = map->width/8) > 0 )
X				for( p = sp, q = &map->bits[i*width]; n-- > 0; )
X					{
X					fetch = *p;
X					*p++ = *q++;
X					}
X
X			if ( (o = map->width%8) != 0 )
X				{
X				p = sp + n;
X
X				*p = (*p & (0xff >> o)) | (map->bits[i*width+n] & ~(0xff >> o));
X				}
X			}
X}
X
X
X/*
X * Getch()
X */
XGetch()
X{
Xchar	c = 0;
X
Xif(EGAaddr) {
X    while( c == 0 )
X	    read(EGAifd, &c, 1);
X
X    if(c == '\r')
X	c = '\n';
X
X    return( c );
X    }
Xelse
X    return( wgetch(stdscr) );
X}
X
X/*
X * Clear()
X */
XClear()
X{
Xif(EGAaddr)
X    egaclear(0,0, 639,349);
Xelse
X    wclear(stdscr);
X}
X
X/*
X * Move(y,x)
X */
XMove(y,x)
X{
Xif(!EGAaddr)
X    wmove(stdscr, y, x);
X}
X
X/*
X * Refresh()
X */
XRefresh()
X{
Xif(!EGAaddr)
X    wrefresh(stdscr);
X}
X
X/*
X * Beep()
X */
X
X#undef	beep
X
XBeep()
X{
Xif(EGAaddr)
X    write(EGAofd,"\007",1);
Xelse
X    beep();
X}
END_OF_FILE
if test 16849 -ne `wc -c <'ega.c'`; then
    echo shar: \"'ega.c'\" unpacked with wrong size!
fi
# end of 'ega.c'
fi
if test -f 'bitmap.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bitmap.h'\"
else
echo shar: Extracting \"'bitmap.h'\" \(532 characters\)
sed "s/^X//" >'bitmap.h' <<'END_OF_FILE'
X#define	BM(h,w)	struct { short y,x; char b[h*((w+7)/8)]; }
X
Xtypedef	struct	{
X		short		height, width;
X		unsigned char	bits[1];
X		}		bitmap;
X
X#define	BACKSLIDE	0
X#define	BALLOON		1
X#define	BRICK		2
X#define	CAGE		3
X#define	DIAMOND		4
X#define	DIRT		5
X#define	FWDSLIDE	6
X#define	LANDMINE	7
X#define	LARROW		8
X#define	MONSTER		9
X#define	PLAYER		10
X#define	RARROW		11
X#define	ROCK		12
X#define	SPACE		13
X#define	SPRITE		14
X#define	TELEPORT	15
X#define	TIMECAPSULE	16
X#define	WALL		17
X#define	WAYOUT		18
X#define	WHOOPS		19
X#define	ARRIVAL		20
END_OF_FILE
if test 532 -ne `wc -c <'bitmap.h'`; then
    echo shar: \"'bitmap.h'\" unpacked with wrong size!
fi
# end of 'bitmap.h'
fi
if test -f 'm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'m.c'\"
else
echo shar: Extracting \"'m.c'\" \(4559 characters\)
sed "s/^X//" >'m.c' <<'END_OF_FILE'
X#include "wand_head.h"
X#include <sys/types.h>
X#include <sys/stat.h>
X#ifdef	EGA
X#include "bitmap.h"
X
Xstruct termio sav;
Xextern int EGAifd;	/* Usually 0, but could be a vt under 386/ix */
X#endif
X
Xint debug_disp = 0;
Xint no_passwords = 0;
Xint maxscreens;
Xint edit_mode = 0;
Xint saved_game = 0;
Xchar *edit_screen;
Xchar *screenpath;
X/* Screen[NOOFROWS][ROWLEN] is centered inside area[NOOFROWS+2][ROWLEN+2].
X * This prevents fall() from accessing some random characters outside of
X * screen[][] that happen to match a boulder, etc.
X */
Xchar area[1+NOOFROWS+1][1+ROWLEN+1];
Xchar (*screen)[ROWLEN+1+1] = &area[1][1];
X
Xmain(argc,argv)
Xint  argc;
Xchar *argv[];
X{
Xstruct stat statbuf;
Xint num,bell = 0,maxmoves = 0,x,y;
Xlong score = 0;
Xchar howdead[25],buffer[100], *name,*keys,*dead;
Xchar *malloc();
Xchar *getenv();
X#ifdef	EGA
Xextern char *EGAaddr;
Xextern bitmap wanderer;
X#endif
X
Xif((screenpath = getenv("SCREENPATH")) == NULL)
X    screenpath = SCREENPATH;
X
Xif(argc == 2)
X    {
X    if(!strcmp(argv[1], "-e"))
X	{
X	edit_mode = 1;
X	edit_screen = NULL;
X	}
X    else if(!strcmp(argv[1], "-m"))
X	{
X	erase_scores();
X	return 0;
X	}
X    else if(!strcmp(argv[1], "-c"))
X	{
X	char ch;
X	int fp;
X	/* show credits */
X	sprintf(buffer,"%s/credits",screenpath);
X	if((fp = open(buffer,O_RDONLY)) == -1) {
X            printf(" Sorry - credits unavailable!\n");
X	    exit(1);
X	    }
X	while(read(fp,&ch,1) == 1)
X	    putchar(ch);
X	putchar('\n');
X	exit(0);
X        }
X    else if(!strcmp(argv[1], "-s"))
X	{
X        savescore("",0L,0,NULL);
X        return 0;
X	}
X    else if(!strcmp(argv[1], "-f"))
X        {
X	debug_disp = 1;
X	}
X    else
X	{
X	fprintf(stderr,"Usage: %s [ -e [file] | -m | -c | -s | -f ]\n",argv[0]);
X	exit(1);
X        }
X    }
Xif(argc > 2)
X    {
X    if(!strcmp(argv[1],"-e"))
X	{
X	edit_mode = 1;
X	edit_screen = argv[2];
X	}
X    else
X	{
X	fprintf(stderr,"Usage: %s [ -e [file] | -m | -c | -s | -f ]\n",argv[0]);
X        exit(1);
X	}
X    }
X
X/* use passwords?  if file "no_pws" exists and is readable, then no pws! */
Xsprintf(buffer,"%s/no_pws",screenpath);
Xif(access(buffer,4) == 0)
X    no_passwords = 1;
X
X/* count available screens */
Xfor(maxscreens = 0;;maxscreens++) {
X    sprintf(buffer,"%s/screen.%d",screenpath,(maxscreens+1));
X    if(stat(buffer,&statbuf) == -1)
X	break;
X}
X
Xif((name = getenv("NEWNAME")) == NULL)
X    if((name = getenv("NAME")) == NULL)
X        if((name = getenv("FULLNAME")) == NULL)
X            if((name = getenv("USER")) == NULL)
X		if((name = getenv("LOGNAME")) == NULL)
X#ifdef	ASKNAME	/* M001 */
X		{
X		    name = malloc(80);
X		    if (name == NULL) {
X			printf("malloc error\n");
X			exit(1);
X		    }
X		    printf("Name? "); fflush(stdout);
X		    gets(name);
X		    if (name[0] == '\0')
X			    name = "noname";
X		}
X#else
X	            name = "noname";
X#endif
X
Xif((keys = getenv("NEWKEYS")) == NULL)
X    keys = "kjhl";
X
X#ifdef	EGA
Xif(egainit()) {
X	struct termio cb;
X
X	/* 
X	 * set stdin to raw mode
X	 */
X	ioctl(EGAifd, TCGETA, &sav);
X	cb = sav;
X	cb.c_cc[VMIN] = 1;
X	cb.c_cc[VTIME] = 255;
X	cb.c_lflag &= ~(ECHO | ICANON);
X	ioctl(EGAifd, TCSETAW, &cb);
X
X	egapaint( 233,95, &wanderer );
X	sleep( 3 );
X	}
X    else
X#endif
X	{
X	initscr();
X	keypad(stdscr, TRUE);
X	CBON;
X	noecho();
X	}
X
X/* MAIN PROGRAM HERE */
X
Xplay_again:
X
Xif(!edit_mode) {
X    howdead[0] = 0;
X    for (num=1; num <= maxscreens; ++num) {
X        if (rscreen(num,&maxmoves)) {
X	    strcpy(howdead,"a non-existant screen");
X	    break;
X	    }
X        dead = playscreen(&num,&score,&bell,maxmoves,keys);
X        if ((dead != NULL) && (*dead == '~')) {
X	    num = (int)(dead[1]) - 1;
X	    dead = NULL;
X	    }
X        if (dead != NULL)
X	    {
X	    strcpy(howdead,dead);
X            break;
X            }
X        }
X    }
Xelse
X    {
X    if(rscreen(num,&maxmoves))
X	{
X	for(x=0;x<ROWLEN;x++)
X	    for(y=0;y<NOOFROWS;y++)
X		screen[y][x] =  ' ';
X	}
X    edit(num,&score,&bell,maxmoves,keys);
X    }
X/* END OF MAIN PROGRAM */
X
X#ifdef	EGA
Xif(!EGAaddr)
X#endif
X    {
X    echo();
X    CBOFF;
X    endwin();
X    }
X
Xif(!edit_mode) {
X    /* SAVE ROUTINES FOR SCORES */
X
X#ifdef NO_RESTORED_GAME_HISCORES
X    if(saved_game) {
X#ifdef	EGA
X	if(!EGAaddr)
X#endif
X	    printf("No scores recorded for restored games.\n");
X    }
X    else
X#endif
X	savescore(howdead,score,num,name);
X
X#ifdef	EGA
X    if(EGAaddr) {
X	egaputs(4,341,"Play again? ");
X	egagets(4+12*8,341,buffer);
X	if(buffer[0] == 'y' || buffer[0] == 'Y') {
X	    score = 0;
X	    saved_game = 0;
X	    goto play_again;
X	    }
X	}
X#endif
X    }
X
X#ifdef	EGA
Xif(EGAaddr) {
X    egareset();
X    ioctl(EGAifd, TCSETAW, &sav);
X    }
X#endif
X
Xprintf("WANDERER (C) 1988 S. Shipway\n");
Xreturn 0;
X}
END_OF_FILE
if test 4559 -ne `wc -c <'m.c'`; then
    echo shar: \"'m.c'\" unpacked with wrong size!
fi
# end of 'm.c'
fi
if test -f 'save.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'save.c'\"
else
echo shar: Extracting \"'save.c'\" \(6500 characters\)
sed "s/^X//" >'save.c' <<'END_OF_FILE'
X#include "wand_head.h"
X
X#ifdef	EGA
Xextern	char	*EGAaddr;
Xextern	int	EGAifd;
X#endif
X
Xextern char area[1+NOOFROWS+1][1+ROWLEN+1];
Xextern int saved_game;
Xextern int debug_disp;
X
X#ifndef NO_ENCRYPTION
X
X/* this is the random number seed */
X#define BLURFL 32451    /* the word blurfl is used for historical reasons */
X                        /* but it can be any number */
X
Xstatic int fread(buffer,length,items,stream)
Xchar *buffer;
XFILE *stream;
X{
Xint loop, c, count;
X
Xfor(loop=0; loop<items; loop++)
X	for(count = 0; count<length; ++count ) {
X		if ( (c = getc(stream)) == EOF || ferror(stream) )
X			return( loop );
X		*buffer++ = c ^ rand();
X		}
X
Xreturn( items );
X}
X
Xstatic int fwrite(buffer,length,items,stream)
Xchar *buffer;
XFILE *stream;
X{
Xint loop, count;
X
Xfor(loop=0; loop<items; loop++)
X	for(count = 0; count<length; ++count ) {
X		if ( putc(*buffer++ ^ rand(), stream) == EOF )
X			return( loop );
X		}
X
Xreturn( items );
X}
X#endif
X
Xstruct	saved_game	{
X	short	num;
X	long	score;
X	short	bell;
X	short	maxmoves;
X	short	num_monsters;
X};
X
Xstruct	save_vars	zz;
X
Xvoid
Xsave_game(num, score, bell, maxmoves, start_of_list, tail_of_list)
Xint	num, *bell, maxmoves;
Xlong    *score;
Xstruct	mon_rec	*start_of_list, *tail_of_list;
X{
X	char	fname[128], *fp;
X	FILE	*fo;
X	struct	saved_game	s;
X	extern	char	*getenv();
X	struct	mon_rec	*mp;
X
X#ifndef NO_ENCRYPTION
X	srand(BLURFL);
X#endif
X
X	fp = getenv("SAVENAME");
X#ifdef	EGA
X	if(EGAaddr) {
X		egaclear(0,350-4*9, 639,349);
X		egaputs(4,350-3*9,"Saving game... Filename ? ");
X
X		if (fp == NULL) {
X			fp = fname;
X			egagets(4+26*8,350-3*9,fp);
X		}
X		else
X			egaputs(4+26*8,350-3*9,fp);
X	}
X	else
X#endif
X		{
X		move(LINES-3,0);
X		clrtobot();
X		addstr("Saving game... Filename ? ");
X
X		if (fp == NULL) {
X			refresh();
X			fp = fname;
X			echo(); CBOFF;
X			getstr(fp);
X			noecho(); CBON;
X		}
X		else {
X			addstr(fp);
X			addch('\n');
X			refresh();
X		}
X	}
X	if (NULL == (fo = fopen(fp, W_BIN))) {
X		saveError("Error opening '%s'", fp);
X		return;
X	}
X
X	s.num = num;
X	s.score = *score;
X	s.bell = *bell;
X	s.maxmoves = maxmoves;
X	s.num_monsters = 0;
X
X	mp = start_of_list;		/* first entry is dummy	*/
X	while (mp != tail_of_list) {
X		mp = mp->next;
X		s.num_monsters++;	/* count them monsters	*/
X	}
X
X	if ( (1 != fwrite("WANDERER", 8, 1, fo)) ||
X	     (1 != fwrite(&s, sizeof(s), 1, fo)) ||
X	     (1 != fwrite(&zz, sizeof(zz), 1, fo)) )
X	{
X		saveError("Error writing '%s'", fp);
X		fclose(fo);
X		unlink(fp);
X		return;
X	}
X
X	mp = start_of_list;
X	while (mp != tail_of_list) {
X		/* save them monsters	*/
X		mp = mp->next;
X		if (1 != fwrite(mp, sizeof(*mp), 1, fo)) {
X			saveError("Error writing '%s'", fp);
X			fclose(fo);
X			unlink(fp);
X			return;
X		}
X	}
X
X	if ( 1 != fwrite(area, sizeof(area), 1, fo) )
X	{
X		saveError("Error writing '%s'", fp);
X		fclose(fo);
X		unlink(fp);
X		return;
X	}
X
X	fclose(fo);
X#ifdef	EGA
X	if(EGAaddr) {
X		extern struct termio sav;
X		egareset();
X		ioctl(EGAifd, TCSETAW, &sav);
X		}
X	else
X#endif
X		{
X		refresh();
X		endwin();
X	}
X	exit(0);
X}
X
XsaveError( msg, arg )
Xchar *msg, *arg;
X{
X#ifdef	EGA
X	if(EGAaddr)
X		egaprintf(4,350-2*9,msg,arg);
X	else
X#endif
X		{
X		mvprintw(LINES-2,0,msg,arg);
X		refresh();
X	}
X}
X
X
Xint
Xrestore_game(num, score, bell, maxmoves, start_of_list, tail_of_list)
Xint	*num, *bell, *maxmoves;
Xlong    *score;
Xstruct	mon_rec	*start_of_list, **tail_of_list;
X{
X	FILE	*fi;
X	struct	saved_game	s;
X	struct	mon_rec	*mp, *tmp, *rp;
X	char	fname[128], *fp;
X	char	name[10];
X	extern	char	*getenv();
X	extern	char	*malloc();
X
X#ifndef NO_ENCRYPTION
X	srand(BLURFL);
X#endif
X
X	fp = getenv("SAVENAME");
X#ifdef	EGA
X	if(EGAaddr) {
X		egaclear(0,350-4*9, 639,349);
X		egaputs(4,350-3*9,"Restore Filename ? ");
X
X		if (fp == NULL) {
X			fp = fname;
X			egagets(4+19*8,350-3*9,fp);
X		}
X		else
X			egaputs(4+19*8,350-3*9,fp);
X	}
X	else
X#endif
X		{
X		move(LINES-3,0);
X		clrtobot();
X		addstr("Restore Filename ? ");
X
X		if (NULL == (fp = getenv("SAVENAME"))) {
X			refresh();
X			CBOFF; echo();
X			fp = fname;
X			getstr(fp);
X			noecho(); CBON;
X		}
X		else {
X			addstr(fp);
X			addch('\n');
X			refresh();
X		}
X	}
X	if (NULL == (fi = fopen(fp, R_BIN))) {
X		restoreError("Error opening '%s'; cannot restore game", fp);
X		return 0;
X	}
X
X	if ( 1 != fread(name, 8, 1, fi) ) {
X		restoreError("Error reading '%s'; cannot restore game", fp);
X		fclose(fi);
X		return 0;
X	}
X
X	if ( 0 != strncmp(name,"WANDERER",8) ) {
X		restoreError("File '%s' is not a WANDERER save file; cannot restore game", fp);
X		fclose(fi);
X		return 0;
X	}
X
X	if ( (1 != fread((char *)&s, sizeof(s), 1, fi)) ||
X	     (1 != fread((char *)&zz, sizeof(zz), 1, fi)) ) {
X		restoreError("Error reading '%s'; cannot restore game", fp);
X		fclose(fi);
X		return 0;
X	}
X
X	/* read monsters into core */
X	if (NULL == (rp = (struct mon_rec*)malloc(s.num_monsters*sizeof(*rp)))) {
X		restoreError("Monster alloc error on '%s'; cannot restore game", fp);
X		fclose(fi);
X		return 0;
X	}
X	if ((s.num_monsters != fread(rp,sizeof(struct mon_rec),s.num_monsters,fi)) ||
X	     (1 != fread(area, sizeof(area), 1, fi)) ) {
X		restoreError("Error reading '%s'; cannot restore game", fp);
X		free(rp);
X		fclose(fi);
X		return 0;
X	}
X
X	/* point of no return */
X	*num = s.num;
X	*score = s.score;
X	*bell = s.bell;
X	*maxmoves = s.maxmoves;
X
X	/* free any monsters already on chain, to start clean */
X	mp = start_of_list->next;
X	while ((mp != NULL) && (mp != start_of_list)) {
X		/* free them monsters	*/
X		tmp = mp;
X		mp = mp->next;
X		free(tmp);
X	}
X
X	/* re-initialize the monster list	*/
X	/* *start_of_list = {0,0,0,0,0,NULL,NULL}; */
X	memset( start_of_list, 0, sizeof(*start_of_list) );
X
X	*tail_of_list = start_of_list;
X
X	for( tmp = rp; s.num_monsters--; ++tmp ) {
X		/* use make_monster to allocate the monster structures	*/
X		/* to get all the linking right without even trying	*/
X		if (NULL == (mp = make_monster(0, 0))) {
X#ifdef	EGA
X			if(EGAaddr) {
X				extern struct termio sav;
X				egareset();
X				ioctl(EGAifd, TCSETAW, &sav);
X				printf("Monster alloc error on '%s'; cannot restore game\n", fp);
X			}
X			else
X#endif
X				{
X				mvprintw(LINES-2,0,"Monster alloc error on '%s'; cannot restore game", fp);
X				refresh();
X				endwin();
X			}
X			fclose(fi);
X			exit(1);	/* no recovery possible */
X		}
X		/* copy info without trashing links	*/
X		mp->x     = tmp->x;
X		mp->y     = tmp->y;
X		mp->mx    = tmp->mx;
X		mp->my    = tmp->my;
X		mp->under = tmp->under;
X	}
X
X	fclose(fi);
X	unlink(fp);
X	free(rp);
X	saved_game = 1;
X	return 1;
X}
X
XrestoreError( msg, arg )
Xchar *msg, *arg;
X{
X#ifdef	EGA
X	if(EGAaddr)
X		egaprintf(4,350-2*9,msg,arg);
X	else
X#endif
X		{
X		mvprintw(LINES-2,0,msg,arg);
X		refresh();
X	}
X}
END_OF_FILE
if test 6500 -ne `wc -c <'save.c'`; then
    echo shar: \"'save.c'\" unpacked with wrong size!
fi
# end of 'save.c'
fi
if test -f 'scores.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'scores.c'\"
else
echo shar: Extracting \"'scores.c'\" \(7579 characters\)
sed "s/^X//" >'scores.c' <<'END_OF_FILE'
X#include "wand_head.h"
X
X#ifdef	EGA
Xextern char *EGAaddr;
X#endif
X
X#ifdef	MSDOS	/* M001	*/
X#define	LOCK
X#define	UNLOCK
X#else
X/* MFC- lockfiles fixed: tries 5 times to get lock, with 1 second between
X * tries,  if after 5 seconds, no lock is gained, the lockfile is blown 
X * away.
X */
X#define LOCK { int lc=5; \
X	       while((lock = creat(LOCKPATH,0))<0 && lc) {  \
X		  sleep(1); lc--; }  \
X	       close(lock); \
X	     } 
X#define UNLOCK (void) unlink(LOCKPATH)
X#endif
X
X#define ENTRIES 15
X
X#ifndef	MSDOS	/* M001 */
Xextern int getuid();
X#else
X#define	 getuid()	0
X#endif
X
Xtypedef struct
X    {
X    char howdead[25];
X    char name[20];
X    long score;
X    int  level;
X    int  uid;
X    } score_entry;
X
X#ifdef	LINT_ARGS	/* M001	*/
Xvoid show_scores(score_entry *,int );
Xint readtable(score_entry *);
X#else
Xvoid show_scores();
Xint readtable();
X#endif
X
Xvoid show_scores(table,num)
Xscore_entry *table;
Xint         num;
X{
Xint tot = num;
Xprintf("\n\
XNo. Score Level           Names                 How they died\n\
X===============================================================================\n"); /*
Xxx xxxxxx xxxx     xxxxxxxxxxxxxxxxxxxx     killed by xxxxxxxxxxxxxxxxxxxxxxxxx */
Xwhile(num > 0)
X    {
X    num--;
X    printf("%2d %6ld %4d     %-20s     ",(tot - num),table->score,table->level,table->name);
X    if(*table->howdead)
X	printf("killed by %s\n",table->howdead);
X    else
X	printf("a total winner!\n");
X    table++;
X    }
Xprintf("\n\n");
X}
X
X#ifdef	EGA
X
X#define	vertical(x,y1,y2)	egaline(x,y1, x,y2)
X#define	horizontal(y,x1,x2)	egaline(x1,y, x2,y)
X
Xvoid egabox( x1,y1, x2,y2 )
X{
X	horizontal( y1, x1,x2 );
X	vertical( x2, y1,y2 );
X	horizontal( y2, x1,x2 );
X	vertical( x1, y1,y2 );
X}
X
X#define	X_MIN	0
X#define	X_NO	X_MIN+4+4
X#define	X_SCORE	X_NO+3*8+4+4
X#define	X_LEVEL	X_SCORE+6*8+4+4
X#define	X_NAMES	X_LEVEL+5*8+4+4
X#define	X_HOW	X_NAMES+20*8+4+4
X#define	X_MAX	639
X
X#define	Y_MIN	50
X#define	Y_TITLE	Y_MIN+4+4
X#define	Y_LINE1	Y_TITLE+1*8+4+1+4
X#define	Y_MAX	Y_LINE1+ENTRIES*10+4+4
X
Xvoid ega_show_scores(header,table,tot)
Xchar *header;
Xscore_entry *table;
Xint         tot;
X{
Xint num;
X
Xclear();
X
Xegaputs( (640 - 8*strlen(header)) / 2, (50 - 8) / 2, header );
X									      /*
XNo.  Score Level           Names                 How they died
Xxx  xxxxxx xxxx     xxxxxxxxxxxxxxxxxxxx     killed by xxxxxxxxxxxxxxxxxxxxxxxxx
X									      */
Xegabox( X_MIN,   Y_MIN,   X_MAX,   Y_MAX );
Xegabox( X_MIN+4, Y_MIN+4, X_MAX-4, Y_MAX-4 );
X
Xegaprintf(X_NO+2, Y_TITLE, "No." );
Xegaprintf(X_SCORE+(6*8-5*8)/2, Y_TITLE, "Score" );
Xegaprintf(X_LEVEL+1, Y_TITLE, "Level" );
Xegaprintf(X_NAMES, Y_TITLE, "     Names                 How they died" );
X
Xhorizontal(Y_LINE1-4, X_MIN+4, X_MAX-4);
X
Xvertical(X_SCORE-4, Y_MIN+4, Y_MAX-4);
Xvertical(X_LEVEL-4, Y_MIN+4, Y_MAX-4);
Xvertical(X_NAMES-4, Y_MIN+4, Y_MAX-4);
Xvertical(X_HOW-4, Y_MIN+4, Y_MAX-4);
X
Xfor( num = 1; num <= tot; ++num, ++table ) {
X    egaprintf(X_NO+(3*8-2*8)/2, Y_LINE1+10*(num-1), "%2d",num);
X    egaprintf(X_SCORE, Y_LINE1+10*(num-1), "%6ld", table->score);
X    egaprintf(X_LEVEL+(5*8-4*8)/2, Y_LINE1+10*(num-1), "%4d", table->level);
X    egaprintf(X_NAMES, Y_LINE1+10*(num-1), "%-20s", table->name);
X    if(*table->howdead)
X	egaprintf(X_HOW, Y_LINE1+10*(num-1), "killed by %s", table->howdead);
X    else
X	egaprintf(X_HOW, Y_LINE1+10*(num-1), "a total winner!");
X    }
X}
X#endif
X
Xint readtable(table_ptr)
Xscore_entry *table_ptr;
X{
XFILE *fp;
Xint  numread;
Xif((fp = fopen(HISCOREPATH,R_BIN)) == NULL)
X    {
X    numread = 0;
X    }
Xelse
X    {
X    numread = fread( VOIDSTAR table_ptr, sizeof(score_entry), ENTRIES, fp);
X    fclose(fp);
X    }
Xreturn numread;
X}
X
Xsavescore(howdead,score,level,name)
Xchar *howdead, *name;
Xlong score;
Xint  level;
X{
Xscore_entry table[ENTRIES + 2],
X	    *table_ptr = table,new_entry;
Xint  numread,index = 1, numsaved, lock, already = 0, user_id;
Xchar buffer[80];
XFILE *fp;
X
XLOCK;
Xnumread = readtable(table);
Xif(name == NULL)
X    {
X    show_scores(table,numread);
X    UNLOCK;
X    return;
X    }
X
Xuser_id = getuid();
Xstrncpy(new_entry.howdead,howdead,25);
Xnew_entry.howdead[24] = '\0';	/* M002 strncpy does not null terminate */
Xstrncpy(new_entry.name,name,20);
Xnew_entry.name[19] = '\0';	/* M002 strncpy does not null terminate */
Xnew_entry.score = score;
Xnew_entry.level = level;
Xnew_entry.uid = user_id;
X
Xif (numread > 0)
X    {
X    /* insert new_entry at correct point */
X    for( table_ptr = &table[numread-1]; table_ptr >= table; --table_ptr ) {
X	if(table_ptr->score > score ||
X		(table_ptr->score == score && table_ptr->level >= level)) {
X	    table_ptr[1] = new_entry;
X	    break;
X	}
X	table_ptr[1] = table_ptr[0];
X    }
X    if ( ! (table_ptr >= table) )
X	table[0] = new_entry;
X
X    /* see if name now appears twice */
X    for( already = index = 0, table_ptr = &table[numread]; table_ptr >= table; --table_ptr ) {
X#ifdef	COMPARE_BY_NAME
X#define	SAMEUSER(p)	(strcmp((p)->name, name) == 0)
X#else
X#define	SAMEUSER(p)	((p)->uid == user_id)
X#endif
X	if(SAMEUSER(table_ptr))
X	    if(index > 0) {
X		already= 1;
X		break;
X	    } else
X		index = table_ptr - table;
X	}
X    if(already)
X	/* remove duplicate */
X	while( index < numread ) {
X	    table[index] = table[index + 1];
X	    ++index;
X	}
X    else
X	++numread;
X    }
Xelse
X    {
X#ifdef	EGA
X    if(!EGAaddr)
X#endif
X	printf("\nCreating new hiscore table.\n\n");
X    table[0] = new_entry;
X    numread = 1;
X    }
Xnumread = ( (numread > ENTRIES) ? ENTRIES : numread );
X
Xif(howdead[0])
X    sprintf(buffer,"%s killed by %s with a score of %ld on level %d.",name,howdead,score,level);
Xelse
X    sprintf(buffer,"%s a total winner with a score of %ld on level %d!",name,score,level);
X
X#ifdef	EGA
Xif(EGAaddr)
X    ega_show_scores(buffer,table,numread);
Xelse
X#endif
X    {
X    printf( "\n\n%s\n", buffer );
X    show_scores(table,numread);
X    }
X
Xfp = fopen(HISCOREPATH,W_BIN);
Xif (fp)
X	numsaved = fwrite( VOIDSTAR table, sizeof(score_entry), numread, fp);
Xelse
X	numsaved = 0;
Xif(numsaved < numread)
X#ifdef	EGA
X    if(EGAaddr)
X	egaprintf(8,300,"ERROR! Only %d items saved from %d!",numsaved,numread);
X    else
X#endif
X	printf("ERROR! Only %d items saved from %d !\n",numsaved,numread);
Xfclose(fp);
Xchmod(HISCOREPATH,0660);
XUNLOCK;
X}
X
Xvoid delete_entry(num)
Xint num;
X{
Xscore_entry table[ENTRIES + 22],
X	    *table_ptr = table;
Xint  numread,index = 1, numsaved, lock;
XFILE *fp;
XLOCK;
Xnumread = readtable(table_ptr);
Xif (numread == 0) {
X    printf("Missing or unreadable hiscore table.\n\n");
X    UNLOCK;
X    exit(1);
X}
Xif (num > numread) {
X    printf("Invalid entry, choose again\n");
X    UNLOCK;
X    return;
X}
Xwhile(index < num) {
X    index++;
X    table_ptr++;
X    }
Xwhile(index < numread) {
X    index++;
X    *table_ptr = *(table_ptr+1);
X    table_ptr++;
X    }
Xnumread--;
Xfp = fopen(HISCOREPATH,W_BIN);
Xtable_ptr = table;
Xnumsaved = fwrite( VOIDSTAR table_ptr, sizeof(score_entry), numread, fp);
Xchmod(HISCOREPATH,0660);
Xif(numsaved < numread)
X    printf("ERROR! Only %d items saved from %d !\n",numsaved,numread);
Xfclose(fp);
XUNLOCK;
Xshow_scores(table,numsaved);
X}
X
Xerase_scores()
X{
Xint erasenum,numread,index = 0;
Xchar correct[20],c;
Xscore_entry table[ENTRIES + 2],
X	    *table_ptr = table;
Xprintf("Please enter password:");
Xwhile((c = getchar()) != '\n' && index <19) {
X    correct[index++] = c;
X    }
Xcorrect[index] = 0;
Xif(strcmp(correct,MASTERPASSWORD)) {
X    printf("\nFoo, charlatan!\n");
X    return;
X    }
Xnumread = readtable(table_ptr);
Xshow_scores(table,numread);
Xprintf("\n");
Xfor(;;) {
X    printf("Number to erase (0 to exit): ");
X    scanf("%d",&erasenum);
X    printf("\n");
X    if(erasenum == 0)
X	break;
X    delete_entry(erasenum);
X    printf("\n");
X    }
Xprintf("Byee!\n");
X}
END_OF_FILE
if test 7579 -ne `wc -c <'scores.c'`; then
    echo shar: \"'scores.c'\" unpacked with wrong size!
fi
# end of 'scores.c'
fi
echo shar: End of shell archive.
exit 0