-+-+-+-+-+-+-+-+ 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 <ESCAPE> 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 <RETURN>`09`09*/
X/* Function returns false if <ESCAPE> is input`09*/
+-+-+-+-+-+-+-+-  END  OF PART 25 +-+-+-+-+-+-+-+-
