[net.sources.games] search -- part 5 of 6

matt@oddjob.UUCP (Matt Crawford) (08/11/85)

: This is a shar archive.  Extract with sh, not csh.
echo x - init.c
sed -e 's/^X//' > init.c << '!xxENDITxx!'
X#ifndef lint
Xstatic char rcsid[] = "$Header: init.c,v 2.2 85/08/06 22:29:44 matt Exp $";
X#endif
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Greg Ordy	1979
X * Rewrite by Sam Leffler	1981
X * Socket code by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * routines to initialize the search databases and to
X * open needed files
X *
X * Copyright (c) 1979
X *
X * $Log:	init.c,v $
X * Revision 2.2  85/08/06  22:29:44  matt
X * Change handling of "r", "b", "g", "j", "q" commands to
X * provide better feedback, using per-player message buffer.
X * 
X * Revision 2.1  85/04/10  17:31:03  matt
X * Major de-linting and minor restructuring.
X * 
X * Revision 1.2  85/02/11  12:43:47  matt
X * added GUTS mode
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/file.h>
X#include <signal.h>
X
X#include "defines.h"
X#include "structs.h"
X
X/*
X * initialize all the databases for search
X */
X
Xvoid init() {
X	extern	time_t	time();
X	extern	int	trap(),
X			core_dump(),
X			srand(),
X			rand();
X	extern	long	lseek();
X	extern	t_player player[NPLAYER];
X	extern	t_alien alien[NALIEN];
X	extern	t_sbase sbase[NBASE];
X	extern	t_planet planet;
X	extern	int pfd,
X		nplayer,
X		sfflag,
X		errfile,
X		sfcount;
X	extern	char ppx,
X		ppy;
X	void	initplayer();
X	register t_alien *pa;
X	register t_sbase *ps;
X	register int i;
X	time_t	tvec;
X	char	buf[100];
X
X	(void) signal(SIGHUP, SIG_IGN);
X	(void) signal(SIGQUIT, core_dump);
X	(void) signal(SIGINT, trap);
X	(void) signal(SIGALRM, SIG_IGN);
X	(void) signal(SIGPIPE, SIG_IGN);
X	(void) signal(SIGSTOP, SIG_IGN);
X	(void) signal(SIGTSTP, SIG_IGN);
X	(void) signal(SIGTERM, SIG_IGN);
X	/*
X	 * clear everything out
X	 */
X	bzero((char *)player, sizeof(t_player) * NPLAYER);
X	pfd = open(POINTFILE, O_RDWR, 0);
X	if (pfd < 0) {
X		perror(POINTFILE);
X		exit(1);
X	}
X	/*
X	 * no big deal if we can't open the error log
X	 */
X	errfile = open(ERRLOG, O_RDWR|O_CREAT, 0666);
X	if (errfile >= 0) {
X		lseek(errfile, 0L, 2);
X		sprintf(buf, "starting daemon, pid %d\n", getpid());
X		errlog(buf);
X	}
X	tvec = time((time_t *)0);
X	srand(tvec);
X	nplayer = 0;
X	/*
X	 * Setup aliens with random locations and random directions.
X	 */
X	for (pa = alien; pa < &alien[NALIEN]; pa++) {
X		pa->cx = (rand()%80)+20;
X		pa->cy = (rand()%50)+25;
X		pa->cix = (rand()%3)-1;
X		pa->ciy = (rand()%3)-1;
X		if (pa->ciy == 0 && pa->cix == 0)
X			pa->cix = pa->ciy = 1;
X		pa->aname = NAMEAL;
X		pa->type = NORM;
X	}
X	/*
X	 * Add in the shankers.
X	 */
X	for (pa = alien; pa < &alien[NSHANK]; pa++) {
X		pa->type = SHANK;
X		pa->count = (rand()%30)+15;	/* shanker alarm clock */
X	}
X	/*
X	 * Some others are the wandering type.
X	 */
X	for (; pa < &alien[NSHANK+NWAND]; pa++) {
X		pa->type = WANDER;
X		pa->aname = NAMEWD;
X		pa->count = (rand()%32)+16;
X	}
X	/*
X	 * Star bases get random places also -- but spread out.
X	 */
X	for (ps = sbase, i = 0; i != NBASE - 1; i++, ps++) {
X		ps->xpos = ((rand()%50)+(25*(i+1))%120)+3;
X		ps->ypos = ((rand()%50)+(25*(i+1))%120)+3;
X	}
X	/*
X	 * Build quartone.
X	 */
X	planet.planetname = "Quartone";
X	planet.places[0][0] = -((rand()%30)+30);
X	planet.places[0][1] = -((rand()%30)+30);
X	for (i = 0; i != 5; i++) {
X		planet.places[i][1] = planet.places[0][1];
X		planet.places[i][0] = planet.places[0][0]+i;
X	}
X	for (i = 5; i != 12; i++) {
X		planet.places[i][1] = planet.places[0][1]-1;
X		planet.places[i][0] = planet.places[0][0]+i-6;
X	}
X	for (i = 12; i != 17; i++) {
X		planet.places[i][1] = planet.places[0][1]-2;
X		planet.places[i][0] = planet.places[0][0]+i-12;
X	}
X	ppx = planet.places[8][0];
X	ppy = planet.places[8][1];
X
X	sbase[NBASE-1].xpos = ppx-(rand()%20)-4;
X	sbase[NBASE-1].ypos = ppy-(rand()%20)-4;
X	/*
X	 * Solar flare alarm clock....
X	 */
X	sfcount = 800+(rand()%100);
X	sfflag = OFF;
X}
X
Xstruct initlist {
X	char	x;
X	char	y;
X	char	*output;
X} initlist[] = {
X	{ XAXISTITLE, "--------------- ---------------" },
X	{ POSTITLE, "POSITION" },
X	{ EGYTITLE, "ENERGY" },
X	{ HRTITLE, "HOMING RADAR" },
X	{ H1TITLE, "1) " },
X	{ H2TITLE, "2) " },
X	{ H3TITLE, "3) " },
X	{ PTTITLE, "POINTS" },
X	{ STTITLE, "STATUS: " },
X	{ MSTITLE, "MESSAGE: " },
X	{ INTITLE, "INVISIBILTY" },
X	{ VLTITLE, "VELOCITY" },
X	{ TMTITLE, "TIME" },
X	{ MFTITLE, "M-FACTOR" },
X	{ PLTITLE, "----- PLAYER MAP ----" },
X	{ 0, 0, 0 }
X};
X
Xvoid initplayer(p)
Xregister t_player *p;
X{
X	extern	void	bflush(),
X			clear(),
X			cput(),
X			initpdisplay(),
X			pldisplay();
X	register int j;
X	register struct initlist *pi = initlist;
X
X	p->eoq = p->outputq;
X	*p->eoq = NULL;
X	clear(p);
X	for (j = CENTY; j < XWIND; j++)
X		cput(YAXISTITLE, j, p, "|");
X	while (pi->x) {
X		cput(pi->x, pi->y, p, pi->output);
X		pi++;
X	}
X	cput(EGYDATA, p, "%d", p->energy);
X	cput(PTDATA, p, "%d", p->points);
X	cput(INDATA, p, p->status.invis == TRUE ? "on " : "off");
X	cput(MFDATA, p, "%c", p->mflg+'0');
X	initpdisplay(p);
X	pldisplay(p, "a");
X	p->plstp = 0;
X	bflush(p);
X}
X
X/*
X * initializes player stuff
X */
Xt_player *startup(sock, fileform)
Xint sock;
Xt_file *fileform;
X{
X	extern	void	makescab();
X	extern	char	*strncpy();
X	extern	t_player player[NPLAYER];
X	extern	char ppx, ppy;
X	extern	long ptime;
X	extern	int  gutsflag;
X	register t_player *p;
X
X	for (p = player; p < &player[NPLAYER]; p++)
X		if (p->status.alive == FALSE)
X			break;
X	/*
X	 * too many players in the game.
X	 */
X	if (p >= &player[NPLAYER]) {
X		(void) shutdown(sock, 2);
X		(void) close(sock);
X		return(NULL);
X	}
X	/*
X	 * clear out everything.
X	 */
X	bzero((char *)p, sizeof(*p));
X	p->socket = sock;
X	if (p->socket < 0 || !ioinit(p, fileform)) {
X		p->status.alive = FALSE;
X		(void) shutdown(sock, 2);
X		p->socket = -1;
X		(void) close(sock);
X		return(NULL);
X	}
X	p->status.alive = TRUE;
X	p->status.begin = TRUE;
X	p->status.guts  = gutsflag;
X	p->curx = ppx+(rand()%10)+5;
X	p->cury = ppy+(rand()%10)+5;
X	p->mflg = 1;
X	p->pltime = ptime;
X	p->maxe = p->energy = 250;
X	(void) strncpy(p->plname, fileform->p_name, sizeof(p->plname)-1);
X	return(p);
X}
!xxENDITxx!
echo x - util.c
sed -e 's/^X//' > util.c << '!xxENDITxx!'
X#ifndef lint
Xstatic char rcsid[] = "$Header: util.c,v 2.2 85/08/06 22:29:53 matt Exp $";
X#endif
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Greg Ordy	1979
X * Rewrite by Sam Leffler	1981
X * Socket code by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * utility routines
X *
X * Copyright (c) 1979
X *
X * $Log:	util.c,v $
X * Revision 2.2  85/08/06  22:29:53  matt
X * Change handling of "r", "b", "g", "j", "q" commands to
X * provide better feedback, using per-player message buffer.
X * 
X * Revision 2.1  85/04/10  17:32:11  matt
X * Major de-linting and minor restructuring.
X * 
X * Revision 1.4  85/02/24  22:52:07  matt
X * Make the select() polls into real polls by setting the timeouts
X * to zero.  This cuts down on context switches and speeds the game
X * up IMMENSELY!
X * 
X * Revision 1.3  85/02/11  12:44:13  matt
X * added GUTS mode
X * 
X * Revision 1.2  85/02/09  23:50:55  matt
X * Eliminated the dependence on the value of the mask after
X * select() times out.  Use the return value to distinguish
X * a timeout!!
X * 
X */
X
X#include <stdio.h>
X#include <sys/time.h>
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <signal.h>
X#include <signal.h>
X
X#include "defines.h"
X#include "structs.h"
X
X/*
X * Out of energy, out of game...
X */
Xvoid
Xoutgame(p)
Xregister t_player *p;
X{
X	extern	void pstatus();
X	void	done();
X
X	p->status.alive = FALSE;
X	pstatus(p, "Out of energy, out of game!");
X	p->status.killed = TRUE;
X	done(p);
X}
X
X
X/*
X * Cleanup after player leaves...
X */
Xvoid
Xdone(p)
Xregister t_player *p;
X{
X	extern	void	bflush(),
X			cput(),
X			fnode(),
X			pldisplay(),
X			putplayer();
X	extern	t_player	player[NPLAYER];
X	extern	char	visual[NPLAYER][NPLAYER];
X	extern	t_player	*whoscab;
X	extern	int	dtabsiz,	nplayer;
X	register	t_player	*pl;
X	register	int	i,	j;
X	struct	timeval delay;
X	char	junkbuf[4096];
X	int	mask,	y;
X
X	nplayer--;
X	p->status.alive = FALSE;
X	cput(PTDATA, p, "%d", p->points);
X	move(0, 23, p);		/* lower left hand corner? */
X	bflush(p);
X	mask = 1 << p->socket;
X	delay.tv_sec = delay.tv_usec = 0L;
X	/*
X	 * close down the socket:
X	 * send an out-of-band message to the player,
X	 * stop any more writes to the socket,
X	 * read all the muck that's accumulated,
X	 * then shut it down for good.
X	 */
X	(void) send(p->socket, "d", 1, MSG_OOB);	/* d for die */
X	(void) shutdown(p->socket, 1);
X	i = select(dtabsiz, &mask, NULLINT, NULLINT, &delay);
X	if (i > 0)
X		(void) read(p->socket, junkbuf, sizeof(junkbuf));
X	(void) shutdown(p->socket, 2);
X	(void) close(p->socket);
X	p->socket = -1;
X	j = p-player;
X	for (i=0,pl=player; i<NPLAYER; i++,pl++) {
X		visual[i][j] = visual[j][i] = 0;
X		if (pl->status.alive == FALSE)
X			continue;
X		for (y = 0; y != 3; y++)
X			if (pl->home[y] == (thing *)p)
X				pl->home[y] = NOTHING;
X	}
X	if (whoscab == p)
X		whoscab = NOBODY;
X	(void) putplayer(p);
X	(void) fnode(p->plstp);
X	(void) pldisplay(p, p->status.killed ? "d" : "q");
X}
X
X/*
X * Time for a solar flare...
X */
Xvoid makeflare() {
X	extern	t_player player[NPLAYER];
X	extern	int sfflag,
X		gutsflag,
X		sfcount,
X		nplayer,
X		TDIST;
X	extern	int rand();
X	extern	void seeall();
X
X	if (sfflag == ON) {
X		sfcount = 500+(rand()%128);
X		sfflag = OFF;
X		TDIST = TSIZE-(2*nplayer);
X		return;
X	}
X	sfcount = 30+(rand()%100);
X	sfflag = ON;
X	if (!gutsflag)
X		seeall("\07From radar-- Solar flare starting!!!");
X}
X
X/*
X * Autopilot update routine
X */
Xvoid apilot(p)
Xregister t_player *p;
X{
X	extern	void cput();
X	register char dx,
X		dy;
X	int	xplus,
X		yplus;
X
X	dx = *(p->apx) - p->curx;
X	dy = *(p->apy) - p->cury;
X	if (dx == 0 && dy == 0) {
X		cput(VLDATAX, VLDATAY, p, "%d %d\07", 0, 0);
X		p->status.ap = FALSE;
X	}
X	xplus = dx < 3 && dx > -3 ? 1 : 2;
X	yplus = dy < 3 && dy > -3 ? 1 : 2;
X	p->offx = dx < 0 ? -xplus : dx > 0 ? xplus : 0;
X	p->offy = dy < 0 ? -yplus : dy > 0 ? yplus : 0;
X	p->energy++;
X}
X
X/*
X * errlog logs the errors found by other routines.
X * this is needed since the main program closes stdout
X * so we need to print out what's wrong into a file.
X *
X * Of course, if errlog isn't opened, then we'll never see
X * anything bad (except a core-dump of searchd).
X */
X
Xerrlog(msg)
Xchar *msg;
X{
X	extern	int	errfile;
X	extern	long	lseek();
X
X	if (errfile < 0) {
X		signal(SIGQUIT, SIG_DFL);
X		kill(getpid(), SIGQUIT);
X	}
X	(void)lseek(errfile, 0L, 2);
X	write(errfile, msg, strlen(msg));
X}
X
X/*
X * seeall makes everyone visible and sends them all the argument
X * string as a message.  This is used by makeflare and when
X * entering guts mode.
X */
Xvoid seeall(msg)
Xchar	*msg;
X{
X	extern	t_player player[NPLAYER];
X	extern	void cput(),
X		pmesg();
X	register t_player *p;
X
X	for (p = player; p < &player[NPLAYER]; p++) {
X		if (p->status.alive == FALSE)
X			continue;
X		cput(INDATA, p, "off");
X		pmesg(p, msg);
X		p->status.invis = FALSE;
X	}
X}
!xxENDITxx!
echo x - io.c
sed -e 's/^X//' > io.c << '!xxENDITxx!'
X#ifndef lint
Xstatic char rcsid[] = "$Header: io.c,v 2.1 85/04/10 17:31:07 matt Stab $";
X#endif
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Sam Leffler	1981
X * Socket code by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * routines for termcap interface and general i/o support
X * Changes were made to the original code to minimize
X * the total number of "write" calls to the sockets
X * (an attempt to increase performance)
X *
X * Copyright (c) 1981
X *
X */
X
X#include "defines.h"
X#include "structs.h"
X
X
X/*
X * Goto <x, y> on who's terminal and put
X */
X/*VARARGS3*/
Xvoid cput(x, y, p, args)
Xint x, y;
Xt_player *p;
Xint args;
X{
X	char	*print();
X	register char *bp;
X	register char *qp;
X	register c;
X
X	move(x, y, p);
X	bp = print(&args);
X	for (qp=p->eoq; c = *bp; bp++) {
X		*qp = c;
X		qp++;
X	}
X	*qp = NULL;
X	p->eoq = qp;
X}
X
X/*
X * clear screen
X */
Xvoid clear(p)
Xt_player *p;
X{
X	register char *bp;
X	register char *qp;
X	register c;
X
X	bp = p->CL;
X	for (qp=p->eoq; c = *bp; bp++) {
X		*qp = c;
X		qp++;
X	}
X	*qp = NULL;
X	p->eoq = qp;
X}
X
X
X/*
X * move to <x, y>
X */
Xmove(x, y, p)
Xint x;
Xint y;
Xt_player *p;
X{
X	extern	char *tgoto();
X	register char *bp;
X	register char *qp;
X	register c;
X
X	bp = tgoto(p, x, y);
X	for (qp=p->eoq; c = *bp; bp++) {
X		*qp = c;
X		qp++;
X	}
X	*qp = NULL;
X	p->eoq = qp;
X}
X
X/*
X * Do the put, but make sure it occupies the entire line -- for
X *  status and message lines
X */
Xvoid /*VARARGS1*/
Xputblank(p, args)
Xregister t_player *p;
Xint *args;
X{
X	char	*print();
X	register char *bp;
X	register int n;
X	register char *qp;
X	register c;
X
X	qp = p->eoq;
X	if (p->CE) {	/* cheat clear out line first */
X		bp = p->CE;
X		for (qp=p->eoq; c = *bp; bp++) {
X			*qp = c;
X			qp++;
X		}
X		*qp = NULL;
X		p->eoq = qp;
X		bp = print(args);
X	} else {	/* have to overwrite line, then clear out remainder */
X		bp = print(args);
X		n = strlen(bp);
X		while (n++ < 40)	/* kludge for now */
X			bp[n] = ' ';
X		bp[40] = NULL;
X	}
X	for (qp=p->eoq; c = *bp; bp++) {
X		*qp = c;
X		qp++;
X	}
X	*qp = NULL;
X	p->eoq = qp;
X}
X
X/*
X * Print something on the message line
X */
X/*VARARGS1*/
Xvoid pmesg(p, args)
Xt_player *p;
Xint args;
X{
X	move(MSDATAX, MSDATAY, p);
X	putblank(p, &args);
X}
X
X
X/*
X * Drop something on the prompt line
X */
X/*VARARGS1*/
Xvoid prompt(p, s)
Xt_player *p;
Xchar *s;
X{
X	move(PROMPTX, PROMPTY, p);
X	putblank(p, &s);
X}
X
X/*
X * Print something on the status line
X */
X/*VARARGS1*/
Xvoid pstatus(p, args)
Xt_player *p;
Xint args;
X{
X	move(STDATAX, STDATAY, p);
X	putblank(p, &args);
X}
X
X/*
X * Clear out the rest of the line from where the cursor is
X *  presently located -- easy if CE exists on this terminal
X */
Xvoid clearline(p)
Xregister t_player *p;
X{
X	register char *bp;
X	register char *qp;
X	register c;
X
X	bp = p->CE;
X	if (bp == NULL)
X		return;
X	for (qp=p->eoq; c = *bp; bp++) {
X		*qp = c;
X		qp++;
X	}
X	*qp = NULL;
X	p->eoq = qp;
X}
X
X
X/*
X * Print write around
X */
X/*VARARGS1*/
Xvoid put(p, args)
Xt_player *p;
Xint args;
X{
X	char	*print();
X	register char *bp;
X	register char *qp;
X	register c;
X
X	bp = print(&args);
X	for (qp=p->eoq; c = *bp; bp++) {
X		*qp = c;
X		qp++;
X	}
X	*qp = NULL;
X	p->eoq = qp;
X}
X
X
Xstatic char printbuf[80];
Xstatic char *bufp;
X
X/*
X * Guts of the I/O...a hacked printf-like beast?
X */
Xstatic	char *print(parg)
Xregister int *parg;	/* should be a union, or something */
X{
X	void	printn();
X	register char *fmt = (char *)(*parg++);
X	register c;
X	register char *bp;
X
X	bufp = printbuf;
X	while (c = *fmt++) {
X		if (c == '%') switch(c = *fmt++) {
X			case 'd':	/* decimal */
X				printn(*parg++, 10, 4);
X				continue;
X			case 'c':	/* character */
X				*bufp++ = (char)(*parg++); 
X				continue;
X			case 's':	/* string */
X				bp = (char *)(*parg++);
X				for ( ; c = *bp; bp++) {
X					*bufp = c;
X					bufp++;
X				}
X				continue;
X			case '%':
X				*bufp++ = '%';
X				continue;
X			default:
X				*bufp++ = '%';
X		}
X		*bufp++ = c;
X	}
X	*bufp = NULL;
X	return printbuf;
X}
X
X
X/*
X * Handle number conversions...everything takes up "width" spaces
X */
Xstatic	void printn(n, base, width)
Xregister int n, base;
Xint width;
X{
X	void	putn();
X	char	*before;
X
X	before = bufp;
X	if (base == 10 && n < 0) {
X		*bufp++ = '-';
X		n = abs(n);
X	} else
X		*bufp++ = ' ';
X	if (n == 0)
X		*bufp++ = '0';
X	else
X		putn(n, base);
X	n = bufp - before;
X	while (n++ < width)
X		*bufp++ = ' ';
X}
X
X
X/*
X * Recursive number constructor
X */
Xstatic	void putn(n, b)
Xregister int n, b;
X{
X	if (n == 0)
X		return;
X	putn(n/b, b);
X	*bufp++ = "0123456789abcdef"[n%b];
X}
X
X
X/*
X * Flush the output buffer to "p"s terminal
X */
Xvoid bflush(p)
Xregister t_player *p;
X{
X	int	i;
X
X	i = strlen(p->outputq);
X	if (i == 0)
X		return;
X	(void) write(p->socket, p->outputq, i);
X	p->eoq = p->outputq;
X	*p->eoq = NULL;
X}
X
X
X/*
X * Set up the termcap stuff in the player structure
X */
Xint ioinit(p, pf)
Xregister t_player *p;
Xregister t_file *pf;
X{
X	extern	char *malloc();
X	char	*copy();
X	register unsigned	nalloc;
X	register char	*cp;
X
X	nalloc = strlen(pf->p_BC)+strlen(pf->p_UP)+ strlen(pf->p_CM)+
X		 strlen(pf->p_CL)+strlen(pf->p_CE)+5;
X	nalloc += nalloc % 2;
X	if ((cp = malloc(nalloc)) == (char *)-1)
X		return(0);
X	p->BC = cp;
X	p->UP = cp = copy(cp, pf->p_BC);
X	p->CM = cp = copy(cp, pf->p_UP);
X	p->CL = cp = copy(cp, pf->p_CM);
X	p->CE = cp = copy(cp, pf->p_CL);
X	(void)copy(cp, pf->p_CE);
X	p->ttyspeed = pf->p_speed;
X	return(1);
X}
X
Xstatic	char *
Xcopy(s1, s2)
Xregister char *s1, *s2;
X{
X	while (*s1++ = *s2++)
X		;
X	return s1;
X}
!xxENDITxx!
echo x - tgoto.c
sed -e 's/^X//' > tgoto.c << '!xxENDITxx!'
X#ifndef lint
Xstatic char rcsid[] = "$Header: tgoto.c,v 2.1 85/04/10 17:32:07 matt Stab $";
X#endif
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Greg Ordy	1979
X * Rewrite by Sam Leffler	1981
X * Socket code by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * routine to perform cursor addressing.
X *
X * Copyright (c) 1979
X *
X */
X
X#define	CTRL(c)	('c' & 037)
X
X#include "defines.h"
X#include "structs.h"
X
X/*
X * CM is a string containing printf type escapes to allow
X * cursor addressing.  We start out ready to print the destination
X * line, and switch each time we print row or column.
X * The following escapes are defined for substituting row/column:
X *
X *	%d	as in printf
X *	%2	like %2d
X *	%3	like %3d
X *	%.	gives %c hacking special case characters
X *	%+x	like %c but adding x first
X *
X *	The codes below affect the state but don't use up a value.
X *
X *	%>xy	if value > x add y
X *	%r	reverses row/column
X *	%i	increments row/column (for one origin indexing)
X *	%%	gives %
X *	%B	BCD (2 decimal digits encoded in one byte)
X *	%D	Delta Data (backwards bcd)
X *
X * all other characters are ``self-inserting''.
X */
Xchar *tgoto(p, destcol, destline)
Xregister t_player *p;
Xint destcol, destline;
X{
X	extern	char	*strcat(), *strcpy();
X	static	char	result[16];
X	static	char	added[10];
X	register	char	*dp = result;
X	register	int	c;
X	register	int	which = destline;
X	char	*cp = p->CM;
X	int	oncol = 0;
X
X	if (cp == 0) {
Xtoohard:
X		/*
X		 * "We don't do that under BOZO's big top"
X		 */
X		return ("OOPS");
X	}
X	added[0] = 0;
X	while (c = *cp++) {
X		if (c != '%') {
X			*dp++ = c;
X			continue;
X		}
X		switch (c = *cp++) {
X
X#ifdef CM_N
X		case 'n':
X			destcol ^= 0140;
X			destline ^= 0140;
X			goto setwhich;
X#endif
X
X		case 'd':
X			if (which < 10)
X				goto one;
X			if (which < 100)
X				goto two;
X			/* fall into... */
X
X		case '3':
X			*dp++ = (which / 100) | '0';
X			which %= 100;
X			/* fall into... */
X
X		case '2':
Xtwo:	
X			*dp++ = which / 10 | '0';
Xone:
X			*dp++ = which % 10 | '0';
Xswap:
X			oncol = 1 - oncol;
Xsetwhich:
X			which = oncol ? destcol : destline;
X			continue;
X
X#ifdef CM_GT
X		case '>':
X			if (which > *cp++)
X				which += *cp++;
X			else
X				cp++;
X			continue;
X#endif
X
X		case '+':
X			which += *cp++;
X			/* fall into... */
X
X		case '.':
X			/*
X			 * This code is worth scratching your head at for a
X			 * while.  The idea is that various weird things can
X			 * happen to nulls, EOT's, tabs, and newlines by the
X			 * tty driver, arpanet, and so on, so we don't send
X			 * them if we can help it.
X			 *
X			 * Tab is taken out to get Ann Arbors to work, otherwise
X			 * when they go to column 9 we increment which is wrong
X			 * because bcd isn't continuous.  We should take out
X			 * the rest too, or run the thing through more than
X			 * once until it doesn't make any of these, but that
X			 * would make termlib (and hence pdp-11 ex) bigger,
X			 * and also somewhat slower.  This requires all
X			 * programs which use termlib to stty tabs so they
X			 * don't get expanded.  They should do this anyway
X			 * because some terminals use ^I for other things,
X			 * like nondestructive space.
X			 */
X			if (which == 0 || which == CTRL(d) || which == '\t' || which == '\n') {
X				if (oncol || p->UP) /* Assumption: backspace works */
X					/*
X					 * Loop needed because newline happens
X					 * to be the successor of tab.
X					 */
X					do {
X						(void)strcat(added, oncol ? (p->BC ? p->BC : "\b") : p->UP);
X						which++;
X					} while (which == '\n');
X			}
X			*dp++ = which;
X			goto swap;
X
X		case 'r':
X			oncol = 1;
X			goto setwhich;
X
X		case 'i':
X			destcol++;
X			destline++;
X			which++;
X			continue;
X
X		case '%':
X			*dp++ = c;
X			continue;
X
X#ifdef CM_B
X		case 'B':
X			which = (which/10 << 4) + which%10;
X			continue;
X#endif
X
X#ifdef CM_D
X		case 'D':
X			which = which - 2 * (which%16);
X			continue;
X#endif
X
X		default:
X			goto toohard;
X		}
X	}
X	(void)strcpy(dp, added);
X	return (result);
X}
!xxENDITxx!
echo x - score.c
sed -e 's/^X//' > score.c << '!xxENDITxx!'
X#ifndef lint
Xstatic char rcsid[] = "$Header: score.c,v 2.1 85/04/10 17:31:40 matt Stab $";
X#endif
X/*
X *
X * search
X *
X * multi-player and multi-system search and destroy.
X *
X * Original by Dave Pare	1983
X * Ported & improved
X *      by Matt Crawford	1985
X *
X * routine to update player scores, formerly handled in
X * search.c, but now moved to the daemon's care.
X *
X * Copyright (c) 1983
X *
X * $Log:	score.c,v $
X * Revision 2.1  85/04/10  17:31:40  matt
X * Major de-linting and minor restructuring.
X * 
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/file.h>
X
X#include "defines.h"
X#include "structs.h"
X
Xvoid putplayer(p)
Xregister t_player *p;
X{
X	extern	long	lseek();
X	extern	char	*strcpy();
X	extern	int	pfd;
X	int	index;
X	int	found;
X	t_totals	entry;
X
X	found = 0;
X	(void)lseek(pfd, 0L, 0);
X	for (index=0; read(pfd, (char *)&entry, sizeof(t_totals)) > 0; index++)
X		if (!strcmp(p->plname, entry.ptname)) {
X			found++;
X			break;
X		}
X	if (!found) {
X		bzero((char *)&entry, sizeof(entry));
X		strcpy(entry.ptname, p->plname);
X	} else
X		(void)lseek(pfd, (long)(index * sizeof(t_totals)), 0);
X	if (p->status.killed == TRUE)
X		entry.ptkilled++;
X	if (entry.ptbest < p->points)
X		entry.ptbest = p->points;
X	entry.ptpoints += p->points;
X	entry.ptgames++;
X	entry.pthits += p->phits;
X	entry.ptkills += p->pkills;
X	entry.ptahits += p->ahits;
X	entry.ptlast = p->points;
X	write(pfd, (char *)&entry, sizeof(t_totals));
X}
!xxENDITxx!