|
|
1.1 ! root 1: /* ! 2: * Hunt ! 3: * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold ! 4: * San Francisco, California ! 5: * ! 6: * Copyright (c) 1985 Regents of the University of California. ! 7: * All rights reserved. The Berkeley software License Agreement ! 8: * specifies the terms and conditions for redistribution. ! 9: */ ! 10: ! 11: # include <curses.h> ! 12: # include <ctype.h> ! 13: # include <signal.h> ! 14: # include <errno.h> ! 15: # include "hunt.h" ! 16: # include <sys/file.h> ! 17: # ifdef TERMINFO ! 18: # include <term.h> ! 19: ! 20: # define AM auto_right_margin ! 21: # define XN eat_newline_glitch ! 22: # define CL clear_screen ! 23: # define CE clr_eol ! 24: # define _putchar _outchar ! 25: # endif ! 26: ! 27: int input(); ! 28: static int nchar_send; ! 29: static int in = FREAD; ! 30: char screen[SCREEN_HEIGHT][SCREEN_WIDTH2], blanks[SCREEN_WIDTH]; ! 31: int cur_row, cur_col; ! 32: # ifdef OTTO ! 33: int Otto_count; ! 34: int Otto_mode; ! 35: static int otto_y, otto_x; ! 36: static char otto_face; ! 37: # endif OTTO ! 38: ! 39: # define MAX_SEND 5 ! 40: ! 41: /* ! 42: * ibuf is the input buffer used for the stream from the driver. ! 43: * It is small because we do not check for user input when there ! 44: * are characters in the input buffer. ! 45: */ ! 46: static char ibuf[20]; ! 47: ! 48: #define GETCHR(fd) (--(fd)->_cnt < 0 ? getchr(fd) \ ! 49: : *((unsigned char *) (fd)->_ptr++)) ! 50: ! 51: /* ! 52: * playit: ! 53: * Play a given game, handling all the curses commands from ! 54: * the driver. ! 55: */ ! 56: playit() ! 57: { ! 58: register FILE *inf; ! 59: register int ch; ! 60: register int y, x; ! 61: extern int errno; ! 62: extern int _putchar(); ! 63: long version; ! 64: ! 65: if (read(Socket, (char *) &version, LONGLEN) != LONGLEN) { ! 66: bad_con(); ! 67: /* NOTREACHED */ ! 68: } ! 69: if (ntohl(version) != HUNT_VERSION) { ! 70: bad_ver(); ! 71: /* NOTREACHED */ ! 72: } ! 73: errno = 0; ! 74: while ((inf = fdopen(Socket, "r")) == NULL) ! 75: if (errno == EINTR) ! 76: errno = 0; ! 77: else { ! 78: perror("fdopen of socket"); ! 79: exit(1); ! 80: } ! 81: # ifdef L_ctermid ! 82: setvbuf(inf, ibuf, _IOFBF, sizeof ibuf); ! 83: # else ! 84: setbuffer(inf, ibuf, sizeof ibuf); ! 85: # endif ! 86: # ifdef OTTO ! 87: Otto_count = 0; ! 88: # endif OTTO ! 89: nchar_send = MAX_SEND; ! 90: while ((ch = GETCHR(inf)) != EOF) { ! 91: # ifdef DEBUG ! 92: fputc(ch, stderr); ! 93: # endif DEBUG ! 94: switch (ch & 0377) { ! 95: case MOVE: ! 96: y = GETCHR(inf); ! 97: x = GETCHR(inf); ! 98: mvcur(cur_row, cur_col, y, x); ! 99: cur_row = y; ! 100: cur_col = x; ! 101: break; ! 102: case ADDCH: ! 103: ch = GETCHR(inf); ! 104: # ifdef OTTO ! 105: switch (ch) { ! 106: ! 107: case '<': ! 108: case '>': ! 109: case '^': ! 110: case 'v': ! 111: otto_face = ch; ! 112: otto_y = cur_row; ! 113: otto_x = cur_col; ! 114: break; ! 115: } ! 116: # endif OTTO ! 117: put_ch(ch); ! 118: break; ! 119: case CLRTOEOL: ! 120: clear_eol(); ! 121: break; ! 122: case CLEAR: ! 123: clear_the_screen(); ! 124: break; ! 125: case REFRESH: ! 126: fflush(stdout); ! 127: break; ! 128: case REDRAW: ! 129: redraw_screen(); ! 130: fflush(stdout); ! 131: break; ! 132: case ENDWIN: ! 133: fflush(stdout); ! 134: if ((ch = GETCHR(inf)) == LAST_PLAYER) ! 135: Last_player = TRUE; ! 136: ch = EOF; ! 137: goto out; ! 138: case BELL: ! 139: putchar(CTRL(G)); ! 140: break; ! 141: case READY: ! 142: (void) fflush(stdout); ! 143: if (nchar_send < 0) ! 144: # ifndef TCFLSH ! 145: (void) ioctl(fileno(stdin), TIOCFLUSH, &in); ! 146: # else ! 147: (void) ioctl(fileno(stdin), TCFLSH, 0); ! 148: # endif ! 149: nchar_send = MAX_SEND; ! 150: # ifndef OTTO ! 151: (void) GETCHR(inf); ! 152: # else OTTO ! 153: Otto_count -= (GETCHR(inf) & 255); ! 154: if (!Am_monitor) { ! 155: # ifdef DEBUG ! 156: fputc('0' + Otto_count, stderr); ! 157: # endif DEBUG ! 158: if (Otto_count == 0 && Otto_mode) ! 159: otto(otto_y, otto_x, otto_face); ! 160: } ! 161: # endif OTTO ! 162: break; ! 163: default: ! 164: # ifdef OTTO ! 165: switch (ch) { ! 166: ! 167: case '<': ! 168: case '>': ! 169: case '^': ! 170: case 'v': ! 171: otto_face = ch; ! 172: otto_y = cur_row; ! 173: otto_x = cur_col; ! 174: break; ! 175: } ! 176: # endif OTTO ! 177: put_ch(ch); ! 178: break; ! 179: } ! 180: } ! 181: out: ! 182: (void) fclose(inf); ! 183: } ! 184: ! 185: /* ! 186: * getchr: ! 187: * Grab input and pass it along to the driver ! 188: * Return any characters from the driver ! 189: * When this routine is called by GETCHR, we already know there are ! 190: * no characters in the input buffer. ! 191: */ ! 192: getchr(fd) ! 193: register FILE *fd; ! 194: { ! 195: long readfds, s_readfds; ! 196: int driver_mask, stdin_mask; ! 197: int nfds, s_nfds; ! 198: ! 199: driver_mask = 1L << fileno(fd); ! 200: stdin_mask = 1L << fileno(stdin); ! 201: s_readfds = driver_mask | stdin_mask; ! 202: s_nfds = (fileno(fd) > fileno(stdin)) ? fileno(fd) : fileno(stdin); ! 203: s_nfds++; ! 204: ! 205: one_more_time: ! 206: do { ! 207: errno = 0; ! 208: readfds = s_readfds; ! 209: nfds = s_nfds; ! 210: nfds = select(nfds, &readfds, NULL, NULL, NULL); ! 211: } while (nfds <= 0 && errno == EINTR); ! 212: ! 213: if (readfds & stdin_mask) ! 214: send_stuff(); ! 215: if ((readfds & driver_mask) == 0) ! 216: goto one_more_time; ! 217: return _filbuf(fd); ! 218: } ! 219: ! 220: /* ! 221: * send_stuff: ! 222: * Send standard input characters to the driver ! 223: */ ! 224: send_stuff() ! 225: { ! 226: register int count; ! 227: register char *sp, *nsp; ! 228: static char inp[sizeof Buf]; ! 229: ! 230: count = read(fileno(stdin), Buf, sizeof Buf); ! 231: if (count <= 0) ! 232: return; ! 233: if (nchar_send <= 0 && !no_beep) { ! 234: (void) write(1, "\7", 1); /* CTRL(G) */ ! 235: return; ! 236: } ! 237: ! 238: /* ! 239: * look for 'q'uit commands; if we find one, ! 240: * confirm it. If it is not confirmed, strip ! 241: * it out of the input ! 242: */ ! 243: Buf[count] = '\0'; ! 244: nsp = inp; ! 245: for (sp = Buf; *sp != '\0'; sp++) ! 246: if ((*nsp = map_key[*sp]) == 'q') ! 247: intr(); ! 248: else ! 249: nsp++; ! 250: count = nsp - inp; ! 251: if (count) { ! 252: # ifdef OTTO ! 253: Otto_count += count; ! 254: # endif OTTO ! 255: nchar_send -= count; ! 256: if (nchar_send < 0) ! 257: count += nchar_send; ! 258: (void) write(Socket, inp, count); ! 259: } ! 260: } ! 261: ! 262: /* ! 263: * quit: ! 264: * Handle the end of the game when the player dies ! 265: */ ! 266: long ! 267: quit(old_status) ! 268: long old_status; ! 269: { ! 270: register int explain, ch; ! 271: ! 272: if (Last_player) ! 273: return Q_QUIT; ! 274: # ifdef OTTO ! 275: if (Otto_mode) ! 276: return Q_CLOAK; ! 277: # endif OTTO ! 278: mvcur(cur_row, cur_col, HEIGHT, 0); ! 279: cur_row = HEIGHT; ! 280: cur_col = 0; ! 281: put_str("Re-enter game [ynwo]? "); ! 282: clear_eol(); ! 283: fflush(stdout); ! 284: explain = FALSE; ! 285: for (;;) { ! 286: if (isupper(ch = getchar())) ! 287: ch = tolower(ch); ! 288: if (ch == 'y') ! 289: return old_status; ! 290: else if (ch == 'o') ! 291: break; ! 292: else if (ch == 'n') { ! 293: # ifndef INTERNET ! 294: return Q_QUIT; ! 295: # else ! 296: mvcur(cur_row, cur_col, HEIGHT, 0); ! 297: cur_row = HEIGHT; ! 298: cur_col = 0; ! 299: put_str("Write a parting message [yn]? "); ! 300: clear_eol(); ! 301: for (;;) { ! 302: if (isupper(ch = getchar())) ! 303: ch = tolower(ch); ! 304: if (ch == 'y') ! 305: goto get_message; ! 306: if (ch == 'n') ! 307: return Q_QUIT; ! 308: } ! 309: # endif ! 310: } ! 311: # ifdef INTERNET ! 312: else if (ch == 'w') { ! 313: static char buf[WIDTH + WIDTH % 2]; ! 314: char *cp, c; ! 315: ! 316: get_message: ! 317: c = ch; /* save how we got here */ ! 318: mvcur(cur_row, cur_col, HEIGHT, 0); ! 319: cur_row = HEIGHT; ! 320: cur_col = 0; ! 321: put_str("Message: "); ! 322: clear_eol(); ! 323: cp = buf; ! 324: while ((ch = getchar()) != '\n' && ch != '\r') { ! 325: # ifdef TERMINFO ! 326: if (ch == erasechar()) ! 327: # else ! 328: if (ch == _tty.sg_erase) ! 329: # endif ! 330: { ! 331: if (cp > buf) { ! 332: mvcur(cur_row, cur_col, cur_row, ! 333: cur_col - 1); ! 334: cur_col -= 1; ! 335: cp -= 1; ! 336: clear_eol(); ! 337: } ! 338: continue; ! 339: # ifdef TERMINFO ! 340: } else if (ch == killchar()) { ! 341: # else ! 342: } else if (ch == _tty.sg_kill) { ! 343: # endif ! 344: mvcur(cur_row, cur_col, cur_row, ! 345: cur_col - (cp - buf)); ! 346: cur_col -= cp - buf; ! 347: cp = buf; ! 348: clear_eol(); ! 349: continue; ! 350: } ! 351: put_ch(ch); ! 352: *cp++ = ch; ! 353: if (cp + 1 >= buf + sizeof buf) ! 354: break; ! 355: } ! 356: *cp = '\0'; ! 357: Send_message = buf; ! 358: return (c == 'w') ? old_status : Q_MESSAGE; ! 359: } ! 360: # endif INTERNET ! 361: (void) putchar(CTRL(G)); ! 362: if (!explain) { ! 363: put_str("(Yes, No, Write message, or Options) "); ! 364: explain = TRUE; ! 365: } ! 366: fflush(stdout); ! 367: } ! 368: ! 369: mvcur(cur_row, cur_col, HEIGHT, 0); ! 370: cur_row = HEIGHT; ! 371: cur_col = 0; ! 372: # ifdef FLY ! 373: put_str("Scan, Cloak, Flying, or Quit? "); ! 374: # else ! 375: put_str("Scan, Cloak, or Quit? "); ! 376: # endif FLY ! 377: clear_eol(); ! 378: fflush(stdout); ! 379: explain = FALSE; ! 380: for (;;) { ! 381: if (isupper(ch = getchar())) ! 382: ch = tolower(ch); ! 383: if (ch == 's') ! 384: return Q_SCAN; ! 385: else if (ch == 'c') ! 386: return Q_CLOAK; ! 387: # ifdef FLY ! 388: else if (ch == 'f') ! 389: return Q_FLY; ! 390: # endif FLY ! 391: else if (ch == 'q') ! 392: return Q_QUIT; ! 393: (void) putchar(CTRL(G)); ! 394: if (!explain) { ! 395: # ifdef FLY ! 396: put_str("[SCFQ] "); ! 397: # else ! 398: put_str("[SCQ] "); ! 399: # endif FLY ! 400: explain = TRUE; ! 401: } ! 402: fflush(stdout); ! 403: } ! 404: } ! 405: ! 406: put_ch(ch) ! 407: char ch; ! 408: { ! 409: if (!isprint(ch)) { ! 410: fprintf(stderr, "r,c,ch: %d,%d,%d", cur_row, cur_col, ch); ! 411: return; ! 412: } ! 413: screen[cur_row][cur_col] = ch; ! 414: putchar(ch); ! 415: if (++cur_col >= COLS) { ! 416: if (!AM || XN) ! 417: putchar('\n'); ! 418: cur_col = 0; ! 419: if (++cur_row >= LINES) ! 420: cur_row = LINES; ! 421: } ! 422: } ! 423: ! 424: put_str(s) ! 425: char *s; ! 426: { ! 427: while (*s) ! 428: put_ch(*s++); ! 429: } ! 430: ! 431: clear_the_screen() ! 432: { ! 433: register int i; ! 434: ! 435: if (blanks[0] == '\0') ! 436: for (i = 0; i < SCREEN_WIDTH; i++) ! 437: blanks[i] = ' '; ! 438: ! 439: if (CL != NULL) { ! 440: tputs(CL, LINES, _putchar); ! 441: for (i = 0; i < SCREEN_HEIGHT; i++) ! 442: bcopy(blanks, screen[i], SCREEN_WIDTH); ! 443: } else { ! 444: for (i = 0; i < SCREEN_HEIGHT; i++) { ! 445: mvcur(cur_row, cur_col, i, 0); ! 446: cur_row = i; ! 447: cur_col = 0; ! 448: clear_eol(); ! 449: } ! 450: mvcur(cur_row, cur_col, 0, 0); ! 451: } ! 452: cur_row = cur_col = 0; ! 453: #ifdef TERMINFO ! 454: move(0, 0); ! 455: refresh(); ! 456: #endif ! 457: } ! 458: ! 459: clear_eol() ! 460: { ! 461: if (CE != NULL) ! 462: tputs(CE, 1, _putchar); ! 463: else { ! 464: fwrite(blanks, sizeof (char), SCREEN_WIDTH - cur_col, stdout); ! 465: if (COLS != SCREEN_WIDTH) ! 466: mvcur(cur_row, SCREEN_WIDTH, cur_row, cur_col); ! 467: else if (AM) ! 468: mvcur(cur_row + 1, 0, cur_row, cur_col); ! 469: else ! 470: mvcur(cur_row, SCREEN_WIDTH - 1, cur_row, cur_col); ! 471: } ! 472: bcopy(blanks, &screen[cur_row][cur_col], SCREEN_WIDTH - cur_col); ! 473: } ! 474: ! 475: redraw_screen() ! 476: { ! 477: register int i; ! 478: # ifndef NOCURSES ! 479: static int first = 1; ! 480: ! 481: if (first) { ! 482: curscr = newwin(SCREEN_HEIGHT, SCREEN_WIDTH, 0, 0); ! 483: if (curscr == NULL) { ! 484: fprintf(stderr, "Can't create curscr\n"); ! 485: exit(1); ! 486: } ! 487: for (i = 0; i < SCREEN_HEIGHT; i++) ! 488: curscr->_y[i] = screen[i]; ! 489: first = 0; ! 490: } ! 491: curscr->_cury = cur_row; ! 492: curscr->_curx = cur_col; ! 493: clearok(curscr, TRUE); ! 494: touchwin(curscr); ! 495: wrefresh(curscr); ! 496: #else ! 497: mvcur(cur_row, cur_col, 0, 0); ! 498: for (i = 0; i < SCREEN_HEIGHT - 1; i++) { ! 499: fwrite(screen[i], sizeof (char), SCREEN_WIDTH, stdout); ! 500: if (COLS > SCREEN_WIDTH || (COLS == SCREEN_WIDTH && !AM)) ! 501: putchar('\n'); ! 502: } ! 503: fwrite(screen[SCREEN_HEIGHT - 1], sizeof (char), SCREEN_WIDTH - 1, ! 504: stdout); ! 505: mvcur(SCREEN_HEIGHT - 1, SCREEN_WIDTH - 1, cur_row, cur_col); ! 506: #endif ! 507: } ! 508: ! 509: /* ! 510: * do_message: ! 511: * Send a message to the driver and return ! 512: */ ! 513: do_message() ! 514: { ! 515: extern int errno; ! 516: long version; ! 517: ! 518: if (read(Socket, (char *) &version, LONGLEN) != LONGLEN) { ! 519: bad_con(); ! 520: /* NOTREACHED */ ! 521: } ! 522: if (ntohl(version) != HUNT_VERSION) { ! 523: bad_ver(); ! 524: /* NOTREACHED */ ! 525: } ! 526: # ifdef INTERNET ! 527: if (write(Socket, Send_message, strlen(Send_message)) < 0) { ! 528: bad_con(); ! 529: /* NOTREACHED */ ! 530: } ! 531: # endif ! 532: (void) close(Socket); ! 533: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.