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