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