xref: /csrg-svn/games/atc/input.c (revision 60740)
141166Sbostic /*-
2*60740Sbostic  * Copyright (c) 1990, 1993
3*60740Sbostic  *	The Regents of the University of California.  All rights reserved.
441166Sbostic  *
541166Sbostic  * This code is derived from software contributed to Berkeley by
641166Sbostic  * Ed James.
741166Sbostic  *
841166Sbostic  * %sccs.include.redist.c%
941166Sbostic  */
1041166Sbostic 
1132471Sbostic /*
1232471Sbostic  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
1332471Sbostic  *
1432471Sbostic  * Copy permission is hereby granted provided that this notice is
1532471Sbostic  * retained on all partial or complete copies.
1632471Sbostic  *
1732471Sbostic  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
1832471Sbostic  */
1932471Sbostic 
2032471Sbostic #ifndef lint
21*60740Sbostic static char sccsid[] = "@(#)input.c	8.1 (Berkeley) 05/31/93";
2232471Sbostic #endif not lint
2332471Sbostic 
2432471Sbostic #include "include.h"
2537938Sbostic #include "pathnames.h"
2632471Sbostic 
2732471Sbostic #define MAXRULES	6
2832471Sbostic #define MAXDEPTH	15
2932471Sbostic 
3032471Sbostic #define RETTOKEN	'\n'
3132471Sbostic #ifdef SYSV
3232471Sbostic #define CRTOKEN		'\r'
3332471Sbostic #endif
3432471Sbostic #define REDRAWTOKEN	'\014'	/* CTRL(L) */
3532471Sbostic #define	SHELLTOKEN	'!'
3632471Sbostic #define HELPTOKEN	'?'
3732471Sbostic #define ALPHATOKEN	256
3832471Sbostic #define NUMTOKEN	257
3932471Sbostic 
4032471Sbostic typedef struct {
4132471Sbostic 	int	token;
4232471Sbostic 	int	to_state;
4332471Sbostic 	char	*str;
4432471Sbostic 	char	*(*func)();
4532471Sbostic } RULE;
4632471Sbostic 
4732471Sbostic typedef struct {
4832471Sbostic 	int	num_rules;
4932471Sbostic 	RULE	*rule;
5032471Sbostic } STATE;
5132471Sbostic 
5232471Sbostic typedef struct {
5332471Sbostic 	char	str[20];
5432471Sbostic 	int	state;
5532471Sbostic 	int	rule;
5632471Sbostic 	int	ch;
5732471Sbostic 	int	pos;
5832471Sbostic } STACK;
5932471Sbostic 
6032471Sbostic #define T_RULE		stack[level].rule
6132471Sbostic #define T_STATE		stack[level].state
6232471Sbostic #define T_STR		stack[level].str
6332471Sbostic #define T_POS		stack[level].pos
6432471Sbostic #define	T_CH		stack[level].ch
6532471Sbostic 
6632471Sbostic #define NUMELS(a)	(sizeof (a) / sizeof (*(a)))
6732471Sbostic 
6832471Sbostic #define NUMSTATES	NUMELS(st)
6932471Sbostic 
7032471Sbostic char	*setplane(), *circle(), *left(), *right(), *Left(), *Right(),
7132471Sbostic 	*beacon(), *ex_it(), *climb(), *descend(), *setalt(), *setrelalt(),
7232471Sbostic 	*benum(), *to_dir(), *rel_dir(), *delayb(), *mark(), *unmark(),
7332471Sbostic 	*airport(), *turn(), *ignore();
7432471Sbostic 
7532471Sbostic RULE	state0[] = {	{ ALPHATOKEN,	1,	"%c:",		setplane},
7632471Sbostic 			{ RETTOKEN,	-1,	"",		NULL	},
7732471Sbostic #ifdef SYSV
7832471Sbostic 			{ CRTOKEN,	-1,	"",		NULL	},
7932471Sbostic #endif
8032471Sbostic 			{ HELPTOKEN,	12,	" [a-z]<ret>",	NULL	}},
8132471Sbostic 	state1[] = {	{ 't',		2,	" turn",	turn	},
8232471Sbostic 			{ 'a',		3,	" altitude:",	NULL	},
8332471Sbostic 			{ 'c',		4,	" circle",	circle	},
8432471Sbostic 			{ 'm',		7,	" mark",	mark	},
8532471Sbostic 			{ 'u',		7,	" unmark",	unmark	},
8632471Sbostic 			{ 'i',		7,	" ignore",	ignore	},
8732471Sbostic 			{ HELPTOKEN,	12,	" tacmui",	NULL	}},
8832471Sbostic 	state2[] = {	{ 'l',		6,	" left",	left	},
8932471Sbostic 			{ 'r',		6,	" right",	right	},
9032471Sbostic 			{ 'L',		4,	" left 90",	Left	},
9132471Sbostic 			{ 'R',		4,	" right 90",	Right	},
9232471Sbostic 			{ 't',		11,	" towards",	NULL	},
9332471Sbostic 			{ 'w',		4,	" to 0",	to_dir	},
9432471Sbostic 			{ 'e',		4,	" to 45",	to_dir	},
9532471Sbostic 			{ 'd',		4,	" to 90",	to_dir	},
9632471Sbostic 			{ 'c',		4,	" to 135",	to_dir	},
9732471Sbostic 			{ 'x',		4,	" to 180",	to_dir	},
9832471Sbostic 			{ 'z',		4,	" to 225",	to_dir	},
9932471Sbostic 			{ 'a',		4,	" to 270",	to_dir	},
10032471Sbostic 			{ 'q',		4,	" to 315",	to_dir	},
10132471Sbostic 			{ HELPTOKEN,	12,	" lrLRt<dir>",	NULL	}},
10232471Sbostic 	state3[] = {	{ '+',		10,	" climb",	climb	},
10332471Sbostic 			{ 'c',		10,	" climb",	climb	},
10432471Sbostic 			{ '-',		10,	" descend",	descend	},
10532471Sbostic 			{ 'd',		10,	" descend",	descend	},
10632471Sbostic 			{ NUMTOKEN,	7,	" %c000 feet",	setalt	},
10732471Sbostic 			{ HELPTOKEN,	12,	" +-cd[0-9]",	NULL	}},
10832471Sbostic 	state4[] = {	{ '@',		9,	" at",		NULL	},
10932471Sbostic 			{ 'a',		9,	" at",		NULL	},
11032471Sbostic 			{ RETTOKEN,	-1,	"",		NULL	},
11132471Sbostic #ifdef SYSV
11232471Sbostic 			{ CRTOKEN,	-1,	"",		NULL	},
11332471Sbostic #endif
11432471Sbostic 			{ HELPTOKEN,	12,	" @a<ret>",	NULL	}},
11532471Sbostic 	state5[] = {	{ NUMTOKEN,	7,	"%c",		delayb	},
11632471Sbostic 			{ HELPTOKEN,	12,	" [0-9]",	NULL	}},
11732471Sbostic 	state6[] = {	{ '@',		9,	" at",		NULL	},
11832471Sbostic 			{ 'a',		9,	" at",		NULL	},
11932471Sbostic 			{ 'w',		4,	" 0",		rel_dir	},
12032471Sbostic 			{ 'e',		4,	" 45",		rel_dir	},
12132471Sbostic 			{ 'd',		4,	" 90",		rel_dir	},
12232471Sbostic 			{ 'c',		4,	" 135",		rel_dir	},
12332471Sbostic 			{ 'x',		4,	" 180",		rel_dir	},
12432471Sbostic 			{ 'z',		4,	" 225",		rel_dir	},
12532471Sbostic 			{ 'a',		4,	" 270",		rel_dir	},
12632471Sbostic 			{ 'q',		4,	" 315",		rel_dir	},
12732471Sbostic 			{ RETTOKEN,	-1,	"",		NULL	},
12832471Sbostic #ifdef SYSV
12932471Sbostic 			{ CRTOKEN,	-1,	"",		NULL	},
13032471Sbostic #endif
13132471Sbostic 			{ HELPTOKEN,	12,	" @a<dir><ret>",NULL	}},
13232471Sbostic 	state7[] = {	{ RETTOKEN,	-1,	"",		NULL	},
13332471Sbostic #ifdef SYSV
13432471Sbostic 	            	{ CRTOKEN,	-1,	"",		NULL	},
13532471Sbostic #endif
13632471Sbostic 			{ HELPTOKEN,	12,	" <ret>",	NULL	}},
13732471Sbostic 	state8[] = {	{ NUMTOKEN,	4,	"%c",		benum	},
13832471Sbostic 			{ HELPTOKEN,	12,	" [0-9]",	NULL	}},
13932471Sbostic 	state9[] = {	{ 'b',		5,	" beacon #",	NULL	},
14032471Sbostic 			{ '*',		5,	" beacon #",	NULL	},
14132471Sbostic 			{ HELPTOKEN,	12,	" b*",		NULL	}},
14232471Sbostic 	state10[] = {	{ NUMTOKEN,	7,	" %c000 ft",	setrelalt},
14332471Sbostic 			{ HELPTOKEN,	12,	" [0-9]",	NULL	}},
14432471Sbostic 	state11[] = {	{ 'b',		8,	" beacon #",	beacon	},
14532471Sbostic 			{ '*',		8,	" beacon #",	beacon	},
14632471Sbostic 			{ 'e',		8,	" exit #",	ex_it	},
14732471Sbostic 			{ 'a',		8,	" airport #",	airport	},
14832471Sbostic 			{ HELPTOKEN,	12,	" b*ea",	NULL	}},
14932471Sbostic 	state12[] = {	{ -1,		-1,	"",		NULL	}};
15032471Sbostic 
15132471Sbostic #define DEF_STATE(s)	{ NUMELS(s),	(s)	}
15232471Sbostic 
15332471Sbostic STATE	st[] = {
15432471Sbostic 	DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2),
15532471Sbostic 	DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5),
15632471Sbostic 	DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8),
15732471Sbostic 	DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11),
15832471Sbostic 	DEF_STATE(state12)
15932471Sbostic };
16032471Sbostic 
16132471Sbostic PLANE	p;
16232471Sbostic STACK	stack[MAXDEPTH];
16332471Sbostic int	level;
16432471Sbostic int	tval;
16532471Sbostic int	dest_type, dest_no, dir;
16632471Sbostic 
pop()16732471Sbostic pop()
16832471Sbostic {
16932471Sbostic 	if (level == 0)
17032471Sbostic 		return (-1);
17132471Sbostic 	level--;
17232471Sbostic 
17332471Sbostic 	ioclrtoeol(T_POS);
17432471Sbostic 
17532471Sbostic 	strcpy(T_STR, "");
17632471Sbostic 	T_RULE = -1;
17732471Sbostic 	T_CH = -1;
17832471Sbostic 	return (0);
17932471Sbostic }
18032471Sbostic 
rezero()18132471Sbostic rezero()
18232471Sbostic {
18332471Sbostic 	iomove(0);
18432471Sbostic 
18532471Sbostic 	level = 0;
18632471Sbostic 	T_STATE = 0;
18732471Sbostic 	T_RULE = -1;
18832471Sbostic 	T_CH = -1;
18932471Sbostic 	T_POS = 0;
19032471Sbostic 	strcpy(T_STR, "");
19132471Sbostic }
19232471Sbostic 
push(ruleno,ch)19332471Sbostic push(ruleno, ch)
19432471Sbostic {
19532471Sbostic 	int	newstate, newpos;
19632471Sbostic 
19732472Sbostic 	(void)sprintf(T_STR, st[T_STATE].rule[ruleno].str, tval);
19832471Sbostic 	T_RULE = ruleno;
19932471Sbostic 	T_CH = ch;
20032471Sbostic 	newstate = st[T_STATE].rule[ruleno].to_state;
20132471Sbostic 	newpos = T_POS + strlen(T_STR);
20232471Sbostic 
20332471Sbostic 	ioaddstr(T_POS, T_STR);
20432471Sbostic 
20532471Sbostic 	if (level == 0)
20632471Sbostic 		ioclrtobot();
20732471Sbostic 	level++;
20832471Sbostic 	T_STATE = newstate;
20932471Sbostic 	T_POS = newpos;
21032471Sbostic 	T_RULE = -1;
21132471Sbostic 	strcpy(T_STR, "");
21232471Sbostic }
21332471Sbostic 
getcommand()21432471Sbostic getcommand()
21532471Sbostic {
21632471Sbostic 	int	c, i, done;
21732471Sbostic 	char	*s, *(*func)();
21832471Sbostic 	PLANE	*pp;
21932471Sbostic 
22032471Sbostic 	rezero();
22132471Sbostic 
22232471Sbostic 	do {
22332471Sbostic 		c = gettoken();
22432471Sbostic 		if (c == tty_new.sg_erase) {
22532471Sbostic 			if (pop() < 0)
22632471Sbostic 				noise();
22732471Sbostic 		} else if (c == tty_new.sg_kill) {
22832471Sbostic 			while (pop() >= 0)
22932471Sbostic 				;
23032471Sbostic 		} else {
23132471Sbostic 			done = 0;
23232471Sbostic 			for (i = 0; i < st[T_STATE].num_rules; i++) {
23332471Sbostic 				if (st[T_STATE].rule[i].token == c ||
23432471Sbostic 				    st[T_STATE].rule[i].token == tval) {
23532471Sbostic 					push(i, (c >= ALPHATOKEN) ? tval : c);
23632471Sbostic 					done = 1;
23732471Sbostic 					break;
23832471Sbostic 				}
23932471Sbostic 			}
24032471Sbostic 			if (!done)
24132471Sbostic 				noise();
24232471Sbostic 		}
24332471Sbostic 	} while (T_STATE != -1);
24432471Sbostic 
24532471Sbostic 	if (level == 1)
24632471Sbostic 		return (1);	/* forced update */
24732471Sbostic 
24832471Sbostic 	dest_type = T_NODEST;
24932471Sbostic 
25032471Sbostic 	for (i = 0; i < level; i++) {
25132471Sbostic 		func = st[stack[i].state].rule[stack[i].rule].func;
25232471Sbostic 		if (func != NULL)
25332471Sbostic 			if ((s = (*func)(stack[i].ch)) != NULL) {
25432471Sbostic 				ioerror(stack[i].pos, strlen(stack[i].str), s);
25532471Sbostic 				return (-1);
25632471Sbostic 			}
25732471Sbostic 	}
25832471Sbostic 
25932471Sbostic 	pp = findplane(p.plane_no);
26032471Sbostic 	if (pp->new_altitude != p.new_altitude)
26132471Sbostic 		pp->new_altitude = p.new_altitude;
26232471Sbostic 	else if (pp->status != p.status)
26332471Sbostic 		pp->status = p.status;
26432471Sbostic 	else {
26532471Sbostic 		pp->new_dir = p.new_dir;
26632471Sbostic 		pp->delayd = p.delayd;
26732471Sbostic 		pp->delayd_no = p.delayd_no;
26832471Sbostic 	}
26932471Sbostic 	return (0);
27032471Sbostic }
27132471Sbostic 
noise()27232471Sbostic noise()
27332471Sbostic {
27432471Sbostic 	putchar('\07');
27532471Sbostic 	fflush(stdout);
27632471Sbostic }
27732471Sbostic 
gettoken()27832471Sbostic gettoken()
27932471Sbostic {
28032471Sbostic 	while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN)
28132471Sbostic 	{
28232471Sbostic 		if (tval == SHELLTOKEN)
28332471Sbostic 		{
28432471Sbostic #ifdef BSD
28532471Sbostic 			struct itimerval	itv;
28632471Sbostic 			itv.it_value.tv_sec = 0;
28732471Sbostic 			itv.it_value.tv_usec = 0;
28832471Sbostic 			setitimer(ITIMER_REAL, &itv, NULL);
28932471Sbostic #endif
29032471Sbostic #ifdef SYSV
29132471Sbostic 			int aval;
29232471Sbostic 			aval = alarm(0);
29332471Sbostic #endif
29432471Sbostic 			if (fork() == 0)	/* child */
29532471Sbostic 			{
29632471Sbostic 				char *shell, *base, *getenv(), *strrchr();
29732471Sbostic 
29832471Sbostic 				setuid(getuid()); /* turn off setuid bit */
29932471Sbostic 				done_screen();
30032471Sbostic 
30132471Sbostic 						 /* run user's favorite shell */
30232471Sbostic 				if ((shell = getenv("SHELL")) != NULL)
30332471Sbostic 				{
30432471Sbostic 					base = strrchr(shell, '/');
30532471Sbostic 					if (base == NULL)
30632471Sbostic 						base = shell;
30732471Sbostic 					else
30832471Sbostic 						base++;
30932471Sbostic 					execl(shell, base, 0);
31032471Sbostic 				}
31132471Sbostic 				else
31237938Sbostic 					execl(_PATH_BSHELL, "sh", 0);
31332471Sbostic 
31432471Sbostic 				exit(0);	/* oops */
31532471Sbostic 			}
31632471Sbostic 
31732471Sbostic 			wait(0);
31832471Sbostic #ifdef BSD
31932471Sbostic 			ioctl(fileno(stdin), TIOCSETP, &tty_new);
32032471Sbostic 			itv.it_value.tv_sec = 0;
32132471Sbostic 			itv.it_value.tv_usec = 1;
32232471Sbostic 			itv.it_interval.tv_sec = sp->update_secs;
32332471Sbostic 			itv.it_interval.tv_usec = 0;
32432471Sbostic 			setitimer(ITIMER_REAL, &itv, NULL);
32532471Sbostic #endif
32632471Sbostic #ifdef SYSV
32732471Sbostic 			ioctl(fileno(stdin), TCSETAW, &tty_new);
32832471Sbostic 			alarm(aval);
32932471Sbostic #endif
33032471Sbostic 		}
33132471Sbostic 		redraw();
33232471Sbostic 	}
33332471Sbostic 
33432471Sbostic 	if (isdigit(tval))
33532471Sbostic 		return (NUMTOKEN);
33632471Sbostic 	else if (isalpha(tval))
33732471Sbostic 		return (ALPHATOKEN);
33832471Sbostic 	else
33932471Sbostic 		return (tval);
34032471Sbostic }
34132471Sbostic 
34232471Sbostic char	*
setplane(c)34332471Sbostic setplane(c)
34432471Sbostic {
34532471Sbostic 	PLANE	*pp;
34632471Sbostic 
34732471Sbostic 	pp = findplane(number(c));
34832471Sbostic 	if (pp == NULL)
34932471Sbostic 		return ("Unknown Plane");
35032471Sbostic 	bcopy(pp, &p, sizeof (p));
35132471Sbostic 	p.delayd = 0;
35232471Sbostic 	return (NULL);
35332471Sbostic }
35432471Sbostic 
35532471Sbostic char	*
turn(c)35632471Sbostic turn(c)
35732471Sbostic {
35832471Sbostic 	if (p.altitude == 0)
35932471Sbostic 		return ("Planes at airports may not change direction");
36032471Sbostic 	return (NULL);
36132471Sbostic }
36232471Sbostic 
36332471Sbostic char	*
circle(c)36432471Sbostic circle(c)
36532471Sbostic {
36632471Sbostic 	if (p.altitude == 0)
36732471Sbostic 		return ("Planes cannot circle on the ground");
36832471Sbostic 	p.new_dir = MAXDIR;
36932471Sbostic 	return (NULL);
37032471Sbostic }
37132471Sbostic 
37232471Sbostic char	*
left(c)37332471Sbostic left(c)
37432471Sbostic {
37532471Sbostic 	dir = D_LEFT;
37632471Sbostic 	p.new_dir = p.dir - 1;
37732471Sbostic 	if (p.new_dir < 0)
37832471Sbostic 		p.new_dir += MAXDIR;
37932471Sbostic 	return (NULL);
38032471Sbostic }
38132471Sbostic 
38232471Sbostic char	*
right(c)38332471Sbostic right(c)
38432471Sbostic {
38532471Sbostic 	dir = D_RIGHT;
38632471Sbostic 	p.new_dir = p.dir + 1;
38732471Sbostic 	if (p.new_dir > MAXDIR)
38832471Sbostic 		p.new_dir -= MAXDIR;
38932471Sbostic 	return (NULL);
39032471Sbostic }
39132471Sbostic 
39232471Sbostic char	*
Left(c)39332471Sbostic Left(c)
39432471Sbostic {
39532471Sbostic 	p.new_dir = p.dir - 2;
39632471Sbostic 	if (p.new_dir < 0)
39732471Sbostic 		p.new_dir += MAXDIR;
39832471Sbostic 	return (NULL);
39932471Sbostic }
40032471Sbostic 
40132471Sbostic char	*
Right(c)40232471Sbostic Right(c)
40332471Sbostic {
40432471Sbostic 	p.new_dir = p.dir + 2;
40532471Sbostic 	if (p.new_dir > MAXDIR)
40632471Sbostic 		p.new_dir -= MAXDIR;
40732471Sbostic 	return (NULL);
40832471Sbostic }
40932471Sbostic 
41032471Sbostic char	*
delayb(c)41132471Sbostic delayb(c)
41232471Sbostic {
41332471Sbostic 	int	xdiff, ydiff;
41432471Sbostic 
41532471Sbostic 	c -= '0';
41632471Sbostic 
41732471Sbostic 	if (c >= sp->num_beacons)
41832471Sbostic 		return ("Unknown beacon");
41932471Sbostic 	xdiff = sp->beacon[c].x - p.xpos;
42032471Sbostic 	xdiff = SGN(xdiff);
42132471Sbostic 	ydiff = sp->beacon[c].y - p.ypos;
42232471Sbostic 	ydiff = SGN(ydiff);
42332471Sbostic 	if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy)
42432471Sbostic 		return ("Beacon is not in flight path");
42532471Sbostic 	p.delayd = 1;
42632471Sbostic 	p.delayd_no = c;
42732471Sbostic 
42832471Sbostic 	if (dest_type != T_NODEST) {
42932471Sbostic 		switch (dest_type) {
43032471Sbostic 		case T_BEACON:
43132471Sbostic 			xdiff = sp->beacon[dest_no].x - sp->beacon[c].x;
43232471Sbostic 			ydiff = sp->beacon[dest_no].y - sp->beacon[c].y;
43332471Sbostic 			break;
43432471Sbostic 		case T_EXIT:
43532471Sbostic 			xdiff = sp->exit[dest_no].x - sp->beacon[c].x;
43632471Sbostic 			ydiff = sp->exit[dest_no].y - sp->beacon[c].y;
43732471Sbostic 			break;
43832471Sbostic 		case T_AIRPORT:
43932471Sbostic 			xdiff = sp->airport[dest_no].x - sp->beacon[c].x;
44032471Sbostic 			ydiff = sp->airport[dest_no].y - sp->beacon[c].y;
44132471Sbostic 			break;
44232471Sbostic 		default:
44332471Sbostic 			return ("Bad case in delayb!  Get help!");
44432471Sbostic 			break;
44532471Sbostic 		}
44632471Sbostic 		if (xdiff == 0 && ydiff == 0)
44732471Sbostic 			return ("Would already be there");
44832471Sbostic 		p.new_dir = DIR_FROM_DXDY(xdiff, ydiff);
44932471Sbostic 		if (p.new_dir == p.dir)
45032471Sbostic 			return ("Already going in that direction");
45132471Sbostic 	}
45232471Sbostic 	return (NULL);
45332471Sbostic }
45432471Sbostic 
45532471Sbostic char	*
beacon(c)45632471Sbostic beacon(c)
45732471Sbostic {
45832471Sbostic 	dest_type = T_BEACON;
45932471Sbostic 	return (NULL);
46032471Sbostic }
46132471Sbostic 
46232471Sbostic char	*
ex_it(c)46332471Sbostic ex_it(c)
46432471Sbostic {
46532471Sbostic 	dest_type = T_EXIT;
46632471Sbostic 	return (NULL);
46732471Sbostic }
46832471Sbostic 
46932471Sbostic char	*
airport(c)47032471Sbostic airport(c)
47132471Sbostic {
47232471Sbostic 	dest_type = T_AIRPORT;
47332471Sbostic 	return (NULL);
47432471Sbostic }
47532471Sbostic 
47632471Sbostic char	*
climb(c)47732471Sbostic climb(c)
47832471Sbostic {
47932471Sbostic 	dir = D_UP;
48032471Sbostic 	return (NULL);
48132471Sbostic }
48232471Sbostic 
48332471Sbostic char	*
descend(c)48432471Sbostic descend(c)
48532471Sbostic {
48632471Sbostic 	dir = D_DOWN;
48732471Sbostic 	return (NULL);
48832471Sbostic }
48932471Sbostic 
49032471Sbostic char	*
setalt(c)49132471Sbostic setalt(c)
49232471Sbostic {
49332471Sbostic 	if ((p.altitude == c - '0') && (p.new_altitude == p.altitude))
49432471Sbostic 		return ("Already at that altitude");
49532471Sbostic 	p.new_altitude = c - '0';
49632471Sbostic 	return (NULL);
49732471Sbostic }
49832471Sbostic 
49932471Sbostic char	*
setrelalt(c)50032471Sbostic setrelalt(c)
50132471Sbostic {
50232471Sbostic 	if (c == 0)
50332471Sbostic 		return ("altitude not changed");
50432471Sbostic 
50532471Sbostic 	switch (dir) {
50632471Sbostic 	case D_UP:
50732471Sbostic 		p.new_altitude = p.altitude + c - '0';
50832471Sbostic 		break;
50932471Sbostic 	case D_DOWN:
51032471Sbostic 		p.new_altitude = p.altitude - (c - '0');
51132471Sbostic 		break;
51232471Sbostic 	default:
51332471Sbostic 		return ("Unknown case in setrelalt!  Get help!");
51432471Sbostic 		break;
51532471Sbostic 	}
51632471Sbostic 	if (p.new_altitude < 0)
51732471Sbostic 		return ("Altitude would be too low");
51832471Sbostic 	else if (p.new_altitude > 9)
51932471Sbostic 		return ("Altitude would be too high");
52032471Sbostic 	return (NULL);
52132471Sbostic }
52232471Sbostic 
52332471Sbostic char	*
benum(c)52432471Sbostic benum(c)
52532471Sbostic {
52632471Sbostic 	dest_no = c -= '0';
52732471Sbostic 
52832471Sbostic 	switch (dest_type) {
52932471Sbostic 	case T_BEACON:
53032471Sbostic 		if (c >= sp->num_beacons)
53132471Sbostic 			return ("Unknown beacon");
53232471Sbostic 		p.new_dir = DIR_FROM_DXDY(sp->beacon[c].x - p.xpos,
53332471Sbostic 			sp->beacon[c].y - p.ypos);
53432471Sbostic 		break;
53532471Sbostic 	case T_EXIT:
53632471Sbostic 		if (c >= sp->num_exits)
53732471Sbostic 			return ("Unknown exit");
53832471Sbostic 		p.new_dir = DIR_FROM_DXDY(sp->exit[c].x - p.xpos,
53932471Sbostic 			sp->exit[c].y - p.ypos);
54032471Sbostic 		break;
54132471Sbostic 	case T_AIRPORT:
54232471Sbostic 		if (c >= sp->num_airports)
54332471Sbostic 			return ("Unknown airport");
54432471Sbostic 		p.new_dir = DIR_FROM_DXDY(sp->airport[c].x - p.xpos,
54532471Sbostic 			sp->airport[c].y - p.ypos);
54632471Sbostic 		break;
54732471Sbostic 	default:
54832471Sbostic 		return ("Unknown case in benum!  Get help!");
54932471Sbostic 		break;
55032471Sbostic 	}
55132471Sbostic 	return (NULL);
55232471Sbostic }
55332471Sbostic 
55432471Sbostic char	*
to_dir(c)55532471Sbostic to_dir(c)
55632471Sbostic {
55732471Sbostic 	p.new_dir = dir_no(c);
55832471Sbostic 	return (NULL);
55932471Sbostic }
56032471Sbostic 
56132471Sbostic char	*
rel_dir(c)56232471Sbostic rel_dir(c)
56332471Sbostic {
56432471Sbostic 	int	angle;
56532471Sbostic 
56632471Sbostic 	angle = dir_no(c);
56732471Sbostic 	switch (dir) {
56832471Sbostic 	case D_LEFT:
56932471Sbostic 		p.new_dir = p.dir - angle;
57032471Sbostic 		if (p.new_dir < 0)
57132471Sbostic 			p.new_dir += MAXDIR;
57232471Sbostic 		break;
57332471Sbostic 	case D_RIGHT:
57432471Sbostic 		p.new_dir = p.dir + angle;
57532471Sbostic 		if (p.new_dir >= MAXDIR)
57632471Sbostic 			p.new_dir -= MAXDIR;
57732471Sbostic 		break;
57832471Sbostic 	default:
57932471Sbostic 		return ("Bizarre direction in rel_dir!  Get help!");
58032471Sbostic 		break;
58132471Sbostic 	}
58232471Sbostic 	return (NULL);
58332471Sbostic }
58432471Sbostic 
58532471Sbostic char	*
mark(c)58632471Sbostic mark(c)
58732471Sbostic {
58832471Sbostic 	if (p.altitude == 0)
58932471Sbostic 		return ("Cannot mark planes on the ground");
59032471Sbostic 	if (p.status == S_MARKED)
59132471Sbostic 		return ("Already marked");
59232471Sbostic 	p.status = S_MARKED;
59332471Sbostic 	return (NULL);
59432471Sbostic }
59532471Sbostic 
59632471Sbostic char	*
unmark(c)59732471Sbostic unmark(c)
59832471Sbostic {
59932471Sbostic 	if (p.altitude == 0)
60032471Sbostic 		return ("Cannot unmark planes on the ground");
60132471Sbostic 	if (p.status == S_UNMARKED)
60232471Sbostic 		return ("Already unmarked");
60332471Sbostic 	p.status = S_UNMARKED;
60432471Sbostic 	return (NULL);
60532471Sbostic }
60632471Sbostic 
60732471Sbostic char	*
ignore(c)60832471Sbostic ignore(c)
60932471Sbostic {
61032471Sbostic 	if (p.altitude == 0)
61132471Sbostic 		return ("Cannot ignore planes on the ground");
61232471Sbostic 	if (p.status == S_IGNORED)
61332471Sbostic 		return ("Already ignored");
61432471Sbostic 	p.status = S_IGNORED;
61532471Sbostic 	return (NULL);
61632471Sbostic }
61732471Sbostic 
dir_no(ch)61832471Sbostic dir_no(ch)
61932471Sbostic 	char	ch;
62032471Sbostic {
62132471Sbostic 	int	dir;
62232471Sbostic 
62332471Sbostic 	switch (ch) {
62432471Sbostic 	case 'w':	dir = 0;	break;
62532471Sbostic 	case 'e':	dir = 1;	break;
62632471Sbostic 	case 'd':	dir = 2;	break;
62732471Sbostic 	case 'c':	dir = 3;	break;
62832471Sbostic 	case 'x':	dir = 4;	break;
62932471Sbostic 	case 'z':	dir = 5;	break;
63032471Sbostic 	case 'a':	dir = 6;	break;
63132471Sbostic 	case 'q':	dir = 7;	break;
63232471Sbostic 	default:
63332471Sbostic 		fprintf(stderr, "bad character in dir_no\n");
63432471Sbostic 		break;
63532471Sbostic 	}
63632471Sbostic 	return (dir);
63732471Sbostic }
638