File:  [MW Coherent from dump] / coherent / d / usr / games / pacman / ibmpac.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:38 2019 UTC (7 years, 2 months ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/*
 * pacman
 * dal 1982
 * steve 1/24/90 added ndelay for reasonable slowness on AT
 * steve 10/4/90 kludged to make speed setting slightly more cogent
 * steve 10/9/90 made arrow keys work
 * steve 10/10/90 added -c option to work on video cards
 * steve 6/10/92 added #if _I386 conditionalization for COH386;
 *	cleaned up a few of the more offensive pointer/int fubars of dal.
 *	The i386 version must be setuid sys, so it can read /dev/mem.
 */

#include "term.c"
#include "io.c"

#if	_I386
#define	SCRBASE_M	0xB0000		/* monochrome screen base address */
#define	SCRBASE_C	0xB8000		/* color board screen base address */
#else
#define	SCRBASE_M	0xB000		/* monochrome screen base segment */
#define	SCRBASE_C	0xB800		/* color board screen base segment */
#endif

#define	rand()	((rn+=rn+((((rn<<0^rn<<1^rn<<8^rn<<9)>>15)^1)&1))&1)
int		rn;
#define	track()	(board>1)
#define	nprox()	(board>2? (board-3)/2+5 : 0)
#define	F_VERT	22
#define	F_HORZ	63
#define	F_HHID	2
#define	F_HOFF	((80-F_HORZ)/2)
#define	F_VOFF	((24-F_VERT)/2)
#define	S_BP	10000
#define	S_PN	3
#define	S_GH	200
#define	S_FD	10
#define	S_EN	50
/*
#define	S_FR	(board<5? (board-1)*200+100 : (board-4)*1000)
*/
#define	S_FR	((board-1)*200+100)
#define	F_GH	0
#define	F_PC	4
#define	F_FR	5
#define	F_BN	6
#define	F_FD	7
#define	F_EN	8
#define	F_DR	9
#define	F_TN	10
#define	F_WL	11
#define	F_BC	12
#define	F_BMSK	((1<<F_BC)-1)
#define	F_GMSK	(((1<<F_GH+4)-1)&~((1<<F_GH+0)-1))
#define	G_ETIM	24
#define	G_BTIM	8
#define	G_TMQN	8
#define	G_TOFF(n)	(5+(n)*G_TMQN)
enum	{G_ERAS, G_WRIT, G_MOVE, G_BLUE, G_INIT};
#define	E_TMQN	16
#define	E_TOFF	1
#define	P_TMQN	(9*(2-P_HALF))
#define	P_TOFF	0
enum	{P_ERAS, P_WRIT, P_MOVE, P_UPDI, P_INIT};
#define	axis(v)	((v)&1)
#define	incr(v)	(1-((v)&2))
#define	hm(v)	(axis(v)==0)
#define	vm(v)	(axis(v)!=0)
#define	om(v)	((v)^2)

int		ndelay = 10;
int		limit[2] = {F_HORZ-2, F_VERT-1};
int		edibles;
int		pacmen = S_PN+1;
int		stop;
int		e_s;
long		score;
long		bonus;
int		board = 1;
int		p_p[3];
int		p_h[2];
int		p_l;
int		p_m;
int		p_d;
int		p_i[3];
unsigned	p_n;
unsigned	e_n;
int		e_k;
int		energ[4][2];
int		r_s;
int		r_t[2];
int		r_d;
int		r_p[2];
int		g_g[2][2];
int		g_v[4];
struct	ghost	{
	int		g_p[3];
	int		g_q[3];
	int		g_h[3];
	int		g_s;
	int		g_d;
	int		g_e;
	int		g_f;
	int		g_r;
	int		g_o;
	unsigned 	g_n;
} ghost[4];

#define	D	(1<<F_DR)
#define	E	(1<<F_EN)
#define	F	(1<<F_FD)
#define	G	(1<<F_GH)
#define	P	(1<<F_PC)
#define	R	(1<<F_FR)
#define	T	(1<<F_TN)
#define	W	(1<<F_WL)
int	field[F_VERT][F_HORZ] = {
{W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W},
{W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,W,W},
{W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,0,F,0,W,W},
{W,W,W,W,W,0,E,0,W,W,W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,0,F,0,W,W},
{W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0},
{W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,0,F,0,W,W,W,0,F,0,W,W,W,W,W,W,W,W},
{W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,W,W,W,0,F,0,F,0,F,0,F,0,W,W},
{W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,0,0,0,W,W},
{W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,0,0,0,0,0,0,0,G},
{W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,W,W,W,W,W,W,D,D},
{T,T,T,T,T,T,T,T,T,T,T,T,T,T,T,0,F,0,0,0,0,0,0,0,W,W,W,0,G,0,0,G},
{W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,W,W,W,W,W,W,W,W},
{W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,0,0,0,0,0,0,0,R},
{W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,0,0,W,W,W,W,W,W,W,W},
{W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,W,W},
{W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,0,F,0,W,W},
{W,W,W,W,W,0,E,0,F,0,F,0,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,0,P},
{W,W,W,W,W,W,W,W,W,0,F,0,W,W,W,0,F,0,W,W,W,0,F,0,W,W,W,W,W,W,W,W},
{W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,W,W,W,0,F,0,F,0,F,0,F,0,W,W},
{W,W,W,W,W,0,F,0,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,0,F,0,W,W},
{W,W,W,W,W,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0,F,0},
{W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W,W}
};
#undef	D
#undef	E
#undef	F
#undef	G
#undef	P
#undef	R
#undef	T
#undef	W

int	cn[3];
unsigned	scrbase = SCRBASE_M;	/* monochrome screen by default */

nc(x, y, z)
{
	cn[0]=(x);
	cn[1]=(y);
	cn[2]=(z);
	mc(cn);
	return (field[cn[1]][cn[0]]);
}

mc(p)
register *p;
{
	register a, i;

	a = axis(p[2]);
	i = incr(p[2]);
	if ((unsigned)(p[a]+=i) > limit[a])
		p[a] -= i*(limit[a]+1);
}


main(argc, argv) int argc; char *argv[];
{
	char c;

	if (argc > 1 && argv[1][0] == '-' && argv[1][1] == 'c') {
		--argc;
		++argv;
		scrbase = SCRBASE_C;		/* color screen if -c */
	}
	if (argc > 1)
		ndelay = atoi(argv[1]);
	setup();
	map();
loop:
	cls();
	if (argc == 1) {
		atrb(s_a);
		curs(1, 0);
		bufstr("Speed [default ");
		dprint((long)ndelay);
		bufstr("]? ");
		bflush();
		inputecho(&c);
		if (c == '\n')
			;		/* take old ndelay, initially 10 */
		else if (c < '0' || c > '9')
			goto loop;	/* bogus nachos */
		else			/* input ndelay char by char, ugh */
			for (ndelay = 0; c >= '0' && c <= '9'; inputecho(&c)) {
				ndelay *= 10;
				ndelay += c - '0';
			}
		if (c != '\n')
			goto loop;	/* bogus terminator */
		curs(1, 0);
		bufstr("                         ");
		bflush();
	}
	score = 0;
	bonus = S_BP;
	curs(1, 0);
	bufstr("      ");
	while (play())
		++board;
	for (;;) {
		cls();
		atrb(s_a);
		curs(1, 0);
		bufstr("Your score was ");
		dprint(score);
		bufstr(" on level ");
		bufchr(board + 'A' - 1);
		bufstr(" at speed ");
		dprint((long)ndelay);
		bufchr('.');
		curs(2, 0);
		bufstr("Do you want to play again [y or n]? ");
		bflush();
		c = 0;
		inputecho(&c);
		switch (c) {
		case 'Y':
		case 'y':
		case '\n':
			board = 1;
			edibles = 0;
			pacmen = S_PN+1;
			goto loop;
		case 'Q':
		case 'q':
		case 'N':
		case 'n':
			reset();
			exit(0);
		}
	}
}

play()
{
	register i, j;
	register *f;
	register k;

	while (pacmen) {
		e_n = E_TOFF;
		e_k = 0;
		r_c[1] = board-1+'A';
		if (edibles == 0) {
			f = field;
			for (j=0; j<F_VERT; ++j)
				for (i=0; i<F_HORZ; ++i)
					if ((*f++&=~(1<<F_BN|1<<F_PC|F_GMSK))
					 &  (1<<F_FD|1<<F_EN))
						++edibles;
			plot(0, 0, F_HORZ, F_VERT);
			if (score == 0) {
				pleft();
				--pacmen;
				r_d = edibles/2;
				i = rand();
				r_t[0] = (1+0)*edibles/(2+i);
				i = rand();
				r_t[1] = (2+i)*edibles/(3+i);
				curs(1, 0);
				atrb(s_a);
				bufchr('0');
			}
		}
		pacman(P_INIT, 0);
		pacman(P_UPDI, 0);
		ghosts(G_INIT, 0, F_GMSK);
		ghosts(G_WRIT, 1, F_GMSK);
		curs(2, 0);
		atrb(r_c[0]);
		bufchr(r_c[1]);
		curs(p_h[1]+F_VOFF, p_h[0]-4+F_HOFF);
		atrb(s_a);
		bufstr("GET READY");
		delay(10);
		pleft();
		delay(5);
		plot(p_p[0]-4, p_p[1], 9, 1);
		pacman(P_WRIT, 1);
		animate();
		if (stop) {
			if (r_s) {
				r_s = 0;
				plot(r_p[0], r_p[1], 1, 1);
			}
			k = 0;
			while ((stop&1<<k+F_GH) == 0)
				++k;
			f = &ghost[k].g_q[2];
			ghosts(G_ERAS, 1, ~stop&F_GMSK);
			beep();
			for (i=0; i<12; ++i) {
				*f ^= 2;
				ghosts(G_WRIT, 1, stop);
				delay(1);
				ghosts(G_ERAS, 1, stop);
			}
			for (i=0; i<12; ++i) {
				p_p[2] += (p_d)? -1: 1;
				p_p[2] &= 3;
				pacman(P_WRIT, 1);
				delay(1);
				pacman(P_ERAS, 1);
			}
			--pacmen;
		} else
			return (1);
	}
	return (0);
}

map()
{
	register x, y, z;
	register e, g;
	register *f;

	e = 0;
	g = 0;
	f = field;
	for (y=0; y<F_VERT; ++y)
		for (x=0; x<=F_HORZ/2; ++x)
			field[y][F_HORZ-x-1] = field[y][x];
	for (y=0; y<F_VERT; ++y)
		for (x=0; x<F_HORZ; ++f, ++x) {
			if (*f & (1<<F_EN)) {
				energ[e][0] = x;
				energ[e][1] = y;
				++e;
			} else if (*f & (1<<F_GH)) {
				ghost[g].g_h[0] = x;
				ghost[g].g_h[1] = y;
				*f &= ~(1<<F_GH);
				if ((g++&1) == 0) {
					g_g[g/2][0] = x;
					g_g[g/2][1] = y;
				}
			} else if (*f & (1<<F_PC)) {
				p_h[0] = x;
				p_h[1] = y;
				*f &= ~(1<<F_PC);
			} else if (*f & (1<<F_FR)) {
				r_p[0] = x;
				r_p[1] = y;
			}
			for (z=0; z<4; ++z)
				if (nc(x, y, z) & 1<<F_WL)
					*f |= 1<<F_WL+z+1;
		}
}


animate()
{
	register i, c;
	register unsigned clock;
	register struct ghost *g;
	register *p;
	char key = '\0';
	long oscore;
	int gscore;

	oscore = score;
	e_s = 0;
	stop = 0;
	for (clock=0; !stop && edibles; ++clock) {
		i = 0;
		if (input(&key) || p_n==clock) switch (key) {
		case KEY_N:
			++i;
		case KEY_W:
			++i;
		case KEY_S:
			++i;
		case KEY_E:
			if (vm(i) && hm(p_p[2])) {
				c = nc(p_p[0], p_p[1], i);
				if (c & (1<<F_DR|1<<F_WL|1<<F_WL+p_p[2]+1))
					break;
				if (c & 1<<F_WL+om(p_p[2])+1)
					mc(p_p);
			} else if (hm(i) && vm(p_p[2])) {
				if (nc(p_p[0]+incr(i), p_p[1]+p_l, i) & 1<<F_WL)
					break;
				p_p[1] += p_l;
				p_l = 0;
			} else if (p_p[2] == i) {
				if (p_m) {
					key = '\0';
					break;
				}
			} else if (vm(i) && p_l) {
				p_p[1] += p_l;
				p_l = -p_l;
			}
			p_p[2] = i;
			p_m = 1;
			p_n = clock;
			key = '\0';
			break;
		case KEY_C:
			p_m = 0;
			key = '\0';
			break;
		}
		if (p_n == clock) {
			if (ndelay)
				delay(1);
			pacman(P_ERAS, 1);
			pacman(P_MOVE, 0);
			pacman(P_UPDI, 0);
			p_d ^= 1;
			pacman(P_WRIT, 1);
			p = &field[p_p[1]+p_l][p_p[0]];
			for (i=-1; i<2; ++i) {
				if (r_s && (p[i]&1<<F_FR)) {
					score += S_FR;
					r_s = 0;
					atrb(s_a);
					curs(r_p[1]+F_VOFF, r_p[0]+F_HOFF);
					c = dprint((long)S_FR);
					delay(5);
					plot(r_p[0], r_p[1], c, 1);
					continue;
				}
				if ((c=p[i]) & 1<<F_BN)
					continue;
				p[i] = c | 1<<F_BN;
				if (c & 1<<F_FD) {
					score += S_FD;
				} else if (c & 1<<F_EN) {
					ghosts(G_BLUE, 1, F_GMSK);
					gscore = S_GH;
					score += S_EN;
				} else
					continue;
				--edibles;
				if (edibles==r_t[0] || edibles==r_t[1]) {
					r_s = r_d;
					plot(r_p[0], r_p[1], 1, 1);
				}
			}
			if (r_s && --r_s==0)
				plot(r_p[0], r_p[1], 1, 1);
			if (e_s) for (g=ghost,i=1<<F_GH; i&F_GMSK; i<<=1,++g) {
				if (g->g_s!=1 || contact(g->g_p, 3)==0)
					continue;
				curs(g->g_p[1]+F_VOFF, g->g_p[0]-1+F_HOFF);
				beep();
				atrb(s_a);
				c = dprint((long)gscore);
				delay(5);
				atrb(0);
				curs(g->g_p[1]+F_VOFF, g->g_p[0]-1+F_HOFF);
				while (c--)
					bufchr(' ');
				g->g_s = 2;
				g->g_e = 0;
				plot(g->g_p[0]-1, g->g_p[1], 4, 1);
				score += gscore;
				gscore *= 2;
			}
		}
		for (g=ghost,i=1<<F_GH; i&F_GMSK; i<<=1,++g) {
			if (g->g_n != clock)
				continue;
			ghosts(G_ERAS, 1, i);
			ghosts(G_MOVE, 0, i);
			ghosts(G_WRIT, 1, i);
		}
		if (e_n == clock) {
			++e_k;
			p = energ[(e_k&=7)&3];
			plot(p[0], p[1], 1, 1);
			e_n += E_TMQN;
		}
		if (score != oscore) {
			curs(1, 0);
			atrb(s_a);
			dprint(score);
			if (score>=bonus && oscore<bonus) {
				bonus += S_BP;
				if (pacmen < S_PN+1) {
					beep();
					++pacmen;
					pleft();
				}
			}
			oscore = score;
		}
		bflush();
	}
}

dprint(l)
long l;
{
	register c, d = 1, e = 0;
	static long mag[] = {1, 10, 100, 1000, 10000, 100000};

	while (mag[d] <= l)
		++d;
	while (d--) {
		for (c=0; l>=mag[d]; ++c)
			l -= mag[d];
		bufchr(c+'0');
		++e;
	}
	return (e);
}

pleft()
{
	register i, j;
	register char *c;

	for (i=0; i<S_PN+1; ++i) {
		curs(22-2*i, 0);
		c = p_cc[pacmen>i+1? 0 : 1];
		for (j=0; j<3; ++j) {
			atrb(*c++);
			bufchr(*c++);
		}
	}
}

pacman(s, p)
{
	register i;
	register *f;

	switch (s) {
	case P_ERAS:
		for (i=0; i<p_i[2]; ++i) {
			f = &field[p_i[1]+i][p_i[0]];
			*f++ &= ~(1<<F_PC);
			*f++ &= ~(1<<F_PC);
			*f   &= ~(1<<F_PC);
		}
		plot(p_i[0], p_i[1], 3, p_i[2]);
		break;
	case P_WRIT:
		for (i=0; i<p_i[2]; ++i) {
			f = &field[p_i[1]+i][p_i[0]];
			*f++ |= (1<<F_PC);
			*f++ |= (1<<F_PC);
			*f   |= (1<<F_PC);
		}
		break;
	case P_MOVE:
		p_n += (P_TMQN*2-p_n%(P_TMQN*2)+P_TOFF);
		if (p_m) {
			i = nc(p_p[0], p_p[1], p_p[2]);
			if (vm(p_p[2]))
				if (p_l) {
					p_p[1] += p_l;
					p_l = 0;
				} else if (i & (1<<F_WL|1<<F_DR))
					p_m = 0;
				else if (P_HALF)
					p_l = incr(p_p[2]);
				else
					p_p[1] += incr(p_p[2]);
			else if (i & 1<<F_WL+p_p[2]+1)
				p_m = 0;
			else {
				mc(p_p);
				if (!P_HALF && (p_p[0]&1))
					mc(p_p);
			}
		}
		break;
	case P_UPDI:
		p_i[0] = p_p[0]-1;
		p_i[1] = p_p[1]+(p_l>>1);
		p_i[2] = 1+(p_l&1);
		break;
	case P_INIT:
		p_p[0] = p_h[0];
		p_p[1] = p_h[1];
		p_p[2] = 1;
		p_l = 0;
		p_m = 0;
		p_d = 0;
		p_n = P_TOFF;
		break;
	}
	if (p)
		plot(p_i[0], p_i[1], 3, p_i[2]);
}

ghosts(s, p, m)
{
	register struct ghost *g;
	register *f;
	register i;

	for (g=ghost,i=1<<F_GH; i&F_GMSK; i<<=1,++g) {
		if ((m&i) == 0)
			continue;
		switch (s) {
		case G_ERAS:
			f = &field[g->g_p[1]][g->g_p[0]];
			*f &= ~i;
			*(f-1) &= ~i;
			*(f+1) &= ~i;
			break;
		case G_WRIT:
			f = &field[g->g_p[1]][g->g_p[0]];
			*f |= i;
			*(f-1) |= i;
			*(f+1) |= i;
			break;
		case G_MOVE:
			g->g_p[0] = g->g_q[0];
			g->g_p[1] = g->g_q[1];
			g->g_p[2] = g->g_q[2];
			f = g_v;
			switch (g->g_s) {
			case 0:
				if (field[g->g_p[1]][g->g_p[0]] & 1<<F_TN)
					g->g_n += G_TMQN*8;
				else
					g->g_n += G_TMQN*4;
				if (g->g_r > 0)
					if (--g->g_r) {
						g->g_f ^= 2;
						break;
					} else {
						--g->g_r;
						g->g_f = 0;
					}
				if (g->g_r) {
					if (vector(g, g_g[0], 0))
						g->g_r = 0;
				} else if (contact(g->g_p, 3) && stop<i) {
					stop = i;
					break;
				} else if (track() && sight(g->g_p)) {
					vector(g, p_p, p_l);
				} else if (nprox() && prox(g->g_p)<=nprox()) {
					vector(g, p_p, p_l);
				} else {
					g_v[0] = g->g_p[2];
					g_v[1] = 3&(g->g_p[2]+
						 (((g-ghost)^g->g_p[2])&2)-1);
					g_v[2] = g_v[1]^2;
					g_v[3] = g_v[0]^2;
					f += (rand()&rand());
				}
				goto select;
			case 1:
				if (--g->g_e == 0) {
					g->g_s = 0;
					g->g_d = 0;
					--e_s;
				} else if (g->g_e <= G_BTIM)
					g->g_d ^= 1;
				g->g_n += G_TMQN*8;
				vector(g, p_p, p_l);
				f = g_v+2;
				goto select;
			case 2:
				if (g->g_r == 0) {
					g->g_r--;
					g->g_d = 0;
				}
				g->g_n += G_TMQN*2;
				if (vector(g, g_g[1], 0)) {
					g->g_q[2] ^= 2;
					while (g->g_n%(G_TMQN*4) != g->g_o)
						g->g_n += G_TMQN*2;
					g->g_s = 0;
					g->g_f = 0;
					--e_s;
					break;
				}
				f = g_v;
			select:
				if (vm(*f)
				&&  nc(g->g_p[0], g->g_p[1], *f)
				 &  (1<<F_WL|1<<F_WL+1|1<<F_WL+3
				 |  (!g->g_r)<<F_DR)
				   ) {
					if (++f-g_v > 3)
						f = g_v;
					goto select;
				}
				if (hm(*f)
				&&  nc(g->g_p[0]+2*incr(*f), g->g_p[1], *f)
				 &  1<<F_WL
				   ) {
					if (++f-g_v > 3)
						f = g_v;
					goto select;
				}
				if ((*f^g->g_p[2])==2 && g->g_e<G_ETIM-1) {
					if (++f-g_v > 3)
						f = g_v;
					goto select;
				}
				g->g_q[2] = *f;
				do {
					mc(g->g_q);
					if (vm(g->g_q[2])
					||  (g->g_q[0]&1) == 0
					   )
						break;
					if (g->g_r
					&& (g->g_q[0] == g_g[0][0]
					&&  g->g_q[1] == g_g[0][1]
					||  g->g_q[0] == g_g[1][0]
					&&  g->g_q[1] == g_g[1][1]
					   ))
						break;
					mc(g->g_q);
				} while (0);
				if (g->g_p[2] == g->g_q[2])
					g->g_f ^= 2;
				else if ((g->g_p[2]^g->g_q[2]) & 1)
					g->g_f = 0;
			}
			break;
		case G_BLUE:
			if (g->g_s < 2) {
				if (g->g_s == 0)
					if (g->g_r)
						break;
					else
						++e_s;
				g->g_s = 1;
				g->g_e = G_ETIM;
				g->g_d = 0;
			}
			break;
		case G_INIT:
			g->g_p[0] = g->g_q[0] = g->g_h[0];
			g->g_p[1] = g->g_q[1] = g->g_h[1];
			g->g_q[2] = g_i[g-ghost];
			g->g_s = 0;
			g->g_d = 0;
			g->g_e = 0;
			g->g_f = 0;
			g->g_r = 12*((g-ghost&1)*2+(g-ghost&2)/2);
			g->g_n = g->g_o = G_TOFF(g-ghost);
			break;
		}
		if (p)
			plot(g->g_p[0]-1, g->g_p[1], 3, 1);
	}
}

plot(x, y, nx, ny)
{
	register b, f;
	register struct ghost *g;
	register char *c;
	register int *p;
	register i;
	register z0, z1, z2, z3;

	if (x < 0) {
		nx -= x;
		x = 0;
	}
	if ((nx+=x) > F_HORZ-F_HHID)
		nx = F_HORZ-F_HHID;
	for (ny+=y; y<ny; ++y) {
		curs(y+F_VOFF, x+F_HOFF);
		p = &field[y][x];
		for (i=x; i<nx; ++i) {
			if ((f=*p++&F_BMSK)==0 || i<F_HHID)
				c = b_c;
			else {
				for (b=0; (f&1)==0; ++b)
					f >>= 1;
				switch (b) {
				case F_GH+0:
				case F_GH+1:
				case F_GH+2:
				case F_GH+3:
					g = ghost + b - F_GH;
/*
					c = g_c[b-F_GH]
					       [g->g_q[2]^(g->g_f&P_GFLP)]
					       [g->g_s-g->g_d]
					       [i-g->g_p[0]+1];
*/
					z0 = b-F_GH;
					z1 = g->g_q[2]^(g->g_f&P_GFLP);
					z2 = g->g_s-g->g_d;
					z3 = i-g->g_p[0]+1;
					c = g_c[z0][z1][z2][z3];
					break;
				case F_PC:
					c = p_c[y-p_i[1]+(p_l&1)][p_p[2]]
					       [p_d][i-p_i[0]];
					break;
				case F_FR:
					c = r_s? r_c : b_c;
					break;
				case F_BN:
					c = b_c;
					break;
				case F_FD:
					c = f_c;
					break;
				case F_EN:
					c = e_c[e_k>>2];
					break;
				case F_DR:
					c = d_c;
					break;
				case F_TN:
					c = b_c;
					break;
				case F_WL:
					c = w_c;
					break;
				}
			}
			atrb(*c++);
			bufchr(*c);
		}
	}
}

contact(p, n)
register *p;
{
	register dx, dy;

	dx = p_p[0] - p[0];
	dy = p_p[1]*2 + p_l - p[1]*2;
	if ((dy==0 && n>dx && dx>-n)
	||  (dx==0 && n>dy && dy>-n)
	   )
		return (1);
	return (0);
}

prox(p)
register *p;
{
	register dx, dy;

	if ((dx=p_p[0]-p[0]) < 0)
		dx = -dx;
	if ((dy=p_p[1]*2+p_l-p[1]*2) < 0)
		dy = -dy;
	if (dy > dx)
		return (dy);
	return (dx);
}

vector(g, t, o)
register struct ghost *g;
register *t;
{
	register i;
	int d[2], s[2] = {0, 0};

	if ((d[0]=t[0]-g->g_p[0]) < 0) {
			d[0] =- d[0];
			s[0] =  2;
	} else if (d[0] == 0)
		if (hm(g->g_p[2]))
			s[0] = g->g_p[2]&2^2;
		else
			s[0] = rand()*2;
	if ((d[1]=t[1]*2+o-g->g_p[1]*2) < 0) {
			d[1] =- d[1];
			s[1] =  2;
	} else if (d[1] == 0)
		if (vm(g->g_p[2]))
			s[1] = g->g_p[2]&2^2;
		else
			s[1] = rand()*2;
	if (d[0] > d[1])
		i = 0;
	else if (d[1] > d[0])
		i = 1;
	else
		i = axis(g->g_p[2]);
	t = g_v;
	*t++ = i | s[i];
	*t++ = (i^1) | s[i^1];
	*t++ = (i^1) | (s[i^1]^2);
	*t   = i | (s[i]^2);
	if (d[0] | d[1])
		return (0);
	return (1);
}

sight(p)
register *p;
{
	register v;
	int q[3];

	if (p[0] != p_p[0]
	&&  p[1] != p_p[1]
	   )
		return (0);
	for (v=p[2]-1; v<=p[2]+1; ++v) {
		q[0] = p[0];
		q[1] = p[1];
		q[2] = v&3;
		while ((field[q[1]][q[0]]&1<<F_WL) == 0) {
			if (q[0]==p_p[0] && q[1]==p_p[1])
				return (1);
			mc(q);
		}
	}
	return (0);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.