1*41166Sbostic /*- 2*41166Sbostic * Copyright (c) 1990 The Regents of the University of California. 3*41166Sbostic * All rights reserved. 4*41166Sbostic * 5*41166Sbostic * This code is derived from software contributed to Berkeley by 6*41166Sbostic * Ed James. 7*41166Sbostic * 8*41166Sbostic * %sccs.include.redist.c% 9*41166Sbostic */ 10*41166Sbostic 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*41166Sbostic static char sccsid[] = "@(#)input.c 5.4 (Berkeley) 04/30/90"; 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 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 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 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 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 27232471Sbostic noise() 27332471Sbostic { 27432471Sbostic putchar('\07'); 27532471Sbostic fflush(stdout); 27632471Sbostic } 27732471Sbostic 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 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 * 45632471Sbostic beacon(c) 45732471Sbostic { 45832471Sbostic dest_type = T_BEACON; 45932471Sbostic return (NULL); 46032471Sbostic } 46132471Sbostic 46232471Sbostic char * 46332471Sbostic ex_it(c) 46432471Sbostic { 46532471Sbostic dest_type = T_EXIT; 46632471Sbostic return (NULL); 46732471Sbostic } 46832471Sbostic 46932471Sbostic char * 47032471Sbostic airport(c) 47132471Sbostic { 47232471Sbostic dest_type = T_AIRPORT; 47332471Sbostic return (NULL); 47432471Sbostic } 47532471Sbostic 47632471Sbostic char * 47732471Sbostic climb(c) 47832471Sbostic { 47932471Sbostic dir = D_UP; 48032471Sbostic return (NULL); 48132471Sbostic } 48232471Sbostic 48332471Sbostic char * 48432471Sbostic descend(c) 48532471Sbostic { 48632471Sbostic dir = D_DOWN; 48732471Sbostic return (NULL); 48832471Sbostic } 48932471Sbostic 49032471Sbostic char * 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 * 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 * 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 * 55532471Sbostic to_dir(c) 55632471Sbostic { 55732471Sbostic p.new_dir = dir_no(c); 55832471Sbostic return (NULL); 55932471Sbostic } 56032471Sbostic 56132471Sbostic char * 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 * 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 * 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 * 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 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