xref: /csrg-svn/games/atc/input.c (revision 32471)
1*32471Sbostic /*
2*32471Sbostic  * Copyright (c) 1987 by Ed James, UC Berkeley.  All rights reserved.
3*32471Sbostic  *
4*32471Sbostic  * Copy permission is hereby granted provided that this notice is
5*32471Sbostic  * retained on all partial or complete copies.
6*32471Sbostic  *
7*32471Sbostic  * For more info on this and all of my stuff, mail edjames@berkeley.edu.
8*32471Sbostic  */
9*32471Sbostic 
10*32471Sbostic #ifndef lint
11*32471Sbostic static char sccsid[] = "@(#)input.c	5.1 (Berkeley) 10/22/87";
12*32471Sbostic #endif not lint
13*32471Sbostic 
14*32471Sbostic #include "include.h"
15*32471Sbostic 
16*32471Sbostic #define MAXRULES	6
17*32471Sbostic #define MAXDEPTH	15
18*32471Sbostic 
19*32471Sbostic #define RETTOKEN	'\n'
20*32471Sbostic #ifdef SYSV
21*32471Sbostic #define CRTOKEN		'\r'
22*32471Sbostic #endif
23*32471Sbostic #define REDRAWTOKEN	'\014'	/* CTRL(L) */
24*32471Sbostic #define	SHELLTOKEN	'!'
25*32471Sbostic #define HELPTOKEN	'?'
26*32471Sbostic #define ALPHATOKEN	256
27*32471Sbostic #define NUMTOKEN	257
28*32471Sbostic 
29*32471Sbostic typedef struct {
30*32471Sbostic 	int	token;
31*32471Sbostic 	int	to_state;
32*32471Sbostic 	char	*str;
33*32471Sbostic 	char	*(*func)();
34*32471Sbostic } RULE;
35*32471Sbostic 
36*32471Sbostic typedef struct {
37*32471Sbostic 	int	num_rules;
38*32471Sbostic 	RULE	*rule;
39*32471Sbostic } STATE;
40*32471Sbostic 
41*32471Sbostic typedef struct {
42*32471Sbostic 	char	str[20];
43*32471Sbostic 	int	state;
44*32471Sbostic 	int	rule;
45*32471Sbostic 	int	ch;
46*32471Sbostic 	int	pos;
47*32471Sbostic } STACK;
48*32471Sbostic 
49*32471Sbostic #define T_RULE		stack[level].rule
50*32471Sbostic #define T_STATE		stack[level].state
51*32471Sbostic #define T_STR		stack[level].str
52*32471Sbostic #define T_POS		stack[level].pos
53*32471Sbostic #define	T_CH		stack[level].ch
54*32471Sbostic 
55*32471Sbostic #define NUMELS(a)	(sizeof (a) / sizeof (*(a)))
56*32471Sbostic 
57*32471Sbostic #define NUMSTATES	NUMELS(st)
58*32471Sbostic 
59*32471Sbostic char	*setplane(), *circle(), *left(), *right(), *Left(), *Right(),
60*32471Sbostic 	*beacon(), *ex_it(), *climb(), *descend(), *setalt(), *setrelalt(),
61*32471Sbostic 	*benum(), *to_dir(), *rel_dir(), *delayb(), *mark(), *unmark(),
62*32471Sbostic 	*airport(), *turn(), *ignore();
63*32471Sbostic 
64*32471Sbostic RULE	state0[] = {	{ ALPHATOKEN,	1,	"%c:",		setplane},
65*32471Sbostic 			{ RETTOKEN,	-1,	"",		NULL	},
66*32471Sbostic #ifdef SYSV
67*32471Sbostic 			{ CRTOKEN,	-1,	"",		NULL	},
68*32471Sbostic #endif
69*32471Sbostic 			{ HELPTOKEN,	12,	" [a-z]<ret>",	NULL	}},
70*32471Sbostic 	state1[] = {	{ 't',		2,	" turn",	turn	},
71*32471Sbostic 			{ 'a',		3,	" altitude:",	NULL	},
72*32471Sbostic 			{ 'c',		4,	" circle",	circle	},
73*32471Sbostic 			{ 'm',		7,	" mark",	mark	},
74*32471Sbostic 			{ 'u',		7,	" unmark",	unmark	},
75*32471Sbostic 			{ 'i',		7,	" ignore",	ignore	},
76*32471Sbostic 			{ HELPTOKEN,	12,	" tacmui",	NULL	}},
77*32471Sbostic 	state2[] = {	{ 'l',		6,	" left",	left	},
78*32471Sbostic 			{ 'r',		6,	" right",	right	},
79*32471Sbostic 			{ 'L',		4,	" left 90",	Left	},
80*32471Sbostic 			{ 'R',		4,	" right 90",	Right	},
81*32471Sbostic 			{ 't',		11,	" towards",	NULL	},
82*32471Sbostic 			{ 'w',		4,	" to 0",	to_dir	},
83*32471Sbostic 			{ 'e',		4,	" to 45",	to_dir	},
84*32471Sbostic 			{ 'd',		4,	" to 90",	to_dir	},
85*32471Sbostic 			{ 'c',		4,	" to 135",	to_dir	},
86*32471Sbostic 			{ 'x',		4,	" to 180",	to_dir	},
87*32471Sbostic 			{ 'z',		4,	" to 225",	to_dir	},
88*32471Sbostic 			{ 'a',		4,	" to 270",	to_dir	},
89*32471Sbostic 			{ 'q',		4,	" to 315",	to_dir	},
90*32471Sbostic 			{ HELPTOKEN,	12,	" lrLRt<dir>",	NULL	}},
91*32471Sbostic 	state3[] = {	{ '+',		10,	" climb",	climb	},
92*32471Sbostic 			{ 'c',		10,	" climb",	climb	},
93*32471Sbostic 			{ '-',		10,	" descend",	descend	},
94*32471Sbostic 			{ 'd',		10,	" descend",	descend	},
95*32471Sbostic 			{ NUMTOKEN,	7,	" %c000 feet",	setalt	},
96*32471Sbostic 			{ HELPTOKEN,	12,	" +-cd[0-9]",	NULL	}},
97*32471Sbostic 	state4[] = {	{ '@',		9,	" at",		NULL	},
98*32471Sbostic 			{ 'a',		9,	" at",		NULL	},
99*32471Sbostic 			{ RETTOKEN,	-1,	"",		NULL	},
100*32471Sbostic #ifdef SYSV
101*32471Sbostic 			{ CRTOKEN,	-1,	"",		NULL	},
102*32471Sbostic #endif
103*32471Sbostic 			{ HELPTOKEN,	12,	" @a<ret>",	NULL	}},
104*32471Sbostic 	state5[] = {	{ NUMTOKEN,	7,	"%c",		delayb	},
105*32471Sbostic 			{ HELPTOKEN,	12,	" [0-9]",	NULL	}},
106*32471Sbostic 	state6[] = {	{ '@',		9,	" at",		NULL	},
107*32471Sbostic 			{ 'a',		9,	" at",		NULL	},
108*32471Sbostic 			{ 'w',		4,	" 0",		rel_dir	},
109*32471Sbostic 			{ 'e',		4,	" 45",		rel_dir	},
110*32471Sbostic 			{ 'd',		4,	" 90",		rel_dir	},
111*32471Sbostic 			{ 'c',		4,	" 135",		rel_dir	},
112*32471Sbostic 			{ 'x',		4,	" 180",		rel_dir	},
113*32471Sbostic 			{ 'z',		4,	" 225",		rel_dir	},
114*32471Sbostic 			{ 'a',		4,	" 270",		rel_dir	},
115*32471Sbostic 			{ 'q',		4,	" 315",		rel_dir	},
116*32471Sbostic 			{ RETTOKEN,	-1,	"",		NULL	},
117*32471Sbostic #ifdef SYSV
118*32471Sbostic 			{ CRTOKEN,	-1,	"",		NULL	},
119*32471Sbostic #endif
120*32471Sbostic 			{ HELPTOKEN,	12,	" @a<dir><ret>",NULL	}},
121*32471Sbostic 	state7[] = {	{ RETTOKEN,	-1,	"",		NULL	},
122*32471Sbostic #ifdef SYSV
123*32471Sbostic 	            	{ CRTOKEN,	-1,	"",		NULL	},
124*32471Sbostic #endif
125*32471Sbostic 			{ HELPTOKEN,	12,	" <ret>",	NULL	}},
126*32471Sbostic 	state8[] = {	{ NUMTOKEN,	4,	"%c",		benum	},
127*32471Sbostic 			{ HELPTOKEN,	12,	" [0-9]",	NULL	}},
128*32471Sbostic 	state9[] = {	{ 'b',		5,	" beacon #",	NULL	},
129*32471Sbostic 			{ '*',		5,	" beacon #",	NULL	},
130*32471Sbostic 			{ HELPTOKEN,	12,	" b*",		NULL	}},
131*32471Sbostic 	state10[] = {	{ NUMTOKEN,	7,	" %c000 ft",	setrelalt},
132*32471Sbostic 			{ HELPTOKEN,	12,	" [0-9]",	NULL	}},
133*32471Sbostic 	state11[] = {	{ 'b',		8,	" beacon #",	beacon	},
134*32471Sbostic 			{ '*',		8,	" beacon #",	beacon	},
135*32471Sbostic 			{ 'e',		8,	" exit #",	ex_it	},
136*32471Sbostic 			{ 'a',		8,	" airport #",	airport	},
137*32471Sbostic 			{ HELPTOKEN,	12,	" b*ea",	NULL	}},
138*32471Sbostic 	state12[] = {	{ -1,		-1,	"",		NULL	}};
139*32471Sbostic 
140*32471Sbostic #define DEF_STATE(s)	{ NUMELS(s),	(s)	}
141*32471Sbostic 
142*32471Sbostic STATE	st[] = {
143*32471Sbostic 	DEF_STATE(state0), DEF_STATE(state1), DEF_STATE(state2),
144*32471Sbostic 	DEF_STATE(state3), DEF_STATE(state4), DEF_STATE(state5),
145*32471Sbostic 	DEF_STATE(state6), DEF_STATE(state7), DEF_STATE(state8),
146*32471Sbostic 	DEF_STATE(state9), DEF_STATE(state10), DEF_STATE(state11),
147*32471Sbostic 	DEF_STATE(state12)
148*32471Sbostic };
149*32471Sbostic 
150*32471Sbostic PLANE	p;
151*32471Sbostic STACK	stack[MAXDEPTH];
152*32471Sbostic int	level;
153*32471Sbostic int	tval;
154*32471Sbostic int	dest_type, dest_no, dir;
155*32471Sbostic 
156*32471Sbostic pop()
157*32471Sbostic {
158*32471Sbostic 	if (level == 0)
159*32471Sbostic 		return (-1);
160*32471Sbostic 	level--;
161*32471Sbostic 
162*32471Sbostic 	ioclrtoeol(T_POS);
163*32471Sbostic 
164*32471Sbostic 	strcpy(T_STR, "");
165*32471Sbostic 	T_RULE = -1;
166*32471Sbostic 	T_CH = -1;
167*32471Sbostic 	return (0);
168*32471Sbostic }
169*32471Sbostic 
170*32471Sbostic rezero()
171*32471Sbostic {
172*32471Sbostic 	iomove(0);
173*32471Sbostic 
174*32471Sbostic 	level = 0;
175*32471Sbostic 	T_STATE = 0;
176*32471Sbostic 	T_RULE = -1;
177*32471Sbostic 	T_CH = -1;
178*32471Sbostic 	T_POS = 0;
179*32471Sbostic 	strcpy(T_STR, "");
180*32471Sbostic }
181*32471Sbostic 
182*32471Sbostic push(ruleno, ch)
183*32471Sbostic {
184*32471Sbostic 	int	newstate, newpos;
185*32471Sbostic 
186*32471Sbostic 	sprintf(T_STR, st[T_STATE].rule[ruleno].str, tval);
187*32471Sbostic 	T_RULE = ruleno;
188*32471Sbostic 	T_CH = ch;
189*32471Sbostic 	newstate = st[T_STATE].rule[ruleno].to_state;
190*32471Sbostic 	newpos = T_POS + strlen(T_STR);
191*32471Sbostic 
192*32471Sbostic 	ioaddstr(T_POS, T_STR);
193*32471Sbostic 
194*32471Sbostic 	if (level == 0)
195*32471Sbostic 		ioclrtobot();
196*32471Sbostic 	level++;
197*32471Sbostic 	T_STATE = newstate;
198*32471Sbostic 	T_POS = newpos;
199*32471Sbostic 	T_RULE = -1;
200*32471Sbostic 	strcpy(T_STR, "");
201*32471Sbostic }
202*32471Sbostic 
203*32471Sbostic getcommand()
204*32471Sbostic {
205*32471Sbostic 	int	c, i, done;
206*32471Sbostic 	char	*s, *(*func)();
207*32471Sbostic 	PLANE	*pp;
208*32471Sbostic 
209*32471Sbostic 	rezero();
210*32471Sbostic 
211*32471Sbostic 	do {
212*32471Sbostic 		c = gettoken();
213*32471Sbostic 		if (c == tty_new.sg_erase) {
214*32471Sbostic 			if (pop() < 0)
215*32471Sbostic 				noise();
216*32471Sbostic 		} else if (c == tty_new.sg_kill) {
217*32471Sbostic 			while (pop() >= 0)
218*32471Sbostic 				;
219*32471Sbostic 		} else {
220*32471Sbostic 			done = 0;
221*32471Sbostic 			for (i = 0; i < st[T_STATE].num_rules; i++) {
222*32471Sbostic 				if (st[T_STATE].rule[i].token == c ||
223*32471Sbostic 				    st[T_STATE].rule[i].token == tval) {
224*32471Sbostic 					push(i, (c >= ALPHATOKEN) ? tval : c);
225*32471Sbostic 					done = 1;
226*32471Sbostic 					break;
227*32471Sbostic 				}
228*32471Sbostic 			}
229*32471Sbostic 			if (!done)
230*32471Sbostic 				noise();
231*32471Sbostic 		}
232*32471Sbostic 	} while (T_STATE != -1);
233*32471Sbostic 
234*32471Sbostic 	if (level == 1)
235*32471Sbostic 		return (1);	/* forced update */
236*32471Sbostic 
237*32471Sbostic 	dest_type = T_NODEST;
238*32471Sbostic 
239*32471Sbostic 	for (i = 0; i < level; i++) {
240*32471Sbostic 		func = st[stack[i].state].rule[stack[i].rule].func;
241*32471Sbostic 		if (func != NULL)
242*32471Sbostic 			if ((s = (*func)(stack[i].ch)) != NULL) {
243*32471Sbostic 				ioerror(stack[i].pos, strlen(stack[i].str), s);
244*32471Sbostic 				return (-1);
245*32471Sbostic 			}
246*32471Sbostic 	}
247*32471Sbostic 
248*32471Sbostic 	pp = findplane(p.plane_no);
249*32471Sbostic 	if (pp->new_altitude != p.new_altitude)
250*32471Sbostic 		pp->new_altitude = p.new_altitude;
251*32471Sbostic 	else if (pp->status != p.status)
252*32471Sbostic 		pp->status = p.status;
253*32471Sbostic 	else {
254*32471Sbostic 		pp->new_dir = p.new_dir;
255*32471Sbostic 		pp->delayd = p.delayd;
256*32471Sbostic 		pp->delayd_no = p.delayd_no;
257*32471Sbostic 	}
258*32471Sbostic 	return (0);
259*32471Sbostic }
260*32471Sbostic 
261*32471Sbostic noise()
262*32471Sbostic {
263*32471Sbostic 	putchar('\07');
264*32471Sbostic 	fflush(stdout);
265*32471Sbostic }
266*32471Sbostic 
267*32471Sbostic gettoken()
268*32471Sbostic {
269*32471Sbostic 	while ((tval = getAChar()) == REDRAWTOKEN || tval == SHELLTOKEN)
270*32471Sbostic 	{
271*32471Sbostic 		if (tval == SHELLTOKEN)
272*32471Sbostic 		{
273*32471Sbostic #ifdef BSD
274*32471Sbostic 			struct itimerval	itv;
275*32471Sbostic 			itv.it_value.tv_sec = 0;
276*32471Sbostic 			itv.it_value.tv_usec = 0;
277*32471Sbostic 			setitimer(ITIMER_REAL, &itv, NULL);
278*32471Sbostic #endif
279*32471Sbostic #ifdef SYSV
280*32471Sbostic 			int aval;
281*32471Sbostic 			aval = alarm(0);
282*32471Sbostic #endif
283*32471Sbostic 			if (fork() == 0)	/* child */
284*32471Sbostic 			{
285*32471Sbostic 				char *shell, *base, *getenv(), *strrchr();
286*32471Sbostic 
287*32471Sbostic 				setuid(getuid()); /* turn off setuid bit */
288*32471Sbostic 				done_screen();
289*32471Sbostic 
290*32471Sbostic 						 /* run user's favorite shell */
291*32471Sbostic 				if ((shell = getenv("SHELL")) != NULL)
292*32471Sbostic 				{
293*32471Sbostic 					base = strrchr(shell, '/');
294*32471Sbostic 					if (base == NULL)
295*32471Sbostic 						base = shell;
296*32471Sbostic 					else
297*32471Sbostic 						base++;
298*32471Sbostic 					execl(shell, base, 0);
299*32471Sbostic 				}
300*32471Sbostic 				else
301*32471Sbostic 					execl("/bin/sh", "sh", 0);
302*32471Sbostic 
303*32471Sbostic 				exit(0);	/* oops */
304*32471Sbostic 			}
305*32471Sbostic 
306*32471Sbostic 			wait(0);
307*32471Sbostic #ifdef BSD
308*32471Sbostic 			ioctl(fileno(stdin), TIOCSETP, &tty_new);
309*32471Sbostic 			itv.it_value.tv_sec = 0;
310*32471Sbostic 			itv.it_value.tv_usec = 1;
311*32471Sbostic 			itv.it_interval.tv_sec = sp->update_secs;
312*32471Sbostic 			itv.it_interval.tv_usec = 0;
313*32471Sbostic 			setitimer(ITIMER_REAL, &itv, NULL);
314*32471Sbostic #endif
315*32471Sbostic #ifdef SYSV
316*32471Sbostic 			ioctl(fileno(stdin), TCSETAW, &tty_new);
317*32471Sbostic 			alarm(aval);
318*32471Sbostic #endif
319*32471Sbostic 		}
320*32471Sbostic 		redraw();
321*32471Sbostic 	}
322*32471Sbostic 
323*32471Sbostic 	if (isdigit(tval))
324*32471Sbostic 		return (NUMTOKEN);
325*32471Sbostic 	else if (isalpha(tval))
326*32471Sbostic 		return (ALPHATOKEN);
327*32471Sbostic 	else
328*32471Sbostic 		return (tval);
329*32471Sbostic }
330*32471Sbostic 
331*32471Sbostic char	*
332*32471Sbostic setplane(c)
333*32471Sbostic {
334*32471Sbostic 	PLANE	*pp;
335*32471Sbostic 
336*32471Sbostic 	pp = findplane(number(c));
337*32471Sbostic 	if (pp == NULL)
338*32471Sbostic 		return ("Unknown Plane");
339*32471Sbostic 	bcopy(pp, &p, sizeof (p));
340*32471Sbostic 	p.delayd = 0;
341*32471Sbostic 	return (NULL);
342*32471Sbostic }
343*32471Sbostic 
344*32471Sbostic char	*
345*32471Sbostic turn(c)
346*32471Sbostic {
347*32471Sbostic 	if (p.altitude == 0)
348*32471Sbostic 		return ("Planes at airports may not change direction");
349*32471Sbostic 	return (NULL);
350*32471Sbostic }
351*32471Sbostic 
352*32471Sbostic char	*
353*32471Sbostic circle(c)
354*32471Sbostic {
355*32471Sbostic 	if (p.altitude == 0)
356*32471Sbostic 		return ("Planes cannot circle on the ground");
357*32471Sbostic 	p.new_dir = MAXDIR;
358*32471Sbostic 	return (NULL);
359*32471Sbostic }
360*32471Sbostic 
361*32471Sbostic char	*
362*32471Sbostic left(c)
363*32471Sbostic {
364*32471Sbostic 	dir = D_LEFT;
365*32471Sbostic 	p.new_dir = p.dir - 1;
366*32471Sbostic 	if (p.new_dir < 0)
367*32471Sbostic 		p.new_dir += MAXDIR;
368*32471Sbostic 	return (NULL);
369*32471Sbostic }
370*32471Sbostic 
371*32471Sbostic char	*
372*32471Sbostic right(c)
373*32471Sbostic {
374*32471Sbostic 	dir = D_RIGHT;
375*32471Sbostic 	p.new_dir = p.dir + 1;
376*32471Sbostic 	if (p.new_dir > MAXDIR)
377*32471Sbostic 		p.new_dir -= MAXDIR;
378*32471Sbostic 	return (NULL);
379*32471Sbostic }
380*32471Sbostic 
381*32471Sbostic char	*
382*32471Sbostic Left(c)
383*32471Sbostic {
384*32471Sbostic 	p.new_dir = p.dir - 2;
385*32471Sbostic 	if (p.new_dir < 0)
386*32471Sbostic 		p.new_dir += MAXDIR;
387*32471Sbostic 	return (NULL);
388*32471Sbostic }
389*32471Sbostic 
390*32471Sbostic char	*
391*32471Sbostic Right(c)
392*32471Sbostic {
393*32471Sbostic 	p.new_dir = p.dir + 2;
394*32471Sbostic 	if (p.new_dir > MAXDIR)
395*32471Sbostic 		p.new_dir -= MAXDIR;
396*32471Sbostic 	return (NULL);
397*32471Sbostic }
398*32471Sbostic 
399*32471Sbostic char	*
400*32471Sbostic delayb(c)
401*32471Sbostic {
402*32471Sbostic 	int	xdiff, ydiff;
403*32471Sbostic 
404*32471Sbostic 	c -= '0';
405*32471Sbostic 
406*32471Sbostic 	if (c >= sp->num_beacons)
407*32471Sbostic 		return ("Unknown beacon");
408*32471Sbostic 	xdiff = sp->beacon[c].x - p.xpos;
409*32471Sbostic 	xdiff = SGN(xdiff);
410*32471Sbostic 	ydiff = sp->beacon[c].y - p.ypos;
411*32471Sbostic 	ydiff = SGN(ydiff);
412*32471Sbostic 	if (xdiff != displacement[p.dir].dx || ydiff != displacement[p.dir].dy)
413*32471Sbostic 		return ("Beacon is not in flight path");
414*32471Sbostic 	p.delayd = 1;
415*32471Sbostic 	p.delayd_no = c;
416*32471Sbostic 
417*32471Sbostic 	if (dest_type != T_NODEST) {
418*32471Sbostic 		switch (dest_type) {
419*32471Sbostic 		case T_BEACON:
420*32471Sbostic 			xdiff = sp->beacon[dest_no].x - sp->beacon[c].x;
421*32471Sbostic 			ydiff = sp->beacon[dest_no].y - sp->beacon[c].y;
422*32471Sbostic 			break;
423*32471Sbostic 		case T_EXIT:
424*32471Sbostic 			xdiff = sp->exit[dest_no].x - sp->beacon[c].x;
425*32471Sbostic 			ydiff = sp->exit[dest_no].y - sp->beacon[c].y;
426*32471Sbostic 			break;
427*32471Sbostic 		case T_AIRPORT:
428*32471Sbostic 			xdiff = sp->airport[dest_no].x - sp->beacon[c].x;
429*32471Sbostic 			ydiff = sp->airport[dest_no].y - sp->beacon[c].y;
430*32471Sbostic 			break;
431*32471Sbostic 		default:
432*32471Sbostic 			return ("Bad case in delayb!  Get help!");
433*32471Sbostic 			break;
434*32471Sbostic 		}
435*32471Sbostic 		if (xdiff == 0 && ydiff == 0)
436*32471Sbostic 			return ("Would already be there");
437*32471Sbostic 		p.new_dir = DIR_FROM_DXDY(xdiff, ydiff);
438*32471Sbostic 		if (p.new_dir == p.dir)
439*32471Sbostic 			return ("Already going in that direction");
440*32471Sbostic 	}
441*32471Sbostic 	return (NULL);
442*32471Sbostic }
443*32471Sbostic 
444*32471Sbostic char	*
445*32471Sbostic beacon(c)
446*32471Sbostic {
447*32471Sbostic 	dest_type = T_BEACON;
448*32471Sbostic 	return (NULL);
449*32471Sbostic }
450*32471Sbostic 
451*32471Sbostic char	*
452*32471Sbostic ex_it(c)
453*32471Sbostic {
454*32471Sbostic 	dest_type = T_EXIT;
455*32471Sbostic 	return (NULL);
456*32471Sbostic }
457*32471Sbostic 
458*32471Sbostic char	*
459*32471Sbostic airport(c)
460*32471Sbostic {
461*32471Sbostic 	dest_type = T_AIRPORT;
462*32471Sbostic 	return (NULL);
463*32471Sbostic }
464*32471Sbostic 
465*32471Sbostic char	*
466*32471Sbostic climb(c)
467*32471Sbostic {
468*32471Sbostic 	dir = D_UP;
469*32471Sbostic 	return (NULL);
470*32471Sbostic }
471*32471Sbostic 
472*32471Sbostic char	*
473*32471Sbostic descend(c)
474*32471Sbostic {
475*32471Sbostic 	dir = D_DOWN;
476*32471Sbostic 	return (NULL);
477*32471Sbostic }
478*32471Sbostic 
479*32471Sbostic char	*
480*32471Sbostic setalt(c)
481*32471Sbostic {
482*32471Sbostic 	if ((p.altitude == c - '0') && (p.new_altitude == p.altitude))
483*32471Sbostic 		return ("Already at that altitude");
484*32471Sbostic 	p.new_altitude = c - '0';
485*32471Sbostic 	return (NULL);
486*32471Sbostic }
487*32471Sbostic 
488*32471Sbostic char	*
489*32471Sbostic setrelalt(c)
490*32471Sbostic {
491*32471Sbostic 	if (c == 0)
492*32471Sbostic 		return ("altitude not changed");
493*32471Sbostic 
494*32471Sbostic 	switch (dir) {
495*32471Sbostic 	case D_UP:
496*32471Sbostic 		p.new_altitude = p.altitude + c - '0';
497*32471Sbostic 		break;
498*32471Sbostic 	case D_DOWN:
499*32471Sbostic 		p.new_altitude = p.altitude - (c - '0');
500*32471Sbostic 		break;
501*32471Sbostic 	default:
502*32471Sbostic 		return ("Unknown case in setrelalt!  Get help!");
503*32471Sbostic 		break;
504*32471Sbostic 	}
505*32471Sbostic 	if (p.new_altitude < 0)
506*32471Sbostic 		return ("Altitude would be too low");
507*32471Sbostic 	else if (p.new_altitude > 9)
508*32471Sbostic 		return ("Altitude would be too high");
509*32471Sbostic 	return (NULL);
510*32471Sbostic }
511*32471Sbostic 
512*32471Sbostic char	*
513*32471Sbostic benum(c)
514*32471Sbostic {
515*32471Sbostic 	dest_no = c -= '0';
516*32471Sbostic 
517*32471Sbostic 	switch (dest_type) {
518*32471Sbostic 	case T_BEACON:
519*32471Sbostic 		if (c >= sp->num_beacons)
520*32471Sbostic 			return ("Unknown beacon");
521*32471Sbostic 		p.new_dir = DIR_FROM_DXDY(sp->beacon[c].x - p.xpos,
522*32471Sbostic 			sp->beacon[c].y - p.ypos);
523*32471Sbostic 		break;
524*32471Sbostic 	case T_EXIT:
525*32471Sbostic 		if (c >= sp->num_exits)
526*32471Sbostic 			return ("Unknown exit");
527*32471Sbostic 		p.new_dir = DIR_FROM_DXDY(sp->exit[c].x - p.xpos,
528*32471Sbostic 			sp->exit[c].y - p.ypos);
529*32471Sbostic 		break;
530*32471Sbostic 	case T_AIRPORT:
531*32471Sbostic 		if (c >= sp->num_airports)
532*32471Sbostic 			return ("Unknown airport");
533*32471Sbostic 		p.new_dir = DIR_FROM_DXDY(sp->airport[c].x - p.xpos,
534*32471Sbostic 			sp->airport[c].y - p.ypos);
535*32471Sbostic 		break;
536*32471Sbostic 	default:
537*32471Sbostic 		return ("Unknown case in benum!  Get help!");
538*32471Sbostic 		break;
539*32471Sbostic 	}
540*32471Sbostic 	return (NULL);
541*32471Sbostic }
542*32471Sbostic 
543*32471Sbostic char	*
544*32471Sbostic to_dir(c)
545*32471Sbostic {
546*32471Sbostic 	p.new_dir = dir_no(c);
547*32471Sbostic 	return (NULL);
548*32471Sbostic }
549*32471Sbostic 
550*32471Sbostic char	*
551*32471Sbostic rel_dir(c)
552*32471Sbostic {
553*32471Sbostic 	int	angle;
554*32471Sbostic 
555*32471Sbostic 	angle = dir_no(c);
556*32471Sbostic 	switch (dir) {
557*32471Sbostic 	case D_LEFT:
558*32471Sbostic 		p.new_dir = p.dir - angle;
559*32471Sbostic 		if (p.new_dir < 0)
560*32471Sbostic 			p.new_dir += MAXDIR;
561*32471Sbostic 		break;
562*32471Sbostic 	case D_RIGHT:
563*32471Sbostic 		p.new_dir = p.dir + angle;
564*32471Sbostic 		if (p.new_dir >= MAXDIR)
565*32471Sbostic 			p.new_dir -= MAXDIR;
566*32471Sbostic 		break;
567*32471Sbostic 	default:
568*32471Sbostic 		return ("Bizarre direction in rel_dir!  Get help!");
569*32471Sbostic 		break;
570*32471Sbostic 	}
571*32471Sbostic 	return (NULL);
572*32471Sbostic }
573*32471Sbostic 
574*32471Sbostic char	*
575*32471Sbostic mark(c)
576*32471Sbostic {
577*32471Sbostic 	if (p.altitude == 0)
578*32471Sbostic 		return ("Cannot mark planes on the ground");
579*32471Sbostic 	if (p.status == S_MARKED)
580*32471Sbostic 		return ("Already marked");
581*32471Sbostic 	p.status = S_MARKED;
582*32471Sbostic 	return (NULL);
583*32471Sbostic }
584*32471Sbostic 
585*32471Sbostic char	*
586*32471Sbostic unmark(c)
587*32471Sbostic {
588*32471Sbostic 	if (p.altitude == 0)
589*32471Sbostic 		return ("Cannot unmark planes on the ground");
590*32471Sbostic 	if (p.status == S_UNMARKED)
591*32471Sbostic 		return ("Already unmarked");
592*32471Sbostic 	p.status = S_UNMARKED;
593*32471Sbostic 	return (NULL);
594*32471Sbostic }
595*32471Sbostic 
596*32471Sbostic char	*
597*32471Sbostic ignore(c)
598*32471Sbostic {
599*32471Sbostic 	if (p.altitude == 0)
600*32471Sbostic 		return ("Cannot ignore planes on the ground");
601*32471Sbostic 	if (p.status == S_IGNORED)
602*32471Sbostic 		return ("Already ignored");
603*32471Sbostic 	p.status = S_IGNORED;
604*32471Sbostic 	return (NULL);
605*32471Sbostic }
606*32471Sbostic 
607*32471Sbostic dir_no(ch)
608*32471Sbostic 	char	ch;
609*32471Sbostic {
610*32471Sbostic 	int	dir;
611*32471Sbostic 
612*32471Sbostic 	switch (ch) {
613*32471Sbostic 	case 'w':	dir = 0;	break;
614*32471Sbostic 	case 'e':	dir = 1;	break;
615*32471Sbostic 	case 'd':	dir = 2;	break;
616*32471Sbostic 	case 'c':	dir = 3;	break;
617*32471Sbostic 	case 'x':	dir = 4;	break;
618*32471Sbostic 	case 'z':	dir = 5;	break;
619*32471Sbostic 	case 'a':	dir = 6;	break;
620*32471Sbostic 	case 'q':	dir = 7;	break;
621*32471Sbostic 	default:
622*32471Sbostic 		fprintf(stderr, "bad character in dir_no\n");
623*32471Sbostic 		break;
624*32471Sbostic 	}
625*32471Sbostic 	return (dir);
626*32471Sbostic }
627