diff options
author | 1997-10-04 09:00:13 +0000 | |
---|---|---|
committer | 1997-10-04 09:00:13 +0000 | |
commit | e9152f6d21d5a8b1e02922e0fc95b71fc21cbd92 (patch) | |
tree | 3e1b32f0c0c61414ebd853c92584cd9d95a99acc /hunt/hunt/playit.c | |
parent | 6f367f8f8be268d527e585867c1c42ffbb07668c (diff) | |
download | bsdgames-darwin-e9152f6d21d5a8b1e02922e0fc95b71fc21cbd92.tar.gz bsdgames-darwin-e9152f6d21d5a8b1e02922e0fc95b71fc21cbd92.tar.zst bsdgames-darwin-e9152f6d21d5a8b1e02922e0fc95b71fc21cbd92.zip |
hunt version 1993-07-17
Diffstat (limited to 'hunt/hunt/playit.c')
-rw-r--r-- | hunt/hunt/playit.c | 628 |
1 files changed, 628 insertions, 0 deletions
diff --git a/hunt/hunt/playit.c b/hunt/hunt/playit.c new file mode 100644 index 00000000..4a6046c9 --- /dev/null +++ b/hunt/hunt/playit.c @@ -0,0 +1,628 @@ +/* + * Hunt + * Copyright (c) 1985 Conrad C. Huang, Gregory S. Couch, Kenneth C.R.C. Arnold + * San Francisco, California + */ + +# if defined(HPUX) || (defined(BSD_RELEASE) && BSD_RELEASE >= 44) +# include <termios.h> +# endif +# include <curses.h> +# include <ctype.h> +# include <signal.h> +# include <errno.h> +# include "hunt.h" +# include <sys/file.h> + +# ifndef FREAD +# define FREAD 1 +# endif + +# if !defined(USE_CURSES) || !defined(TERMINFO) +# define beep() (void) putchar(CTRL('G')) +# endif +# if !defined(USE_CURSES) +# undef refresh +# define refresh() (void) fflush(stdout); +# endif +# ifdef USE_CURSES +# define clear_eol() clrtoeol() +# define put_ch addch +# define put_str addstr +# endif + +int input(); +static int nchar_send; +static int in = FREAD; +# ifndef USE_CURSES +char screen[SCREEN_HEIGHT][SCREEN_WIDTH2], blanks[SCREEN_WIDTH]; +int cur_row, cur_col; +# endif +# ifdef OTTO +int Otto_count; +int Otto_mode; +static int otto_y, otto_x; +static char otto_face; +# endif + +# define MAX_SEND 5 +# define STDIN 0 + +/* + * ibuf is the input buffer used for the stream from the driver. + * It is small because we do not check for user input when there + * are characters in the input buffer. + */ +static int icnt = 0; +static unsigned char ibuf[256], *iptr = ibuf; +static unsigned char getchr(); + +#define GETCHR() (--icnt < 0 ? getchr() : *iptr++) + +#if !defined(BSD_RELEASE) || BSD_RELEASE < 44 +extern int _putchar(); +#endif + +/* + * playit: + * Play a given game, handling all the curses commands from + * the driver. + */ +playit() +{ + register int ch; + register int y, x; + extern int errno; + long version; + + if (read(Socket, (char *) &version, LONGLEN) != LONGLEN) { + bad_con(); + /* NOTREACHED */ + } + if (ntohl(version) != HUNT_VERSION) { + bad_ver(); + /* NOTREACHED */ + } + errno = 0; +# ifdef OTTO + Otto_count = 0; +# endif + nchar_send = MAX_SEND; + while ((ch = GETCHR()) != EOF) { +# ifdef DEBUG + fputc(ch, stderr); +# endif + switch (ch & 0377) { + case MOVE: + y = GETCHR(); + x = GETCHR(); +# ifdef USE_CURSES + move(y, x); +# else + mvcur(cur_row, cur_col, y, x); + cur_row = y; + cur_col = x; +# endif + break; + case ADDCH: + ch = GETCHR(); +# ifdef OTTO + switch (ch) { + + case '<': + case '>': + case '^': + case 'v': + otto_face = ch; +# ifdef USE_CURSES + getyx(stdscr, otto_y, otto_x); +# else + otto_y = cur_row; + otto_x = cur_col; +# endif + break; + } +# endif + put_ch(ch); + break; + case CLRTOEOL: + clear_eol(); + break; + case CLEAR: + clear_the_screen(); + break; + case REFRESH: + refresh(); + break; + case REDRAW: + redraw_screen(); + refresh(); + break; + case ENDWIN: + refresh(); + if ((ch = GETCHR()) == LAST_PLAYER) + Last_player = TRUE; + ch = EOF; + goto out; + case BELL: + beep(); + break; + case READY: + refresh(); + if (nchar_send < 0) +# if defined(HPUX) || (defined(BSD_RELEASE) && BSD_RELEASE >= 44) + tcflush(STDIN, TCIFLUSH); +# else +# ifndef TCFLSH + (void) ioctl(STDIN, TIOCFLUSH, &in); +# else + (void) ioctl(STDIN, TCFLSH, 0); +# endif +# endif + nchar_send = MAX_SEND; +# ifndef OTTO + (void) GETCHR(); +# else + Otto_count -= (GETCHR() & 0xff); + if (!Am_monitor) { +# ifdef DEBUG + fputc('0' + Otto_count, stderr); +# endif + if (Otto_count == 0 && Otto_mode) + otto(otto_y, otto_x, otto_face); + } +# endif + break; + default: +# ifdef OTTO + switch (ch) { + + case '<': + case '>': + case '^': + case 'v': + otto_face = ch; +# ifdef USE_CURSES + getyx(stdscr, otto_y, otto_x); +# else + otto_y = cur_row; + otto_x = cur_col; +# endif + break; + } +# endif + put_ch(ch); + break; + } + } +out: + (void) close(Socket); +} + +/* + * getchr: + * Grab input and pass it along to the driver + * Return any characters from the driver + * When this routine is called by GETCHR, we already know there are + * no characters in the input buffer. + */ +static +unsigned char +getchr() +{ + long readfds, s_readfds; + int driver_mask, stdin_mask; + int nfds, s_nfds; + + driver_mask = 1L << Socket; + stdin_mask = 1L << STDIN; + s_readfds = driver_mask | stdin_mask; + s_nfds = (Socket > STDIN) ? Socket : STDIN; + s_nfds++; + +one_more_time: + do { + errno = 0; + readfds = s_readfds; + nfds = s_nfds; + nfds = select(nfds, &readfds, NULL, NULL, NULL); + } while (nfds <= 0 && errno == EINTR); + + if (readfds & stdin_mask) + send_stuff(); + if ((readfds & driver_mask) == 0) + goto one_more_time; + icnt = read(Socket, ibuf, sizeof ibuf); + if (icnt < 0) { + bad_con(); + /* NOTREACHED */ + } + if (icnt == 0) + goto one_more_time; + iptr = ibuf; + icnt--; + return *iptr++; +} + +/* + * send_stuff: + * Send standard input characters to the driver + */ +send_stuff() +{ + register int count; + register char *sp, *nsp; + static char inp[sizeof Buf]; + + count = read(STDIN, Buf, sizeof Buf); + if (count <= 0) + return; + if (nchar_send <= 0 && !no_beep) { + (void) write(1, "\7", 1); /* CTRL('G') */ + return; + } + + /* + * look for 'q'uit commands; if we find one, + * confirm it. If it is not confirmed, strip + * it out of the input + */ + Buf[count] = '\0'; + nsp = inp; + for (sp = Buf; *sp != '\0'; sp++) + if ((*nsp = map_key[*sp]) == 'q') + intr(); + else + nsp++; + count = nsp - inp; + if (count) { +# ifdef OTTO + Otto_count += count; +# endif + nchar_send -= count; + if (nchar_send < 0) + count += nchar_send; + (void) write(Socket, inp, count); + } +} + +/* + * quit: + * Handle the end of the game when the player dies + */ +long +quit(old_status) +long old_status; +{ + register int explain, ch; + + if (Last_player) + return Q_QUIT; +# ifdef OTTO + if (Otto_mode) + return Q_CLOAK; +# endif +# ifdef USE_CURSES + move(HEIGHT, 0); +# else + mvcur(cur_row, cur_col, HEIGHT, 0); + cur_row = HEIGHT; + cur_col = 0; +# endif + put_str("Re-enter game [ynwo]? "); + clear_eol(); + explain = FALSE; + for (;;) { + refresh(); + if (isupper(ch = getchar())) + ch = tolower(ch); + if (ch == 'y') + return old_status; + else if (ch == 'o') + break; + else if (ch == 'n') { +# ifndef INTERNET + return Q_QUIT; +# else +# ifdef USE_CURSES + move(HEIGHT, 0); +# else + mvcur(cur_row, cur_col, HEIGHT, 0); + cur_row = HEIGHT; + cur_col = 0; +# endif + put_str("Write a parting message [yn]? "); + clear_eol(); + refresh(); + for (;;) { + if (isupper(ch = getchar())) + ch = tolower(ch); + if (ch == 'y') + goto get_message; + if (ch == 'n') + return Q_QUIT; + } +# endif + } +# ifdef INTERNET + else if (ch == 'w') { + static char buf[WIDTH + WIDTH % 2]; + char *cp, c; + +get_message: + c = ch; /* save how we got here */ +# ifdef USE_CURSES + move(HEIGHT, 0); +# else + mvcur(cur_row, cur_col, HEIGHT, 0); + cur_row = HEIGHT; + cur_col = 0; +# endif + put_str("Message: "); + clear_eol(); + refresh(); + cp = buf; + for (;;) { + refresh(); + if ((ch = getchar()) == '\n' || ch == '\r') + break; +# if defined(TERMINFO) || BSD_RELEASE >= 44 + if (ch == erasechar()) +# else + if (ch == _tty.sg_erase) +# endif + { + if (cp > buf) { +# ifdef USE_CURSES + int y, x; + getyx(stdscr, y, x); + move(y, x - 1); +# else + mvcur(cur_row, cur_col, cur_row, + cur_col - 1); + cur_col -= 1; +# endif + cp -= 1; + clear_eol(); + } + continue; + } +# if defined(TERMINFO) || BSD_RELEASE >= 44 + else if (ch == killchar()) +# else + else if (ch == _tty.sg_kill) +# endif + { +# ifdef USE_CURSES + int y, x; + getyx(stdscr, y, x); + move(y, x - (cp - buf)); +# else + mvcur(cur_row, cur_col, cur_row, + cur_col - (cp - buf)); + cur_col -= cp - buf; +# endif + cp = buf; + clear_eol(); + continue; + } else if (!isprint(ch)) { + beep(); + continue; + } + put_ch(ch); + *cp++ = ch; + if (cp + 1 >= buf + sizeof buf) + break; + } + *cp = '\0'; + Send_message = buf; + return (c == 'w') ? old_status : Q_MESSAGE; + } +# endif + beep(); + if (!explain) { + put_str("(Yes, No, Write message, or Options) "); + explain = TRUE; + } + } + +# ifdef USE_CURSES + move(HEIGHT, 0); +# else + mvcur(cur_row, cur_col, HEIGHT, 0); + cur_row = HEIGHT; + cur_col = 0; +# endif +# ifdef FLY + put_str("Scan, Cloak, Flying, or Quit? "); +# else + put_str("Scan, Cloak, or Quit? "); +# endif + clear_eol(); + refresh(); + explain = FALSE; + for (;;) { + if (isupper(ch = getchar())) + ch = tolower(ch); + if (ch == 's') + return Q_SCAN; + else if (ch == 'c') + return Q_CLOAK; +# ifdef FLY + else if (ch == 'f') + return Q_FLY; +# endif + else if (ch == 'q') + return Q_QUIT; + beep(); + if (!explain) { +# ifdef FLY + put_str("[SCFQ] "); +# else + put_str("[SCQ] "); +# endif + explain = TRUE; + } + refresh(); + } +} + +# ifndef USE_CURSES +put_ch(ch) + char ch; +{ + if (!isprint(ch)) { + fprintf(stderr, "r,c,ch: %d,%d,%d", cur_row, cur_col, ch); + return; + } + screen[cur_row][cur_col] = ch; + putchar(ch); + if (++cur_col >= COLS) { + if (!AM || XN) + putchar('\n'); + cur_col = 0; + if (++cur_row >= LINES) + cur_row = LINES; + } +} + +put_str(s) + char *s; +{ + while (*s) + put_ch(*s++); +} +# endif + +clear_the_screen() +{ +# ifdef USE_CURSES + clear(); + move(0, 0); + refresh(); +# else + register int i; + + if (blanks[0] == '\0') + for (i = 0; i < SCREEN_WIDTH; i++) + blanks[i] = ' '; + + if (CL != NULL) { +#if !defined(BSD_RELEASE) || BSD_RELEASE < 44 + tputs(CL, LINES, _putchar); +#else + tputs(CL, LINES, __cputchar); +#endif + for (i = 0; i < SCREEN_HEIGHT; i++) + memcpy(screen[i], blanks, SCREEN_WIDTH); + } else { + for (i = 0; i < SCREEN_HEIGHT; i++) { + mvcur(cur_row, cur_col, i, 0); + cur_row = i; + cur_col = 0; + clear_eol(); + } + mvcur(cur_row, cur_col, 0, 0); + } + cur_row = cur_col = 0; +#endif +} + +#ifndef USE_CURSES +clear_eol() +{ + if (CE != NULL) +#if !defined(BSD_RELEASE) || BSD_RELEASE < 44 + tputs(CE, 1, _putchar); +#else + tputs(CE, 1, __cputchar); +#endif + else { + fwrite(blanks, sizeof (char), SCREEN_WIDTH - cur_col, stdout); + if (COLS != SCREEN_WIDTH) + mvcur(cur_row, SCREEN_WIDTH, cur_row, cur_col); + else if (AM) + mvcur(cur_row + 1, 0, cur_row, cur_col); + else + mvcur(cur_row, SCREEN_WIDTH - 1, cur_row, cur_col); + } + memcpy(&screen[cur_row][cur_col], blanks, SCREEN_WIDTH - cur_col); +} +# endif + +redraw_screen() +{ +# ifdef USE_CURSES + clearok(stdscr, TRUE); + touchwin(stdscr); +# else + register int i; +# ifndef NOCURSES + static int first = 1; + + if (first) { + curscr = newwin(SCREEN_HEIGHT, SCREEN_WIDTH, 0, 0); + if (curscr == NULL) { + fprintf(stderr, "Can't create curscr\n"); + exit(1); + } +# if !defined(BSD_RELEASE) || BSD_RELEASE < 44 + for (i = 0; i < SCREEN_HEIGHT; i++) + curscr->_y[i] = screen[i]; +# endif + first = 0; + } +# if defined(BSD_RELEASE) && BSD_RELEASE >= 44 + for (i = 0; i < SCREEN_HEIGHT; i++) { + register int j; + for (j = 0; j < SCREEN_WIDTH; j++) + curscr->lines[i]->line[j].ch = screen[i][j]; + } + curscr->cury = cur_row; + curscr->curx = cur_col; +# else + curscr->_cury = cur_row; + curscr->_curx = cur_col; +# endif + clearok(curscr, TRUE); + touchwin(curscr); + wrefresh(curscr); +#else + mvcur(cur_row, cur_col, 0, 0); + for (i = 0; i < SCREEN_HEIGHT - 1; i++) { + fwrite(screen[i], sizeof (char), SCREEN_WIDTH, stdout); + if (COLS > SCREEN_WIDTH || (COLS == SCREEN_WIDTH && !AM)) + putchar('\n'); + } + fwrite(screen[SCREEN_HEIGHT - 1], sizeof (char), SCREEN_WIDTH - 1, + stdout); + mvcur(SCREEN_HEIGHT - 1, SCREEN_WIDTH - 1, cur_row, cur_col); +#endif +#endif +} + +/* + * do_message: + * Send a message to the driver and return + */ +do_message() +{ + extern int errno; + long version; + + if (read(Socket, (char *) &version, LONGLEN) != LONGLEN) { + bad_con(); + /* NOTREACHED */ + } + if (ntohl(version) != HUNT_VERSION) { + bad_ver(); + /* NOTREACHED */ + } +# ifdef INTERNET + if (write(Socket, Send_message, strlen(Send_message)) < 0) { + bad_con(); + /* NOTREACHED */ + } +# endif + (void) close(Socket); +} |