[comp.sources.games] v01i048: warp7 - space war game, Part04/07

games-request@tekred.UUCP (06/10/87)

Submitted by: Larry Wall <lwall%sdcrdcf.UUCP@jove.cam.unisys.com>
Comp.sources.games: Volume 1, Issue 48
Archive-name: warp7/Part04



#! /bin/sh

# Make a new directory for the warp sources, cd to it, and run kits 1
# thru 7 through sh.  When all 7 kits have been run, read README.

echo "This is warp 7.0 kit 4 (of 7).  If kit 4 is complete, the line"
echo '"'"End of kit 4 (of 7)"'" will echo at the end.'
echo ""
export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
echo Extracting intrp.c
sed >intrp.c <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Header: intrp.c,v 7.0.1.2 86/12/12 16:59:04 lwall Exp $
X *
X * $Log:	intrp.c,v $
X * Revision 7.0.1.2  86/12/12  16:59:04  lwall
X * Baseline for net release.
X * 
X * Revision 7.0.1.1  86/10/16  10:51:43  lwall
X * Added Damage.  Fixed random bugs.
X * 
X * Revision 7.0  86/10/08  15:12:19  lwall
X * Split into separate files.  Added amoebas and pirates.
X * 
X */
X
X#include "EXTERN.h"
X#include "warp.h"
X#include "sig.h"
X#include "util.h"
X#include "term.h"
X#include "INTERN.h"
X#include "intrp.h"
X
X/* name of this host */
X#ifdef GETHOSTNAME
X    char *hostname;
X#   undef HOSTNAME
X#   define HOSTNAME hostname
X#else /* !GETHOSTNAME */
X#   ifdef DOUNAME
X#	include <sys/utsname.h>
X	struct utsname uts;
X#	undef HOSTNAME
X#	define HOSTNAME uts.nodename
X#   else /* !DOUNAME */
X#	ifdef PHOSTNAME
X	    char *hostname;
X#	    undef HOSTNAME
X#	    define HOSTNAME hostname
X#	else /* !PHOSTNAME */
X#	    ifdef WHOAMI
X#		undef HOSTNAME
X#		define HOSTNAME sysname
X#	    endif /* WHOAMI */
X#	endif /* PHOSTNAME */
X#   endif /* DOUNAME */
X#endif /* GETHOSTNAME */
X
X#ifdef TILDENAME
Xstatic char *tildename = Nullch;
Xstatic char *tildedir = Nullch;
X#endif
X
Xchar *dointerp();
Xchar *getrealname();
X#ifdef CONDSUB
Xchar *skipinterp();
X#endif
X
Xstatic void abort_interp();
X
Xvoid
Xintrp_init(tcbuf)
Xchar *tcbuf;
X{
X    char *getlogin();
X
X    /* get environmental stuff */
X
X    /* get home directory */
X
X    homedir = getenv("HOME");
X    if (homedir == Nullch)
X	homedir = getenv("LOGDIR");
X
X    dotdir = getval("DOTDIR",homedir);
X
X    /* get login name */
X
X    logname = getenv("USER");
X    if (logname == Nullch)
X	logname = getenv("LOGNAME");
X#ifdef GETLOGIN
X    if (logname == Nullch)
X	logname = savestr(getlogin());
X#endif
X    
X    /* get the real name of the person (%N) */
X    /* Must be done after logname is read in because BERKNAMES uses that */
X
X    strcpy(tcbuf,getrealname(getuid()));
X    realname = savestr(tcbuf);
X
X    /* name of this host (%H) */
X
X#ifdef GETHOSTNAME
X    gethostname(buf,sizeof buf);
X    hostname = savestr(buf);
X#else
X#ifdef DOUNAME
X    /* get sysname */
X    uname(&uts);
X#else
X#ifdef PHOSTNAME
X    {
X	FILE *popen();
X	FILE *pipefp = popen(PHOSTNAME,"r");
X	
X	if (pipefp == Nullfp) {
X	    printf("Can't find hostname\r\n");
X	    sig_catcher(0);
X	}
X	Fgets(buf,sizeof buf,pipefp);
X	buf[strlen(buf)-1] = '\0';	/* wipe out newline */
X	hostname = savestr(buf);
X	pclose(pipefp);
X    }
X#endif
X#endif
X#endif
X    if (index(HOSTNAME,'.'))
X	hostname = savestr(HOSTNAME);
X    else {
X	char hname[128];
X
X	strcpy(hname,HOSTNAME);
X	strcat(hname,MYDOMAIN);
X	hostname=savestr(hname);
X    }
X    warplib = savestr(filexp(WARPLIB));
X
X    if (scorespec)			/* that getwd below takes ~1/3 sec. */
X	return;				/* and we do not need it for -s */
X    (void) getwd(tcbuf);		/* find working directory name */
X    origdir = savestr(tcbuf);		/* and remember it */
X}
X
X/* expand filename via %, ~, and $ interpretation */
X/* returns pointer to static area */
X/* Note that there is a 1-deep cache of ~name interpretation */
X
Xchar *
Xfilexp(s)
XReg1 char *s;
X{
X    static char filename[CBUFLEN];
X    char scrbuf[CBUFLEN];
X    Reg2 char *d;
X
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	printf("< %s\r\n",s);
X#endif
X    interp(filename, (sizeof filename), s);			/* interpret any % escapes */
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	printf("%% %s\r\n",filename);
X#endif
X    s = filename;
X    if (*s == '~') {	/* does destination start with ~? */
X	if (!*(++s) || *s == '/') {
X	    Sprintf(scrbuf,"%s%s",homedir,s);
X				/* swap $HOME for it */
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	printf("~ %s\r\n",scrbuf);
X#endif
X	    strcpy(filename,scrbuf);
X	}
X	else {
X#ifdef TILDENAME
X	    for (d=scrbuf; isalnum(*s); s++,d++)
X		*d = *s;
X	    *d = '\0';
X	    if (tildedir && strEQ(tildename,scrbuf)) {
X		strcpy(scrbuf,tildedir);
X		strcat(scrbuf, s);
X		strcpy(filename, scrbuf);
X#ifdef DEBUGGING
X		if (debug & DEB_FILEXP)
X		    printf("r %s %s\r\n",tildename,tildedir);
X#endif
X	    }
X	    else {
X		if (tildename) {
X		    free(tildename);
X		    free(tildedir);
X		}
X		tildedir = Nullch;
X		tildename = savestr(scrbuf);
X#ifdef GETPWENT		/* getpwnam() is not the paragon of efficiency */
X		{
X		    struct passwd *getpwnam();
X		    struct passwd *pwd = getpwnam(tildename);
X
X		    Sprintf(scrbuf,"%s%s",pwd->pw_dir,s);
X		    tildedir = savestr(pwd->pw_dir);
X		    strcpy(filename,scrbuf);
X#ifdef GETPWENT
X		    endpwent();
X#endif
X		}
X#else			/* this will run faster, and is less D space */
X		{	/* just be sure LOGDIRFIELD is correct */
X		    FILE *pfp = fopen("/etc/passwd","r");
X		    char tmpbuf[512];
X		    int i;
X		    
X		    if (pfp == Nullfp) {
X			printf(cantopen,"passwd");
X			sig_catcher(0);
X		    }
X		    while (fgets(tmpbuf,512,pfp) != Nullch) {
X			d = cpytill(scrbuf,tmpbuf,':');
X#ifdef DEBUGGING
X			if (debug & DEB_FILEXP)
X			    printf("p %s\r\n",tmpbuf);
X#endif
X			if (strEQ(scrbuf,tildename)) {
X			    for (i=LOGDIRFIELD-2; i; i--) {
X				if (d)
X				    d = index(d+1,':');
X			    }
X			    if (d) {
X				Cpytill(scrbuf,d+1,':');
X				tildedir = savestr(scrbuf);
X				strcat(scrbuf,s);
X				strcpy(filename,scrbuf);
X			    }
X			    break;
X			}
X		    }
X		    Fclose(pfp);
X		}
X#endif
X	    }
X#else /* !TILDENAME */
X#ifdef VERBOSE
X	    IF(verbose)
X		fputs("~loginname not implemented.\r\n",stdout);
X	    ELSE
X#endif
X#ifdef TERSE
X		fputs("~login not impl.\r\n",stdout);
X#endif
X#endif
X	}
X    }
X    else if (*s == '$') {	/* starts with some env variable? */
X	d = scrbuf;
X	*d++ = '%';
X	if (s[1] == '{')
X	    strcpy(d,s+2);
X	else {
X	    *d++ = '{';
X	    for (s++; isalnum(*s); s++) *d++ = *s;
X				/* skip over token */
X	    *d++ = '}';
X	    strcpy(d,s);
X	}
X#ifdef DEBUGGING
X	if (debug & DEB_FILEXP)
X	    printf("$ %s\r\n",scrbuf);
X#endif
X	interp(filename, (sizeof filename), scrbuf);
X					/* this might do some extra '%'s but */
X					/* that is how the Mercedes Benz */
X    }
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	printf("> %s\r\n",filename);
X#endif
X    return filename;
X}
X
X#ifdef CONDSUB
X/* skip interpolations */
X
Xchar *
Xskipinterp(pattern,stoppers)
XReg1 char *pattern;
Xchar *stoppers;
X{
X
X    while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
X#ifdef DEBUGGING
X	if (debug & 8)
X	    printf("skipinterp till %s at %s\r\n",stoppers?stoppers:"",pattern);
X#endif
X	if (*pattern == '%' && pattern[1]) {
X	    switch (*++pattern) {
X	    case '{':
X		for (pattern++; *pattern && *pattern != '}'; pattern++)
X		    if (*pattern == '\\')
X			pattern++;
X		break;
X#ifdef CONDSUB
X	    case '(': {
X		pattern = skipinterp(pattern+1,"!=");
X		if (!*pattern)
X		    goto getout;
X		for (pattern++; *pattern && *pattern != '?'; pattern++)
X		    if (*pattern == '\\')
X			pattern++;
X		if (!*pattern)
X		    goto getout;
X		pattern = skipinterp(pattern+1,":)");
X		if (*pattern == ':')
X		    pattern = skipinterp(pattern+1,")");
X		break;
X	    }
X#endif
X#ifdef BACKTICK
X	    case '`': {
X		pattern = skipinterp(pattern+1,"`");
X		break;
X	    }
X#endif
X#ifdef PROMPTTTY
X	    case '"':
X		pattern = skipinterp(pattern+1,"\"");
X		break;
X#endif
X	    default:
X		break;
X	    }
X	    pattern++;
X	}
X	else {
X	    if (*pattern == '^' && pattern[1])
X		pattern += 2;
X	    else if (*pattern == '\\' && pattern[1])
X		pattern += 2;
X	    else
X		pattern++;
X	}
X    }
Xgetout:
X    return pattern;			/* where we left off */
X}
X#endif
X
X/* interpret interpolations */
X
Xchar *
Xdointerp(dest,destsize,pattern,stoppers)
XReg1 char *dest;
XReg2 int destsize;
XReg3 char *pattern;
Xchar *stoppers;
X{
X    Reg4 char *s;
X    Reg5 int i;
X    char scrbuf[512];
X    bool upper = FALSE;
X    bool lastcomp = FALSE;
X    int metabit = 0;
X
X    while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
X#ifdef DEBUGGING
X	if (debug & 8)
X	    printf("dointerp till %s at %s\r\n",stoppers?stoppers:"",pattern);
X#endif
X	if (*pattern == '%' && pattern[1]) {
X	    upper = FALSE;
X	    lastcomp = FALSE;
X	    for (s=Nullch; !s; ) {
X		switch (*++pattern) {
X		case '^':
X		    upper = TRUE;
X		    break;
X		case '_':
X		    lastcomp = TRUE;
X		    break;
X		case '{':
X		    pattern = cpytill(scrbuf,pattern+1,'}');
X		    if (s = index(scrbuf,'-'))
X			*s++ = '\0';
X		    else
X			s = nullstr;
X		    s = getval(scrbuf,s);
X		    break;
X#ifdef CONDSUB
X		case '(': {
X		    char rch;
X		    bool matched;
X		    
X		    pattern = dointerp(dest,destsize,pattern+1,"!=");
X		    rch = *pattern;
X		    if (rch == '!')
X			pattern++;
X		    if (*pattern != '=')
X			goto getout;
X		    pattern = cpytill(scrbuf,pattern+1,'?');
X		    if (!*pattern)
X			goto getout;
X		    if (*scrbuf == '^' && scrbuf[strlen(scrbuf)-1] == '$') {
X			scrbuf[strlen(scrbuf)-1] = '\0';
X			matched = strEQ(scrbuf+1,dest);
X		    }
X		    else
X			matched = instr(dest,scrbuf) != Nullch;
X		    if (matched==(rch == '=')) {
X			pattern = dointerp(dest,destsize,pattern+1,":)");
X			if (*pattern == ':')
X			    pattern = skipinterp(pattern+1,")");
X		    }
X		    else {
X			pattern = skipinterp(pattern+1,":)");
X			if (*pattern == ':')
X			    pattern++;
X			pattern = dointerp(dest,destsize,pattern,")");
X		    }
X		    s = dest;
X		    break;
X		}
X#endif
X#ifdef BACKTICK
X		case '`': {
X		    FILE *pipefp, *popen();
X
X		    pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`");
X		    pipefp = popen(scrbuf,"r");
X		    if (pipefp != Nullfp) {
X			int len;
X
X			len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1,
X			    pipefp);
X			scrbuf[len] = '\0';
X			pclose(pipefp);
X		    }
X		    else {
X			printf("\r\nCan't run %s\r\n",scrbuf);
X			*scrbuf = '\0';
X		    }
X		    for (s=scrbuf; *s; s++) {
X			if (*s == '\n') {
X			    if (s[1])
X				*s = ' ';
X			    else
X				*s = '\0';
X			}
X		    }
X		    s = scrbuf;
X		    break;
X		}
X#endif
X#ifdef PROMPTTTY
X		case '"':
X		    pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\"");
X		    fputs(scrbuf,stdout);
X		    resetty();
X		    gets(scrbuf);
X		    crmode();
X		    raw();
X		    noecho();
X		    nonl();
X		    s = scrbuf;
X		    break;
X#endif
X		case '~':
X		    s = homedir;
X		    break;
X		case '.':
X		    s = dotdir;
X		    break;
X		case '$':
X		    s = scrbuf;
X		    Sprintf(s,"%d",getpid());
X		    break;
X		case 'H':			/* host name */
X		    s = hostname;
X		    break;
X		case 'L':			/* login id */
X		    s = logname;
X		    break;
X		case 'N':			/* full name */
X		    s = getval("NAME",realname);
X		    break;
X		case 'O':
X		    s = origdir;
X		    break;
X		case 'p':
X		    s = cwd;
X		    break;
X		case 'X':			/* warp library */
X		    s = warplib;
X		    break;
X		default:
X		    if (--destsize <= 0)
X			abort_interp();
X		    *dest++ = *pattern | metabit;
X		    s = nullstr;
X		    break;
X		}
X	    }
X	    if (!s)
X		s = nullstr;
X	    pattern++;
X	    if (upper || lastcomp) {
X		char *t;
X
X		if (s != scrbuf) {
X		    Safecpy(scrbuf,s,(sizeof scrbuf));
X		    s = scrbuf;
X		}
X		if (upper || !(t=rindex(s,'/')))
X		    t = s;
X		while (*t && !isalpha(*t))
X		    t++;
X		if (islower(*t))
X		    *t = toupper(*t);
X	    }
X	    i = metabit;		/* maybe get into register */
X	    if (s == dest) {
X		while (*dest) {
X		    if (--destsize <= 0)
X			abort_interp();
X		    *dest++ |= i;
X		}
X	    }
X	    else {
X		while (*s) {
X		    if (--destsize <= 0)
X			abort_interp();
X		    *dest++ = *s++ | i;
X		}
X	    }
X	}
X	else {
X	    if (--destsize <= 0)
X		abort_interp();
X	    if (*pattern == '^' && pattern[1]) {
X		++pattern;			/* skip uparrow */
X		i = *pattern;		/* get char into a register */
X		if (i == '?')
X		    *dest++ = '\177' | metabit;
X		else if (i == '(') {
X		    metabit = 0200;
X		    destsize++;
X		}
X		else if (i == ')') {
X		    metabit = 0;
X		    destsize++;
X		}
X		else
X		    *dest++ = i & 037 | metabit;
X		pattern++;
X	    }
X	    else if (*pattern == '\\' && pattern[1]) {
X		++pattern;			/* skip backslash */
X		i = *pattern;		/* get char into a register */
X    
X		/* this used to be a switch but the if may save space */
X		
X		if (i >= '0' && i <= '7') {
X		    i = 1;
X		    while (i < 01000 && *pattern >= '0' && *pattern <= '7') {
X			i <<= 3;
X			i += *pattern++ - '0';
X		    }
X		    *dest++ = i & 0377 | metabit;
X		    --pattern;
X		}
X		else if (i == 'b')
X		    *dest++ = '\b' | metabit;
X		else if (i == 'f')
X		    *dest++ = '\f' | metabit;
X		else if (i == 'n')
X		    *dest++ = '\n' | metabit;
X		else if (i == 'r')
X		    *dest++ = '\r' | metabit;
X		else if (i == 't')
X		    *dest++ = '\t' | metabit;
X		else
X		    *dest++ = i | metabit;
X		pattern++;
X	    }
X	    else
X		*dest++ = *pattern++ | metabit;
X	}
X    }
X    *dest = '\0';
Xgetout:
X    return pattern;			/* where we left off */
X}
X
Xvoid
Xinterp(dest,destsize,pattern)
Xchar *dest;
Xint destsize;
Xchar *pattern;
X{
X    (void) dointerp(dest,destsize,pattern,Nullch);
X#ifdef DEBUGGING
X    if (debug & DEB_FILEXP)
X	fputs(dest,stdout);
X#endif
X}
X
X/* get the person's real name from /etc/passwd */
X/* (string is overwritten, so it must be copied) */
X
Xchar *
Xgetrealname(uid)
Xint uid;
X{
X    char *s, *c;
X
X#ifdef PASSNAMES
X#ifdef GETPWENT
X    struct passwd *pwd = getpwuid(uid);
X    
X    s = pwd->pw_gecos;
X#else
X    char tmpbuf[512];
X    int i;
X
X    getpw(uid, tmpbuf);
X    for (s=tmpbuf, i=GCOSFIELD-1; i; i--) {
X	if (s)
X	    s = index(s,':')+1;
X    }
X    if (!s)
X	return nullstr;
X    Cpytill(tmpbuf,s,':');
X    s = tmpbuf;
X#endif
X#ifdef BERKNAMES
X#ifdef BERKJUNK
X    while (*s && !isalnum(*s) && *s != '&') s++;
X#endif
X    if ((c = index(s, ',')) != Nullch)
X	*c = '\0';
X    if ((c = index(s, ';')) != Nullch)
X	*c = '\0';
X    s = cpytill(buf,s,'&');
X    if (*s == '&') {			/* whoever thought this one up was */
X	c = buf + strlen(buf);		/* in the middle of the night */
X	strcat(c,logname);		/* before the morning after */
X	strcat(c,s+1);
X	if (islower(*c))
X	    *c = toupper(*c);		/* gack and double gack */
X    }
X#else
X    if ((c = index(s, '(')) != Nullch)
X	*c = '\0';
X    if ((c = index(s, '-')) != Nullch)
X	s = c;
X    strcpy(buf,tmpbuf);
X#endif
X#ifdef GETPWENT
X    endpwent();
X#endif
X    return buf;				/* return something static */
X#else
X    if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != Nullfp) {
X	Fgets(buf,sizeof buf,tmpfp);
X	Fclose(tmpfp);
X    }
X    else {
X	resetty();
X	printf("What is your name? ");
X	Fgets(buf,(sizeof buf),stdin);
X	crmode();
X	raw();
X	noecho();
X	nonl();
X	if (fork())
X	    wait(0);
X	else {
X	    setuid(getuid());
X	    if ((tmpfp = fopen(filexp(FULLNAMEFILE),"w")) == NULL)
X		exit(1);
X	    fprintf(tmpfp, "%s\n", buf);
X	    Fclose(tmpfp);
X	    exit(0);
X	}
X    }
X    buf[strlen(buf)-1] = '\0';
X    return buf;
X#endif
X}
X
Xstatic void
Xabort_interp()
X{
X    fputs("\r\n% interp buffer overflow!\r\n",stdout);
X    sig_catcher(0);
X}
!STUFFY!FUNK!
echo Extracting warp.h
sed >warp.h <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Header: warp.h,v 7.0.1.2 86/12/12 17:08:42 lwall Exp $ */
X
X/* $Log:	warp.h,v $
X * Revision 7.0.1.2  86/12/12  17:08:42  lwall
X * Baseline for net release.
X * 
X * Revision 7.0.1.1  86/10/16  10:54:26  lwall
X * Added Damage.  Fixed random bugs.
X * 
X * Revision 7.0  86/10/08  15:17:55  lwall
X * Split into separate files.  Added amoebas and pirates.
X * 
X */
X
Xextern int errno;
X
X#include "config.h"	/* generated by Configure script */
X
X#include <stdio.h>
X#include <signal.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <errno.h> 
X
X/* WARPLIB must be readable and writeable by warp, but not by anyone who you
X * don't trust.  In other words, to set up warp so everyone can play and
X * no one can cheat, give warp a uid of its own and make warp setuid to
X * that uid.  WARPLIB must then NOT be made writeable by the world,
X * since no attempt is made to encrypt saved games or anything.
X * (It must be readable by the world, however, due to a strangeness in
X * access.)
X */
X
X#define SAVEDIR "./"
X#define NEWSFILE "warp.news"
X#define HELPFILE "warp.doc"
X#define LOCKFILE ".warp.lock"
X#define LOGFILE "warp.log"
X#define SCOREBOARD "warp.top"
X#define LSCOREBOARD "warp.lowtop"
X#define FSCOREBOARD "warp.funtop"
X#define TMPSCOREBOARD "warp.topnew"
X#define WARPMACRO "%X/Kbmap.%{TERM}"
X
X/* warp library */
X#ifndef WARPLIB		/* ~ and %l only ("~%l" is permissable) */
X#   ifdef PRIVLIB
X#	define WARPLIB PRIVLIB
X#   else
X#	define WARPLIB "/usr/games/warp"
X#   endif
X#endif
X
XEXT char *warplib;
X
X#define PERMMAPS 8	/* how many starmaps are permanent */
X#define MAPS 20		/* how many starmaps to choose from */
X			/* (MAPS - PERMMAPS is # of half-gone universes) */
X
X/*
X * Screen size info, minimum screen size is 23x40 (actually 24x80).
X * YSIZE and XSIZE should be relatively prime so that a torpedo launched
X * at an angle will eventually cover the whole screen.
X * To calculate a new position for something:
X * new_position = (current_position + delta + ?SIZE00) % ?SIZE
X * This allows for negative deltas of up to ?SIZE00 (% doesn't work right
X * on negative numbers).
X * ?SIZE01, etc. are fudges for efficiency--they already include a delta.
X */
X
X#define XYSIZE 920
X#define XYSIZEx4 3680
X
X#define YSIZE   23
X#define YSIZE00 2300
X#define YSIZE01 2301
X#define YSIZE99 2299
X
X#define XSIZE   40
X#define XSIZE00 4000
X#define XSIZE01 4001
X#define XSIZE99 3999
X#define XSIZE02 4002
X#define XSIZE98 3998
X#define XSIZE03 4003
X#define XSIZE97 3997
X#define XSIZE08 4008
X#define XSIZE92 3992
X
XEXT char amb[YSIZE][XSIZE];
X
X#ifdef WHOAMI
X#    include <whoami.h>
X#endif
X
X#ifndef isalnum
X#   define isalnum(c) (isalpha(c) || isdigit(c))
X#endif
X
X#ifdef IOCTL
X#include <sys/ioctl.h>
X#endif /* IOCTL */
X
X#ifdef FCNTL
X#   include <fcntl.h>
X#endif
X
X#ifdef TERMIO
X#   include <termio.h>
X#else
X#   include <sgtty.h>
X#endif
X
X#ifdef FTIMER
X#include <sys/timeb.h>
X#endif
X
X#ifdef GETPWENT
X#   include <pwd.h>
X#endif
X
X#define BITSPERBYTE 8
X#define LBUFLEN 512	/* line buffer length */
X
X#ifdef pdp11
X#   define CBUFLEN 256	/* command buffer length */
X#   define PUSHSIZE 128
X#else
X#   define CBUFLEN 512	/* command buffer length */
X#   define PUSHSIZE 256
X#endif
X#ifdef pdp11
X#   define MAXFILENAME 128
X#else
X#   define MAXFILENAME 512
X#endif
X#define FINISHCMD 0177
X
X/* some handy defs */
X
X#define bool char
X#define TRUE (1)
X#define FALSE (0)
X#define Null(t) ((t)0)
X#define Nullch Null(char *)
X#define Nullfp Null(FILE *)
X
X#define Ctl(ch) (ch & 037)
X
X#define strNE(s1,s2) (strcmp(s1,s2))
X#define strEQ(s1,s2) (!strcmp(s1,s2))
X#define strnNE(s1,s2,l) (strncmp(s1,s2,l))
X#define strnEQ(s1,s2,l) (!strncmp(s1,s2,l))
X
X#define sgn(x) ((x) < 0 ? -1 : (x) > 0)
X
X/* Things we can figure out ourselves */
X
X#ifdef SIGPROF
X#   define BSD42		/* do we have Berkeley 4.2? */
X#endif
X
X#ifdef FIONREAD
X#   define PENDING
X#else
X#   ifdef O_NDELAY
X#	define PENDING
X#   else
X#	ifdef RDCHK
X#	    define PENDING
X#	endif
X#   endif
X#endif
X
X#ifdef EUNICE
X#   define UNLINK(victim) while (!unlink(victim))
X#else
X#   define UNLINK(victim) unlink(victim)
X#endif
X
X/* Valid substitutions for strings marked with % comment are:
X *	%H	Host name (yours)
X *	%L	Login name (yours)
X *	%N	Full name (yours)
X *	%O	Original working directory (where you ran warp from)
X *	%X	Warp library directory
X *	%~	Home directory
X *	%.	Directory containing . files
X *	%$	current process number
X *	%{name} Environment variable "name".  %{name-default} form allowed.
X *	%"prompt"
X *		Print prompt and insert what is typed.
X *	%`command`
X *		Insert output of command.
X *	%(test_text=pattern?if_text:else_text)
X *		Substitute if_text if test_text matches pattern, otherwise
X *		substitute else_text.  Use != for negated match.
X *		% substitutions are done on test_text, if_text, and else_text.
X *		(Note: %() only works if CONDSUB defined.)
X */
X
X/* *** System Dependent Stuff *** */
X
X/* NOTE: many of these are defined in the config.h file */
X
X#ifndef ROOTID
X#   define ROOTID 0        /* uid of superuser */
X#endif
X
X#ifdef NORMSIG
X#   define sigset Signal
X#   define sigignore(sig) Signal(sig,SIG_IGN)
X#endif
X
X#ifndef LOGDIRFIELD
X#   define LOGDIRFIELD 6		/* Which field (origin 1) is the */
X					/* login directory in /etc/passwd? */
X					/* (If it is not kept in passwd, */
X					/* but getpwnam() returns it, */
X					/* define the symbol GETPWENT) */
X#endif
X#ifndef GCOSFIELD
X#   define GCOSFIELD 5
X#endif
X
X/* Undefine any of the following features to save both I and D space */
X/* In general, earlier ones are easier to get along without */
X/* Pdp11's without split I and D may have to undefine them all */
X#define DEBUGGING	/* include debugging code */
X#define PUSHBACK	/* macros and keymaps using pushback buffer */
X#define CONDSUB		/* allow %(cond?text:text) */
X#define BACKTICK	/* allow %`command` */
X#define PROMPTTTY	/* allow %"prompt" */
X#define GETLOGIN	/* use getlogin() routine as backup to environment */
X			/* variables USER or LOGNAME */
X#define TILDENAME	/* allow ~logname expansion */
X#define GETWD		/* use our getwd() instead of piped in pwd */
X#define SETUIDGID	/* substitute eaccess() for access() so that rn */
X			/* can run setuid or setgid */
X			/* if not setuid or setgid, you don't need it */
X#define VERBOSE		/* compile in more informative messages */
X#define TERSE		/* compile in shorter messages */
X
X/* some dependencies among options */
X
X#ifndef SETUIDGID
X#   define eaccess access
X#endif
X
X#ifdef VERBOSE
X#   ifdef TERSE
X#	define IF(c) if (c)
X#	define ELSE else
X#   else /* !TERSE */
X#	define IF(c)
X#	define ELSE
X#   endif
X#else /* !VERBOSE */
X#   ifndef TERSE
X#	define TERSE
X#   endif
X#   define IF(c) "IF" outside of VERBOSE???
X#   define ELSE "ELSE" outside of VERBOSE???
X#endif
X
X#ifdef DEBUGGING
X#   define assert(ex) {if (!(ex)){fprintf(stderr,"Assertion failed: file %s, line %d\r\n", __FILE__, __LINE__);sig_catcher(0);}}
X#else
X#   define assert(ex) ;
X#endif
X
X#define TCSIZE 512	/* capacity for termcap strings */
X
X/* End of Space Conservation Section */
X
X/* More System Dependencies */
X
X/* preferred shell for use in doshell routine */
X/*  ksh or sh would be okay here */
X#ifndef PREFSHELL
X#   define PREFSHELL "/bin/csh"
X#endif
X
X/* path to fastest starting shell */
X#ifndef SH
X#   define SH "/bin/sh"
X#endif
X
X/* location of macro file */
X#ifndef WARPMACRO
X#   ifdef PUSHBACK
X#	define WARPMACRO "%./.warpmac"
X#   endif
X#endif
X
X/* location of full name */
X#ifndef FULLNAMEFILE
X#   ifndef PASSNAMES
X#	define FULLNAMEFILE "%./.fullname"
X#   endif
X#endif
X
X/* a motd-like file for warp */
X#ifndef WARPNEWSNAME		/* % and ~ */
X#   define WARPNEWSNAME "%X/warp.news"
X#endif
X
X/* typedefs */
X
Xtypedef unsigned int	MEM_SIZE;	/* for passing to malloc */
X
X/* *** end of the machine dependent stuff *** */
X
X/* GLOBAL THINGS */
X
X/* file statistics area */
X
XEXT struct stat filestat;
X
X/* various things of type char */
X
Xchar	*index();
Xchar	*rindex();
Xchar	*getenv();
Xchar	*strcat();
Xchar	*strcpy();
X#ifdef CHARSPRINTF
Xchar	*sprintf();
X#else
Xint	sprintf();
X#endif
X
XEXT char buf[LBUFLEN+1];	/* general purpose line buffer */
X
XEXT char *cwd INIT(Nullch);		/* current working directory */
X
X/* switches */
X
X#ifdef DEBUGGING
X    EXT int debug INIT(0);				/* -D */
X#   define DEB_FILEXP 64 
X#endif
X
X#ifdef VERBOSE
X#   ifdef TERSE
X	EXT bool verbose INIT(TRUE);			/* +t */
X#   endif
X#endif
X
X/* miscellania */
X
XEXT FILE *tmpfp INIT(Nullfp);	/* scratch fp */
X
X#define NOMARKING 0
X#define STANDOUT 1
X#define UNDERLINE 2
X
X/* Factored strings */
X
XEXT char nullstr[] INIT("");
XEXT char readerr[] INIT("warp read error");
XEXT char cantopen[] INIT("Can't open %s\r\n");
X
X#ifdef VERBOSE
X    EXT char nocd[] INIT("Can't chdir to directory %s\r\n");
X#else
X    EXT char nocd[] INIT("Can't find %s\r\n");
X#endif
X
Xextern int errno;
X
XEXT bool justonemoretime INIT(TRUE);
XEXT bool keepgoing INIT(TRUE);
X
XEXT bool friendspec INIT(FALSE);
XEXT bool piratespec INIT(FALSE);
XEXT bool amoebaspec INIT(FALSE);
XEXT bool starspec INIT(FALSE);
XEXT bool klingspec INIT(FALSE);
XEXT bool apolspec INIT(FALSE);
XEXT bool crushspec INIT(FALSE);
XEXT bool romspec INIT(FALSE);
XEXT bool prespec INIT(FALSE);
XEXT bool tholspec INIT(FALSE);
XEXT bool gornspec INIT(FALSE);
XEXT bool beginner INIT(FALSE);
XEXT bool massacre INIT(FALSE);
XEXT bool lowspeed INIT(FALSE);
XEXT bool debugging INIT(FALSE);
XEXT bool didkill INIT(FALSE);
XEXT bool experimenting INIT(FALSE);
XEXT bool scorespec INIT(FALSE);
XEXT bool metakey INIT(FALSE);
X
XEXT bool bombed_out;
XEXT bool panic INIT(FALSE);
XEXT bool madgorns;
X
XEXT int madfriends;
X
XEXT int inumpirates;
XEXT int numpirates;
XEXT int inumfriends;
XEXT int numfriends;
XEXT int inumamoebas;
XEXT int numamoebas;
XEXT int inumstars;
XEXT int numstars;
XEXT int inumenemies;
XEXT int numenemies;
XEXT int inumroms;
XEXT int inumthols;
XEXT int inumapollos;
XEXT int numapollos;
XEXT int apolloflag;
XEXT int inumcrushes;
XEXT int numcrushes;
XEXT int inumgorns;
XEXT int numgorns;
XEXT int deados;
XEXT int deadmudds;
XEXT int smarts;
XEXT int ismarts INIT(0);
XEXT int numos INIT(0);
XEXT int numxes INIT(0);
XEXT int ient;
XEXT int numents;
XEXT int ibase;
XEXT int numbases;
XEXT int inuminhab;
XEXT int numinhab;
XEXT int wave;
XEXT int cumsmarts;
XEXT int prescene INIT(-1);
XEXT int scandist;
XEXT int antibase;
XEXT int sm35;
XEXT int sm45;
XEXT int sm50;
XEXT int sm55;
XEXT int sm80;
XEXT int sm95;
XEXT int entmax;
XEXT int basemax;
XEXT int enemshields;
XEXT int super;
XEXT int whenok;
XEXT int yamblast;
XEXT int xamblast;
XEXT int ambsize;
X
XEXT char spbuf[512];
X
Xchar *index(), *ttyname(), *malloc(), *ctime(), *strcpy();
Xchar *getenv(), cmstore(), *tgoto();
Xlong atol();
X
X#define Fclose (void)fclose
X#define Fflush (void)fflush
X#define Fgets (void)fgets
X#define Sprintf (void)sprintf
X#define Signal (void)signal
X#define Safecpy (void)safecpy
X#define Cpytill (void)cpytill
X#define Tract (void)tract
X#define Make_object (void)make_object
X#define Read_tty (void)read_tty
!STUFFY!FUNK!
echo Extracting term.h
sed >term.h <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Header: term.h,v 7.0.1.2 86/12/12 17:05:15 lwall Exp $ */
X
X/* $Log:	term.h,v $
X * Revision 7.0.1.2  86/12/12  17:05:15  lwall
X * Baseline for net release.
X * 
X * Revision 7.0.1.1  86/10/16  10:53:33  lwall
X * Added Damage.  Fixed random bugs.
X * 
X * Revision 7.0  86/10/08  15:14:07  lwall
X * Split into separate files.  Added amoebas and pirates.
X * 
X */
X
X/* warp will still work without the following, but may get ahead at low speed */
X#ifdef TIOCOUTQ		/* chars left in output queue */
X#define output_pending() (ioctl(1, TIOCOUTQ, &iocount),iocount)
X#endif
X
X/* If some of the following look something like curses calls, it is because
X * warp used to use curses but doesn't now.  Warp was neither as efficient nor
X * as portable with curses, and since the program had to cheat on curses all
X * over the place anyway, we ripped it out.
X */
X#define setimage(of,to) (mvaddch(of->posy+1,of->posx*2,of->image=(to)))
X
X#define mvaddch(y,x,ch) move((y),(x),(ch))
X/* #define addch(ch) (tmpchr=(ch), write(1,&tmpchr,1), real_x++) */
X#define mvaddc(y,x,ch) move((y),(x),(ch))
X#define addc(ch) (write(1,&(ch),1), real_x++)
X#define addspace() (write(1," ",1), real_x++)
X#define mvaddstr(y,x,s) (move((y),(x),0), tmpstr = (s), \
X     tmplen = strlen(tmpstr), write(1, tmpstr, tmplen), real_x += tmplen)
X
XEXT int tmplen;
XEXT char *tmpstr;
X/* EXT char tmpchr; */
X
X/* The following macros are like the pseudo-curses macros above, but do
X * certain amount of controlled output buffering.
X *
X * NOTE: a beg_qwrite()..end_qwrite() sequence must NOT contain a cursor
X * movement (move), because the move() routine uses beg_qwrite()..end_qwrite()
X * itself.
X */
X
X#define beg_qwrite() (maxcmstring = cmbuffer)
X#ifdef vax
X#define qwrite() asm("movc3 _gfillen,_filler,*_maxcmstring"); maxcmstring += gfillen
X#else
X#define qwrite() (movc3(gfillen,filler,maxcmstring), maxcmstring += gfillen)
X#endif
X#define qaddc(ch) (*maxcmstring++ = (ch), real_x++)
X#define qaddch(ch) (*maxcmstring++ = (ch), real_x++)
X#define qaddspace() (*maxcmstring++ = ' ', real_x++)
X#define end_qwrite() (write(1,cmbuffer,maxcmstring-cmbuffer))
X
X/* setting a ??size to infinity forces cursor addressing in that direction */
X
XEXT int CMsize;
XEXT int BCsize INIT(1);
XEXT int DOsize INIT(1000);
XEXT int UPsize INIT(1000);
XEXT int NDsize INIT(1000);
X
XEXT int charsperhalfsec;
X
XEXT int real_y INIT(-100);
XEXT int real_x INIT(-100);
X
X#ifdef DOINIT
Xchar filler[] = {0,'\b',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
X#else
XEXT char filler[];
X#endif
X
XEXT char *bsptr INIT(filler+1);
X
XEXT char term[12];
X
XEXT char gfillen INIT(25);
X
XEXT char *maxcmstring;
XEXT char cmbuffer[512];
X
X#define BREAKCH '\0'
X
XEXT char INTRCH INIT('\03');
X
X#ifdef PUSHBACK
X    EXT char circlebuf[PUSHSIZE];
X    EXT int nextin INIT(0);
X    EXT int nextout INIT(0);
X#   ifdef PENDING
X#	ifdef FIONREAD
X	    EXT long iocount INIT(0);
X#	    ifndef lint
X#		define input_pending() (nextin!=nextout || \
X(ioctl(0, FIONREAD, &iocount),(int)iocount))
X#	    else
X#		define input_pending() bizarre
X#	    endif /* lint */
X#	else /* FIONREAD */
X	    int circfill();
X#	    ifdef RDCHK
X#		ifndef lint
X#		    define input_pending() rdchk(0)
X#		else /* lint */
X#		    define input_pending() bizarre
X#		endif /* lint */
X#	    else /* RDCHK */
X#		ifndef O_NDELAY	/* assert O_NDELAY */
X		    ??? PENDING isn't defined correctly in warp.h
X#		endif
X		EXT int devtty INIT(0);
X#		ifndef lint
X#		    define input_pending() (nextin!=nextout || circfill())
X#		else
X#		    define input_pending() bizarre
X#		endif /* lint */
X#	    endif /* RDCHK */
X#	endif /* FIONREAD */
X#   else /* PENDING */
X	??? warp won't work without PENDING
X#	ifndef lint
X#	    define input_pending() (nextin!=nextout)
X#	else
X#	    define input_pending() bizarre
X#	endif /* lint */
X#   endif /* PENDING */
X#else /* PUSHBACK */
X#   ifdef PENDING
X#	ifdef FIONREAD /* must have FIONREAD or O_NDELAY for input_pending() */
X#	    define read_tty(addr,size) read(0,addr,size)
X#	    ifndef lint
X#		define input_pending() (ioctl(0, FIONREAD, &iocount), \
X(int)iocount)
X#	    else
X#		define input_pending() bizarre
X#	    endif /* lint */
X	    EXT long iocount INIT(0);
X#	else /* FIONREAD */
X#	    ifdef RDCHK		/* actually, they can have rdchk() too */
X#	    define read_tty(addr,size) read(0,addr,size)
X#		ifndef lint
X#		    define input_pending() rdchk(0)
X#		else /* lint */
X#		    define input_pending() bizarre
X#		endif /* lint */
X#	    else /* RDCHK */
X#		ifndef O_NDELAY	/* assert O_NDELAY */
X		    ??? PENDING isn't defined correctly in warp.h
X#		endif
X		EXT int devtty INIT(0);
X		EXT bool is_input INIT(FALSE);
X		EXT char pending_ch INIT(0);
X#		ifndef lint
X#		    define input_pending() (is_input || \
X(is_input=read(devtty,&pending_ch,1)))
X#		else
X#		    define input_pending() bizarre
X#		endif /* lint */
X#	    endif /* RDCHK */
X#	endif /* FIONREAD */
X#   else /* PENDING */
X	??? warp won't work without PENDING
X#	define read_tty(addr,size) read(0,addr,size)
X#	define input_pending() (FALSE)
X#   endif /* PENDING */
X#endif /* PUSHBACK */
X
X/* stuff wanted by terminal mode diddling routines */
X
X#ifdef TERMIO
XEXT struct termio _tty, _oldtty;
X#else
XEXT struct sgttyb _tty;
XEXT int _res_flg INIT(0);
X#endif
X
XEXT int _tty_ch INIT(2);
XEXT bool bizarre INIT(FALSE);			/* do we need to restore terminal? */
X
X/* terminal mode diddling routines */
X
X#ifdef TERMIO
X  
X#define raw() ((bizarre=1),_tty.c_lflag &=~ISIG,_tty.c_cc[VMIN] = 1,ioctl(_tty_ch,TCSETAF,&_tty))
X#define noraw() ((bizarre=1),_tty.c_lflag |= ISIG,_tty.c_cc[VEOF] = CEOF,ioctl(_tty_ch,TCSETAF,&_tty))
X#define crmode() ((bizarre=1),_tty.c_lflag &=~ICANON,_tty.c_cc[VMIN] = 1,ioctl(_tty_ch,TCSETAF,&_tty))
X#define nocrmode() ((bizarre=1),_tty.c_lflag |= ICANON,_tty.c_cc[VEOF] = CEOF,ioctl(_tty_ch,TCSETAF,&_tty))
X#define echo()	 ((bizarre=1),_tty.c_lflag |= ECHO, ioctl(_tty_ch, TCSETAW, &_tty))
X#define noecho() ((bizarre=1),_tty.c_lflag &=~ECHO, ioctl(_tty_ch, TCSETAW, &_tty))
X#define nl()	 ((bizarre=1),_tty.c_iflag |= ICRNL,_tty.c_oflag |= ONLCR,ioctl(_tty_ch, TCSETAW, &_tty))
X#define nonl()	 ((bizarre=1),_tty.c_iflag &=~ICRNL,_tty.c_oflag &=~ONLCR,ioctl(_tty_ch, TCSETAW, &_tty))
X#define	savetty() (ioctl(_tty_ch, TCGETA, &_oldtty),ioctl(_tty_ch, TCGETA, &_tty))
X#define	resetty() ((bizarre=0),ioctl(_tty_ch, TCSETAF, &_oldtty))
X#define unflush_output()
X
X#else
X
X#define raw()	 ((bizarre=1),_tty.sg_flags|=RAW, stty(_tty_ch,&_tty))
X#define noraw()	 ((bizarre=1),_tty.sg_flags&=~RAW,stty(_tty_ch,&_tty))
X#define crmode() ((bizarre=1),_tty.sg_flags |= CBREAK, stty(_tty_ch,&_tty))
X#define nocrmode() ((bizarre=1),_tty.sg_flags &= ~CBREAK,stty(_tty_ch,&_tty))
X#define echo()	 ((bizarre=1),_tty.sg_flags |= ECHO, stty(_tty_ch, &_tty))
X#define noecho() ((bizarre=1),_tty.sg_flags &= ~ECHO, stty(_tty_ch, &_tty))
X#define nl()	 ((bizarre=1),_tty.sg_flags |= CRMOD,stty(_tty_ch, &_tty))
X#define nonl()	 ((bizarre=1),_tty.sg_flags &= ~CRMOD, stty(_tty_ch, &_tty))
X#define	savetty() (gtty(_tty_ch, &_tty), _res_flg = _tty.sg_flags)
X#define	resetty() ((bizarre=0),_tty.sg_flags = _res_flg, stty(_tty_ch, &_tty))
X#endif /* TERMIO */
X
X#ifdef TIOCSTI
X#ifdef lint
X#define forceme(c) ioctl(_tty_ch,TIOCSTI,Null(long*))	/* ghad! */
X#else
X#define forceme(c) ioctl(_tty_ch,TIOCSTI,c) /* pass character in " " */
X#endif /* lint */
X#else
X#define forceme(c)
X#endif
X
X/* termcap stuff */
X
X/*
X * NOTE: if you don't have termlib you'll have to define these strings,
X *    the tputs routine, and the tgoto routine.
X * The tgoto routine simply produces a cursor addressing string for a given
X * x and y.  The 1st argument is a generic string to be interpreted.
X * If you are hardwiring it you might just ignore the 1st argument.
X * The tputs routine interprets any leading number as a padding factor, possibly
X * scaled by the number of lines (2nd argument), puts out the string (1st arg)
X * and the padding using the routine specified as the 3rd argument.
X */
X
X#ifdef HAVETERMLIB
XEXT char *BC INIT(Nullch);		/* backspace character */
XEXT char *UP INIT(Nullch);		/* move cursor up one line */
XEXT char *myUP;
XEXT char *ND INIT(Nullch);		/* non-destructive cursor right */
XEXT char *myND;
XEXT char *DO INIT(Nullch);		/* move cursor down one line */
XEXT char *myDO;
XEXT char *CR INIT(Nullch);		/* get to left margin, somehow */
XEXT char *VB INIT(Nullch);		/* visible bell */
XEXT char *CL INIT(Nullch);		/* home and clear screen */
XEXT char *CE INIT(Nullch);		/* clear to end of line */
XEXT char *CM INIT(Nullch);		/* cursor motion -- PWP */
XEXT char *HO INIT(Nullch);		/* home cursor -- PWP */
XEXT char *CD INIT(Nullch);		/* clear to end of display -- PWP */
XEXT char *SO INIT(Nullch);		/* begin standout mode */
XEXT char *SE INIT(Nullch);		/* end standout mode */
XEXT int SG INIT(0);		/* blanks left by SO and SE */
XEXT char *US INIT(Nullch);		/* start underline mode */
XEXT char *UE INIT(Nullch);		/* end underline mode */
XEXT char *UC INIT(Nullch);		/* underline a character, if that's how it's done */
XEXT int UG INIT(0);		/* blanks left by US and UE */
XEXT bool AM INIT(FALSE);		/* does terminal have automatic margins? */
XEXT bool XN INIT(FALSE);		/* does it eat 1st newline after automatic wrap? */
XEXT char PC INIT(0);		/* pad character for use by tputs() */
XEXT short ospeed INIT(0);	/* terminal output speed, for use by tputs() */
XEXT int LINES INIT(0), COLS INIT(0);	/* size of screen */
XEXT int just_a_sec INIT(960);			/* 1 sec at current baud rate */
X					/* (number of nulls) */
XEXT char ERASECH;		/* rubout character */
XEXT char KILLCH;		/* line delete character */
X
X/* define a few handy macros */
X
X#define clear() (do_tc(CL,LINES),real_y=real_x=0)
X#define erase_eol() do_tc(CE,1)
X#define backspace() (do_tc(BC,0),real_x--)
X#define clear_rest() do_tc(CD,LINES)
X#define underline() do_tc(US,1)
X#define un_underline() do_tc(UE,1)
X#define underchar() do_tc(UC,0)
X#define standout() do_tc(SO,1)
X#define un_standout() do_tc(SE,1)
X#define up_line() do_tc(UP,1)
X#define carriage_return() do_tc(CR,1)
X#define dingaling() do_tc(VB,1)
X#else
X  ????????		/* up to you */
X#endif
X
Xvoid	term_init();
Xvoid	term_set();
X#ifdef PUSHBACK
Xvoid	pushchar();
Xvoid	mac_init();
Xvoid	mac_line();
X#endif
Xvoid	eat_typeahead();
Xvoid	settle_down();
X#ifndef read_tty
X    int		read_tty();
X#endif
Xvoid	getcmd();
X
Xint read_nd();
Xvoid page();
Xvoid move();
Xvoid do_tc();
Xint comp_tc();
Xvoid helper();
Xvoid rewrite();
Xchar cmstore();
X
!STUFFY!FUNK!
echo Extracting warp.doc
sed >warp.doc <<'!STUFFY!FUNK!' -e 's/X//'
XWarp is a real-time space war game.  This means that the enemies will keep
Xplaying even when you sit still.  Another peculiarity is that things which
Xblow up can damage other things around them.  Universes above a critical
Xdensity may chain react.
X
XThe game starts at difficulty 1, and gets more difficult with each
Xsucceeding wave, up to difficulty 99.  You're not likely to get that far.
X(Invoking warp with a -b switch causes the difficulty to increase more
Xslowly, but games count only a tenth as much.)  The game starts with
X5 Enterprises and 3 Bases, and you get more for surviving long enough.
XThe game is over when you run out of Enterprises and Bases.
X
XThe object of the game is to get as many points as possible.  This is done
Xby destroying as many enemies as possible.  This is not a trivial task.
XEach wave starts with one Enterprise and one Base, and continues until
Xeither both the Enterprise and Base are destroyed, or all the enemies
X(including any homing torpedoes) are destroyed.  It is possible to abort a
Xwave, but you will be penalized for it.  The game may be saved between waves.
X
XA -x switch causes any saved game to be ignored, and causes the new game
Xnot to be saveable.  Hence it is possible to run test games without
Xinvalidating a currently saved game.
X
XThe game is played in a 23 x 40 double wrap-around universe.  Everybody
X(both you and the enemies) gets the chance to move once every second,
Xunless a -l (low-speed) switch was given or you are under 2400 baud, in
Xwhich case it's every two seconds.  The following symbols are displayed:
X
X				FRIENDS
XE	Enterprise with shields		e	Enterprise without shields
XC	Cloaked E with shields		c	Cloaked E without shields
XB	Base with shields		b	Base without shields
X+	Friendly torpedo		M	Harry Mudd
X
X				ENEMIES
XK	Klingon				G	Gorn
XR	Romulan				A	Apollo
X	Romulan with cloaking device!	&	Space Amoeba Nucleus
XT	Tholian				>,<	Planet crusher
Xx,X	Hostile torpedo			o,O	Homing torpedo
XP	Pirate				M	Harry Mudd
X
X			    MISCELLANEOUS
X*	Star				@	Inhabited star
X|,-,/,\	Web				~	Protoplasm
Xother	Friendly Freighter, for now...
X
XThe following keys control the DIRECTION of your various actions:
X
X	h or 4          left
X	j or 2          down
X	k or 8          up
X	l or 6          right
X	b or 1          down and left
X	n or 3          down and right
X	y or 7          up and left
X	u or 9          up and right
X
X(You will note that the letters are the same as other visual games, and the
Xnumbers are for use with a keypad.)  By themselves, these keys move either
Xthe Enterprise or the Base, whichever is the current vessel.  When shifted,
Xthey fire photon torpedoes in the specified direction from the current
Xvessel.  When used with either the CTRL key or the FUNCT key, phasers
X(turbo-lasers for the Base) are fired in the specified direction.  (CTRL
Xwon't work with numbers, and FUNCT probably doesn't exist on non-TVI
Xterminals.)  When preceded by an 'a', an attractor beam is fired in the
Xspecified direction, and when preceded by an 'r', a repulsor beam is fired.
X
XThese keys have special functions:
X
X	del or %        fire photon torpedoes in every (reasonable) direction
X	s               stop all friendly torpedoes
X	S or 0          stop the Enterprise when in warp mode
X	d               destruct all friendly torpedoes (quite useful)
X	D               destruct the current vessel (commit suicide)
X	i/w             switch to Enterprise and put into impulse/warp mode
X	c/v             switch to Enterprise and put into cloaking/visible mode
X	p		switch to Base (not very mnemonic, but 'b' is taken)
X	o               switch from Enterprise to Base, or vice versa
X	z		zap explosions (multiple zaps extend further) (E only)
X
X	^R              refresh the screen
X	^Z              suspend the game (on a bsd system)
X	q               asks if you want to exit this wave (will not work
X			    within 10 cycles of previous q command)
X	Q		exit this game (not wave)
X	?               display a summary of these commands
X
XThere may be additional commands listed in your terminal's keymap file.
XUnrecognized keystrokes are ignored.  IF YOU FORGET ALL THE OTHER COMMANDS,
XREMEMBER "?", which gives you help.
X
XCommands for moving the Enterprise may operate in one of two ways.  If it
Xis in impulse mode, movement commands affect the position of the ship;
Xif it is in warp mode, movement commands affect the velocity instead.
XThe Base always moves in impulse mode.  Since multiple commands may be
Xentered in one turn (if you can type fast enough), it is possible to jump
Xover things even in impulse mode.  In a crowded universe this may be the
Xonly way to go.
X
X(Actually, motion commands always change the velocity--the actual motion
Xdoes not occur until the next turn.  Impulse mode simply causes the
Xvelocity to be zeroed out at the end of every turn.  Phaser commands, on
Xthe other hand, are executed immediately.  If you want to move and fire a
Xphaser, you must wait for the motion to actually occur before typing the
Xphaser command, or the phaser fires from your old position.  This is a
Xfeature, not a bug, and is intended to reflect reality.  Really.)
X
XIf multiple torpedo launching commands are given in a turn, a single torpedo
Xis launched with extra velocity.  You can thus launch photon torpedoes over
Xobjects in the way, and get them where you want them quickly.  This feature
Xworks well with the destruct button.  Variations on this may be useful
Xagainst the Space Amoeba.
X
XNOTE:  Phasers destroy the target by blasting the projected next location of
Xthe object hit.  This means that if the object hit, be it Klingon, Romulan or
XEnterprise, changes velocity in the same turn, it can elude the effect of
Xthe phaser!  (Note that this also means that if you phaser a Klingon or
Xtorpedo that is about to ram you, you will be phasered as well as he/she/it.
XThis can be embarrassing, not to mention deadly.)  Smart players move
Ximmediately upon phasering something at short range, or whenever they
Xthink they might get phasered (in other words, most of the time).
X
XObjects with larger mass can bounce objects with smaller mass out of the way.
XIn a crowded universe the bouncee can bounce quite a way before finding an
Xempty place to land.  If you let the Tholians fill up the universe with web,
Xso that there is no place to bounce to, the Tholians win that wave.
X
XThe status line across the top gives the current mode, the number of
Xpoints accumulated this wave, the Enterprise's energy and torpedoes, the
XBase's energy and torpedoes, the number of stars, the number of enemies,
Xand the stardate.  You will note that nice things happen to your energy levels
Xwhen you put the Enterprise next to the Base, or the Base next to some stars.
XBad things happen inside an Amoeba.
X
XAn object is destroyed when its energy goes negative, either from a direct
Xhit, or from the blast of the previous turn's explosions.  Enemies and
Xstars start with random amounts of energy.  High energy enemies can go warp
X2.  A Romulan with sufficient energy maintains a cloaking device.  Tholians
Xspin web, Gorns shoot homing torpedoes, and the Planet Crusher munches
Xanything in its way, even Apollo.  Apollo won't let you go unless you kill
Xhim, but he loves you very much and beefs up your shields considerably.
XBoth Apollo and the Planet Crusher recharge themselves, so you must hit
Xthem hard in a single turn to do them in. (Yes, the Planet Crusher must be
Xshot in the mouth--he can only die of gluttony--and he blasts out of his
Xmouth when he dies.)  Tholian web may be crossed only by coasting across it
Xin warp mode, or by blasting it (but web blasts extend twice as far as
Xnormal blasts, so keep your distance).  The Space Amoeba sucks energy and
Xgrows, and you must destroy the nucleus.  Somehow.  There are at least four
Xways.  Phasers won't work on the big ones.
X
XPirates turn inhabited star systems into uninhabited ones.  Even Friendly
XFreighters will take potshots at you if you get them mad enough.
X
XNote that because of the size of the Base's turbo-lasers (the Base does not
Xhave phasers) they cannot shoot anything next to the Base.  (This is why the
XDeath Star died!)  In part, this is to protect the Enterprise.  It also lets
Xyou shoot over one adjacent star.  The Enterprise's phasers will shoot over
Xa arbitrary number of adjacent, contiguous stars, including inhabited ones.
XPhasers die away with distance, so don't expect them to kill everything with
Xone blow.
X
XWhile the Enterprise's shields are up (when it is displayed as "E" rather
Xthan "e"), hits on it count only a fifth as much (or even less if you are
Xmoving in warp mode).  The shields are automatically maintained as long as
Xthere are more than 500 units of energy for the Enterprise.  The Base also
Xhas shields, which stay up as long as it has at least 1000 units of energy.
X
XAside from losing energy, the Enterprise can also take damage, either random
Xdamage from getting blasted, or specific damage when a system is in use
Xand breaks down under the load.  In place of the score you will see the
XEstimated Time to Repair.  Sometimes docking helps to get things fixed faster.
XIf you lose both your warp and impulse engines, try the tractors.  The
XBase doesn't take damage because it has much more redundancy than the
XEnterprise.
X
XYou get points for destroying enemies and hostile torpedoes.  At the end of
Xa wave, you also get bonus points for saving stars, saving the Enterprise
Xand Base, and for having an efficiency rating higher that 0.8.  You get
XNEGATIVE bonus points for letting friendly life forms get blown up, and for
Xgiving up.  Bonuses tend to be scaled by the ratio of the number of points
Xyou got over the number of points you could have got.  If you think you are
Xdone with a wave, but it won't quit, there may be homing torpedoes that you
Xhaven't destroyed--you must make the universe safe for posterity, you know.
X
XWhen you have used up your Enterprises and Bases (or quit), your score will
Xbe posted to the scoreboard.  You may see the scoreboard outside of the game
Xsimply by giving the command "warp -s".
X
XIf you get bored, you can always play with some of the undocumented switches
Xthat are used to test warp.  Such funny games go on their own scoreboard.
XFor kicks try "warp -x -d50 -C -\& -G -T -E400 -S5" and then go hide.  Quick.
X
!STUFFY!FUNK!
echo Extracting score.h
sed >score.h <<'!STUFFY!FUNK!' -e 's/X//'
X/* $Header: score.h,v 7.0 86/10/08 15:13:21 lwall Exp $ */
X
X/* $Log:	score.h,v $
X * Revision 7.0  86/10/08  15:13:21  lwall
X * Split into separate files.  Added amoebas and pirates.
X * 
X */
X
X#define ENTBOUNDARY 100000	/*  point boundary across which a new E is
X					awarded */
X
X#define BASEBOUNDARY 250000	/*  point boundary across which a new B is
X					awarded */
X
XEXT int oldstatus;
XEXT int oldetorp;
XEXT int oldbtorp;
XEXT int oldstrs;
XEXT int oldenemies;
X
XEXT long totalscore;
XEXT long lastscore INIT(0);
XEXT long curscore;
XEXT long possiblescore;
XEXT long oldeenergy;
XEXT long oldbenergy;
XEXT long oldcurscore;
X
XEXT char savefilename[40];
X
X#ifdef SCOREFULL
X#define COMPOFF 0
X#define COMPNAME longlognam
X#define COMPLEN 24
X#else
X#define COMPOFF 24
X#define COMPNAME longlognam
X#define COMPLEN 8
X#endif
XEXT char longlognam[128];
X
XEXT char c INIT(' ');
X
Xvoid score_init();
Xvoid wscore();
Xvoid display_status();
Xvoid wavescore();
Xvoid score();
Xvoid save_game();
!STUFFY!FUNK!
echo ""
echo "End of kit 4 (of 7)"
cat /dev/null >kit4isdone
config=true
for iskit in 1 2 3 4 5 6 7; do
    if test -f kit${iskit}isdone; then
	echo "You have run kit ${iskit}."
    else
	echo "You still need to run kit ${iskit}."
	config=false
    fi
done
case $config in
    true)
	echo "You have run all your kits.  Please read README and then type Configure."
	chmod 755 Configure
	;;
esac
: Someone might mail this, so...
exit