-+-+-+-+-+-+-+-+ START OF PART 25 -+-+-+-+-+-+-+-+ X use_value cbreak(); X#endif X#endif X use_value noecho(); X /* would call nonl() here if could use nl()/nonl(), see moriaterm() */ X#ifdef MSDOS X msdos_raw(); X#endif X /* disable all of the local special characters except the suspend char */ X /* have to disable `5EY for tunneling */ X#ifdef USG X#if !defined(MSDOS) && !defined(ATARI_ST) X (void) ioctl(0, TCSETA, (char *)&tbuf); X#endif X#else X (void) ioctl(0, TIOCSLTC, (char *)&lcbuf); X (void) ioctl(0, TIOCSETP, (char *)&tbuf); X (void) ioctl(0, TIOCSETC, (char *)&cbuf); X (void) ioctl(0, TIOCLSET, (char *)&lbuf); X#endif X (void) wrefresh(curscr); X`7D X#endif X#endif X#endif X#endif X X/* Returns a single character input from the terminal.`09This silently -CJS- X consumes `5ER to redraw the screen and reset the terminal, so that this X operation can always be performed at any input prompt. inkey() never X returns `5ER.`09*/ Xchar inkey() X#ifdef MAC X/* The Mac does not need `5ER, so it just consumes it */ X/* This routine does nothing special with direction keys */ X/* Just returns their keypad ascii value (e.g. '0'-'9') */ X/* Compare with inkeydir() below */ X`7B X char ch; X int dir; X int shift_flag, ctrl_flag; X X put_qio(); X command_count = 0; X X do `7B X macgetkey(&ch, FALSE); X `7D while (ch == CTRL('R')); X X dir = extractdir(ch, &shift_flag, &ctrl_flag); X if (dir != -1) X ch = '0' + dir; X X return(ch); X`7D X#else X`7B X int i; X#ifdef VMS X vtype tmp_str; X#endif X X put_qio();`09`09`09/* Dump IO buffer`09`09*/ X command_count = 0; /* Just to be safe -CJS- */ X while (TRUE) X `7B X#ifdef MSDOS X i = msdos_getch(); X#else X#ifdef VMS X i = vms_getch (); X#else X i = getch(); X#if defined(atarist) && defined(__GNUC__) X/* for some reason a keypad number produces an initial negative number. */ X if (i<0) i = getch(); X#endif X#endif X#endif X X#ifdef VMS X if (i == 27) /* if ESCAPE key, then we probably have a keypad key */ X`09`7B X`09 i = vms_getch(); X`09 if (i == 'O') /* Now it is definitely a numeric keypad key */ X`09 `7B X`09 i = vms_getch(); X`09 switch (i) X`09`09`7B X`09`09 case 'p': i = '0'; break; X`09`09 case 'q' : i = '1'; break; X`09`09 case 'r' : i = '2'; break; X`09`09 case 's' : i = '3'; break; X`09`09 case 't' : i = '4'; break; X`09`09 case 'u' : i = '5'; break; X`09`09 case 'v' : i = '6'; break; X`09`09 case 'w' : i = '7'; break; X`09`09 case 'x' : i = '8'; break; X`09`09 case 'y' : i = '9'; break; X`09`09 case 'm' : i = '-'; break; X`09`09 case 'M' : i = 10; break; /* Enter = RETURN */ X`09`09 case 'n' : i = '.'; break; X`09`09 default : while (kbhit()) (void) vms_getch(); X`09`09 `7D X`09 `7D X`09 else X`09 `7B X`09 while (kbhit()) X`09`09(void) vms_getch(); X`09 `7D X`09`7D X#endif /* VMS */ X X /* some machines may not sign extend. */ X if (i == EOF) X`09`7B X`09 eof_flag++; X`09 /* avoid infinite loops while trying to call inkey() for a -more- X`09 prompt. */ X`09 msg_flag = FALSE; X X`09 (void) refresh (); X`09 if (!character_generated `7C`7C character_saved) X`09 exit_game(); X`09 disturb(1, 0); X`09 if (eof_flag > 100) X`09 `7B X`09 /* just in case, to make sure that the process eventually dies */ X`09 panic_save = 1; X`09 (void) strcpy(died_from, "(end of input: panic saved)"); X`09 if (!save_char()) X`09`09`7B X`09`09 (void) strcpy(died_from, "panic: unexpected eof"); X`09`09 death = TRUE; X`09`09`7D X`09 exit_game(); X`09 `7D X`09 return ESCAPE; X`09`7D X if (i != CTRL('R')) X`09return (char)i; X#ifdef VMS X /* Refresh does not work right under VMS, so use a brute force. */ X overwrite (stdscr, tempscr); X clear_screen(); X put_qio(); X overwrite (tempscr, stdscr); X touchwin (stdscr); X (void) wrefresh (stdscr); X#endif X (void) wrefresh (curscr); X moriaterm(); X `7D X`7D X#endif X X X#ifdef MAC Xchar inkeydir() X/* The Mac does not need `5ER, so it just consumes it */ X/* This routine translates the direction keys in rogue-like mode */ X/* Compare with inkeydir() below */ X`7B X char ch; X int dir; X int shift_flag, ctrl_flag; X static char tab`5B9`5D = `7B X`09'b',`09`09'j',`09`09'n', X`09'h',`09`09'.',`09`09'l', X`09'y',`09`09'k',`09`09'u' X `7D; X static char shifttab`5B9`5D = `7B X`09'B',`09`09'J',`09`09'N', X`09'H',`09`09'.',`09`09'L', X`09'Y',`09`09'K',`09`09'U' X `7D; X static char ctrltab`5B9`5D = `7B X`09CTRL('B'),`09CTRL('J'),`09CTRL('N'), X`09CTRL('H'),`09'.',`09`09CTRL('L'), X`09CTRL('Y'),`09CTRL('K'),`09CTRL('U') X `7D; X X put_qio(); X command_count = 0; X X do `7B X macgetkey(&ch, FALSE); X `7D while (ch == CTRL('R')); X X dir = extractdir(ch, &shift_flag, &ctrl_flag); X X if (dir != -1) `7B X if (!rogue_like_commands) `7B X ch = '0' + dir; X `7D X else `7B X if (ctrl_flag) X`09ch = ctrltab`5Bdir - 1`5D; X else if (shift_flag) X`09ch = shifttab`5Bdir - 1`5D; X else X`09ch = tab`5Bdir - 1`5D; X `7D X `7D X X return(ch); X`7D X#endif X X X/* Flush the buffer`09`09`09`09`09-RAK-`09*/ Xvoid flush() X#ifdef MAC X`7B X/* Removed put_qio() call. Reduces flashing. Doesn't seem to hurt. */ X FlushScreenKeys(); X`7D X#else X`7B X#if defined(MSDOS) X while (kbhit()) X`09(void) getch(); X#else X#ifdef VMS X while (kbhit ()) X (void) vms_getch(); X#else X /* the code originally used ioctls, TIOCDRAIN, or TIOCGETP/TIOCSETP, or X TCGETA/TCSETAF, however this occasionally resulted in loss of output, X the happened especially often when rlogin from BSD to SYS_V machine, X using check_input makes the desired effect a bit clearer */ X /* wierd things happen on EOF, don't try to flush input in that case */ X if (!eof_flag) X while (check_input(0)); X#endif X#endif X X /* used to call put_qio() here to drain output, but it is not necessary */ X`7D X#endif X X X/* Clears given line of text`09`09`09`09-RAK-`09*/ Xvoid erase_line(row, col) Xint row; Xint col; X#ifdef MAC X`7B X Rect line; X X if (row == MSG_LINE && msg_flag) X msg_print(CNIL); X X line.left = col; X line.top = row; X line.right = SCRN_COLS; X line.bottom = row + 1; X DEraseScreen(&line); X`7D X#else X`7B X if (row == MSG_LINE && msg_flag) X msg_print(CNIL); X (void) move(row, col); X clrtoeol(); X`7D X#endif X X X/* Clears screen */ Xvoid clear_screen() X#ifdef MAC X`7B X Rect area; X X if (msg_flag) X msg_print(CNIL); X X area.left = area.top = 0; X area.right = SCRN_COLS; X area.bottom = SCRN_ROWS; X DEraseScreen(&area); X`7D X#else X`7B X if (msg_flag) X msg_print(CNIL); X#ifdef VMS X /* Clear doesn't work right under VMS, so use brute force. */ X (void) clearok (stdscr, TRUE); X (void) wclear(stdscr); X (void) clearok (stdscr, FALSE); X#else X (void) clear(); X#endif X`7D X#endif X Xvoid clear_from (row) Xint row; X#ifdef MAC X`7B X Rect area; X X area.left = 0; X area.top = row; X area.right = SCRN_COLS; X area.bottom = SCRN_ROWS; X DEraseScreen(&area); X`7D X#else X`7B X (void) move(row, 0); X clrtobot(); X`7D X#endif X X X/* Outputs a char to a given interpolated y, x position`09-RAK-`09*/ X/* sign bit of a character used to indicate standout mode. -CJS */ Xvoid print(ch, row, col) Xchar ch; Xint row; Xint col; X#ifdef MAC X`7B X char cnow, anow; X X row -= panel_row_prt;/* Real co-ords convert to screen positions */ X col -= panel_col_prt; X X GetScreenCharAttr(&cnow, &anow, col, row);`09/* Check current */ X X /* If char is already set, ignore op */ X if ((cnow != ch) `7C`7C (anow != ATTR_NORMAL)) X DSetScreenCharAttr(ch & 0x7F, X`09`09 (ch & 0x80) ? attrReversed : attrNormal, X`09`09 col, row); X`7D X#else X`7B X vtype tmp_str; X X row -= panel_row_prt;/* Real co-ords convert to screen positions */ X col -= panel_col_prt; X if (mvaddch (row, col, ch) == ERR) X `7B X abort(); X /* clear msg_flag to avoid problems with unflushed messages */ X msg_flag = 0; X (void) sprintf(tmp_str, "error in print, row = %d col = %d\n", X`09`09 row, col); X prt(tmp_str, 0, 0); X bell (); X /* wait so user can see error */ X (void) sleep(2); X `7D X`7D X#endif X X X/* Moves the cursor to a given interpolated y, x position`09-RAK-`09*/ Xvoid move_cursor_relative(row, col) Xint row; Xint col; X#ifdef MAC X`7B X row -= panel_row_prt;/* Real co-ords convert to screen positions */ X col -= panel_col_prt; X X DSetScreenCursor(col, row); X`7D X#else X`7B X vtype tmp_str; X X row -= panel_row_prt;/* Real co-ords convert to screen positions */ X col -= panel_col_prt; X if (move (row, col) == ERR) X `7B X abort(); X /* clear msg_flag to avoid problems with unflushed messages */ X msg_flag = 0; X (void) sprintf(tmp_str, X`09`09 "error in move_cursor_relative, row = %d col = %d\n", X`09`09 row, col); X prt(tmp_str, 0, 0); X bell(); X /* wait so user can see error */ X (void) sleep(2); X `7D X`7D X#endif X X X/* Print a message so as not to interrupt a counted command. -CJS- */ Xvoid count_msg_print(p) Xchar *p; X`7B X int i; X X i = command_count; X msg_print(p); X command_count = i; X`7D X X X/* Outputs a line to a given y, x position`09`09-RAK-`09*/ Xvoid prt(str_buff, row, col) Xchar *str_buff; Xint row; Xint col; X#ifdef MAC X`7B X Rect line; X X if (row == MSG_LINE && msg_flag) X msg_print(CNIL); X X line.left = col; X line.top = row; X line.right = SCRN_COLS; X line.bottom = row + 1; X DEraseScreen(&line); X X put_buffer(str_buff, row, col); X`7D X#else X`7B X if (row == MSG_LINE && msg_flag) X msg_print(CNIL); X (void) move(row, col); X clrtoeol(); X put_buffer(str_buff, row, col); X`7D X#endif X X X/* move cursor to a given y, x position */ Xvoid move_cursor(row, col) Xint row, col; X#ifdef MAC X`7B X DSetScreenCursor(col, row); X`7D X#else X`7B X (void) move (row, col); X`7D X#endif X X X/* Outputs message to top line of screen`09`09`09`09*/ X/* These messages are kept for later reference.`09 */ Xvoid msg_print(str_buff) Xchar *str_buff; X`7B X register int old_len, new_len; X int combine_messages = FALSE; X char in_char; X#ifdef MAC X Rect line; X#endif X X if (msg_flag) X `7B X old_len = strlen(old_msg`5Blast_msg`5D) + 1; X X /* If the new message and the old message are short enough, we want X`09 display them together on the same line. So we don't flush the old X`09 message in this case. */ X`09`20 X if (str_buff) X`09new_len = strlen (str_buff); X else X`09new_len = 0; X X if (! str_buff `7C`7C (new_len + old_len + 2 >= 73)) X`09`7B X`09 /* ensure that the complete -more- message is visible. */ X`09 if (old_len > 73) X`09 old_len = 73; X`09 put_buffer(" -more-", MSG_LINE, old_len); X`09 /* let sigint handler know that we are waiting for a space */ X`09 wait_for_more = 1; X`09 do X`09 `7B X`09 in_char = inkey(); X`09 `7D X`09 while ((in_char != ' ') && (in_char != ESCAPE) && (in_char != '\n') X`09`09 && (in_char != '\r')); X`09 wait_for_more = 0; X`09`7D X else X`09combine_messages = TRUE; X `7D X X if (! combine_messages) X `7B X#ifdef MAC X line.left = 0; X line.top = MSG_LINE; X line.right = SCRN_COLS; X line.bottom = MSG_LINE+1; X DEraseScreen(&line); X#else X (void) move(MSG_LINE, 0); X clrtoeol(); X#endif X `7D X X /* Make the null string a special case. -CJS- */ X if (str_buff) X `7B X command_count = 0; X msg_flag = TRUE; X X /* If the new message and the old message are short enough, display X`09 them on the same line. */ X `20 X if (combine_messages) X`09`7B X`09 put_buffer (str_buff, MSG_LINE, old_len + 2); X`09 strcat (old_msg`5Blast_msg`5D, " "); X`09 strcat (old_msg`5Blast_msg`5D, str_buff); X`09`7D X else X`09`7B X`09 put_buffer(str_buff, MSG_LINE, 0); X`09 last_msg++; X`09 if (last_msg >= MAX_SAVE_MSG) X`09 last_msg = 0; X`09 (void) strncpy(old_msg`5Blast_msg`5D, str_buff, VTYPESIZ); X`09 old_msg`5Blast_msg`5D`5BVTYPESIZ - 1`5D = '\0'; X`09`7D X `7D X else X msg_flag = FALSE; X`7D X X X/* Used to verify a choice - user gets the chance to abort choice. -CJS- */ Xint get_check(prompt) Xchar *prompt; X`7B X int res; X#ifdef MAC X long y, x;`09`09/* ??? Should change to int or short. */ X#else X int y, x; X#endif X X prt(prompt, 0, 0); X#ifdef MAC X GetScreenCursor(&x, &y); X#else X getyx(stdscr, y, x); X#if defined(lint) X /* prevent message 'warning: y is unused' */ X x = y; X#endif X#ifdef LINT_ARGS X /* prevent message about y never used for MSDOS systems */ X res = y; X#endif X#endif X X if (x > 73) X (void) move(0, 73); X#ifdef MAC X DWriteScreenStringAttr(" `5By/n`5D", ATTR_NORMAL); X#else X (void) addstr(" `5By/n`5D"); X#endif X do X `7B X res = inkey(); X `7D X while(res == ' '); X erase_line(0, 0); X if (res == 'Y' `7C`7C res == 'y') X return TRUE; X else X return FALSE; X`7D X X/* Prompts (optional) and returns ord value of input char`09*/ X/* Function returns false if is input`09*/ Xint get_com(prompt, command) Xchar *prompt; Xchar *command; X`7B X int res; X X if (prompt) X prt(prompt, 0, 0); X *command = inkey(); X if (*command == ESCAPE) X res = FALSE; X else X res = TRUE; X erase_line(MSG_LINE, 0); X return(res); X`7D X X#ifdef MAC X/* Same as get_com(), but translates direction keys from keypad */ Xint get_comdir(prompt, command) Xchar *prompt; Xchar *command; X`7B X int res; X X if (prompt) X prt(prompt, 0, 0); X *command = inkeydir(); X if (*command == ESCAPE) X res = FALSE; X else X res = TRUE; X erase_line(MSG_LINE, 0); X return(res); X`7D X#endif X X X/* Gets a string terminated by `09`09*/ X/* Function returns false if is input`09*/ +-+-+-+-+-+-+-+- END OF PART 25 +-+-+-+-+-+-+-+-