-+-+-+-+-+-+-+-+ START OF PART 24 -+-+-+-+-+-+-+-+
Xint Use_value2;
X#define use_value2  Use_value2 +=
X#else
X#define use_value2
X#endif
X
X#endif
X
X#ifndef MAC
Xchar *getenv();
X#endif
X
X#ifndef VMS
X#ifdef USG
Xvoid exit();
X#if defined(__TURBOC__)
Xvoid sleep();
X#else
X#ifndef AMIGA
Xunsigned sleep();
X#endif
X#endif
X#endif
X#endif
X
X#ifdef ultrix
Xvoid exit();
Xvoid sleep();
X#endif
X
X#if !defined(MAC) && !defined(MSDOS) && !defined(ATARI_ST) && !defined(VMS)
X#ifndef AMIGA
X#ifdef USG
Xstatic struct termio save_termio;
X#else
Xstatic struct ltchars save_special_chars;
Xstatic struct sgttyb save_ttyb;
Xstatic struct tchars save_tchars;
Xstatic int save_local_chars;
X#endif
X#endif
X#endif
X
X#ifndef MAC
Xstatic int curses_on = FALSE;
Xstatic WINDOW *savescr;`09`09/* Spare window for saving the screen. -CJS-*/
X#ifdef VMS
Xstatic WINDOW *tempscr;`09`09/* Spare window for VMS CTRL('R'). */
X#endif
X#endif
X
X#ifdef MAC
X/* Attributes of normal and hilighted characters */
X#define ATTR_NORMAL`09attrNormal
X#define ATTR_HILITED`09attrReversed
X#endif
X
X#ifndef MAC
X#ifdef SIGTSTP
X/* suspend()`09`09`09`09`09`09`09   -CJS-
X   Handle the stop and start signals. This ensures that the log
X   is up to date, and that the terminal is fully reset and
X   restored.  */
Xint suspend()
X`7B
X#ifdef USG
X  /* for USG systems with BSDisms that have SIGTSTP defined, but don't
X     actually implement it */
X#else
X  struct sgttyb tbuf;
X  struct ltchars lcbuf;
X  struct tchars cbuf;
X  int lbuf;
X  long time();
X
X  py.misc.male `7C= 2;
X  (void) ioctl(0, TIOCGETP, (char *)&tbuf);
X  (void) ioctl(0, TIOCGETC, (char *)&cbuf);
X  (void) ioctl(0, TIOCGLTC, (char *)&lcbuf);
X#if !defined(atarist) && !defined(__GNUC__)
X  (void) ioctl(0, TIOCLGET, (char *)&lbuf);
X#endif
X  restore_term();
X  (void) kill(0, SIGSTOP);
X  curses_on = TRUE;
X  (void) ioctl(0, TIOCSETP, (char *)&tbuf);
X  (void) ioctl(0, TIOCSETC, (char *)&cbuf);
X  (void) ioctl(0, TIOCSLTC, (char *)&lcbuf);
X#if !defined(atarist) && !defined(__GNUC__)
X  (void) ioctl(0, TIOCLSET, (char *)&lbuf);
X#endif
X  (void) wrefresh(curscr);
X  py.misc.male &= `7E2;
X#endif
X  return 0;
X`7D
X#endif
X#endif
X
X/* initializes curses routines */
Xvoid init_curses()
X#ifdef MAC
X`7B
X  /* Primary initialization is done in mac.c since game is restartable */
X  /* Only need to clear the screen here */
X  Rect scrn;
X
X  scrn.left = scrn.top = 0;
X  scrn.right = SCRN_COLS;
X  scrn.bottom = SCRN_ROWS;
X  EraseScreen(&scrn);
X  UpdateScreen();
X`7D
X#else
X`7B
X  int i, y, x;
X
X#ifdef AMIGA
X  if (opentimer() == 0)
X    `7B
X      (void) printf ("Could not open timer device.\n");
X      exit (1);
X    `7D
X#endif
X
X#ifndef USG
X  (void) ioctl(0, TIOCGLTC, (char *)&save_special_chars);
X  (void) ioctl(0, TIOCGETP, (char *)&save_ttyb);
X  (void) ioctl(0, TIOCGETC, (char *)&save_tchars);
X#if !defined(atarist) && !defined(__GNUC__)
X  (void) ioctl(0, TIOCLGET, (char *)&save_local_chars);
X#endif
X#else
X#if !defined(VMS) && !defined(MSDOS) && !defined(ATARI_ST)
X#ifndef AMIGA
X  (void) ioctl(0, TCGETA, (char *)&save_termio);
X#endif
X#endif
X#endif
X
X  /* PC curses returns ERR */
X#if defined(USG) && !defined(PC_CURSES) && !defined(AMIGA)
X  if (initscr() == NULL)
X#else
X  if (initscr() == ERR)
X#endif
X    `7B
X      (void) printf("Error allocating screen in curses package.\n");
X      exit(1);
X    `7D
X  if (LINES < 24 `7C`7C COLS < 80)`09 /* Check we have enough screen. -CJS-
V */
X    `7B
X      (void) printf("Screen too small for moria.\n");
X      exit (1);
X    `7D
X#ifdef SIGTSTP
X#if defined(atarist) && defined(__GNUC__)
X  (void) signal (SIGTSTP, (__Sigfunc)suspend);
X#else
X  (void) signal (SIGTSTP, suspend);
X#endif
X#endif
X  if (((savescr = newwin (0, 0, 0, 0)) == NULL)
X#ifdef VMS
X      `7C`7C ((tempscr = newwin (0, 0, 0, 0)) == NULL))
X#else
X    )
X#endif
X    `7B
X      (void) printf ("Out of memory in starting up curses.\n");
X      exit_game();
X    `7D
X  (void) clear();
X  (void) refresh();
X  moriaterm ();
X
X#if 0
X  /* This assumes that the terminal is 80 characters wide, which is not
X     guaranteed to be true.  */
X
X  /* check tab settings, exit with error if they are not 8 spaces apart */
X  (void) move(0, 0);
X  for (i = 1; i < 10; i++)
X    `7B
X      (void) addch('\t');
X      getyx(stdscr, y, x);
X      if (y != 0 `7C`7C x != i*8)
X`09break;
X    `7D
X  if (i != 10)
X    `7B
X      msg_print("Tabs must be set 8 spaces apart.");
X      exit_game();
X    `7D
X#endif
X`7D
X#endif
X
X/* Set up the terminal into a suitable state for moria.`09 -CJS- */
Xvoid moriaterm()
X#ifdef MAC
X/* Nothing to do on Mac */
X`7B
X`7D
X#else
X`7B
X#if !defined(MSDOS) && !defined(ATARI_ST) && !defined(VMS)
X#ifndef AMIGA
X#ifdef USG
X  struct termio tbuf;
X#else
X  struct ltchars lbuf;
X  struct tchars buf;
X#endif
X#endif
X#endif
X
X  curses_on = TRUE;
X#ifndef BSD4_3
X  use_value crmode();
X#else
X#ifdef VMS
X  use_value vms_crmode ();
X#else
X  use_value cbreak();
X#endif
X#endif
X  use_value noecho();
X  /* can not use nonl(), because some curses do not handle it correctly */
X#ifdef MSDOS
X  msdos_raw();
X#else
X#ifdef AMIGA
X  init_color (0,   0,   0,   0);`09/* pen 0 - black */
X  init_color (1,1000,1000,1000);`09/* pen 1 - white */
X  init_color (2,   0, 300, 700);`09/* pen 2 - blue */
X  init_color (3,1000, 500,   0);`09/* pen 3 - orange */
X#else
X#if !defined(ATARI_ST) && !defined(VMS)
X#ifdef USG
X  (void) ioctl(0, TCGETA, (char *)&tbuf);
X  /* disable all of the normal special control characters */
X  tbuf.c_cc`5BVINTR`5D = (char)3; /* control-C */
X  tbuf.c_cc`5BVQUIT`5D = (char)-1;
X  tbuf.c_cc`5BVERASE`5D = (char)-1;
X  tbuf.c_cc`5BVKILL`5D = (char)-1;
X  tbuf.c_cc`5BVEOF`5D = (char)-1;
X
X  /* don't know what these are for */
X  tbuf.c_cc`5BVEOL`5D = (char)-1;
X#ifdef VEOL2
X  tbuf.c_cc`5BVEOL2`5D = (char)-1;
X#endif
X
X  /* stuff needed when !icanon, i.e. cbreak/raw mode */
X  tbuf.c_cc`5BVMIN`5D = 1;  /* Input should wait for at least 1 char */
X  tbuf.c_cc`5BVTIME`5D = 0; /* no matter how long that takes. */
X
X  (void) ioctl(0, TCSETA, (char *)&tbuf);
X#else
X  /* disable all of the special characters except the suspend char, interrup
Vt
X     char, and the control flow start/stop characters */
X  (void) ioctl(0, TIOCGLTC, (char *)&lbuf);
X  lbuf.t_suspc = (char)26; /* control-Z */
X  lbuf.t_dsuspc = (char)-1;
X  lbuf.t_rprntc = (char)-1;
X  lbuf.t_flushc = (char)-1;
X  lbuf.t_werasc = (char)-1;
X  lbuf.t_lnextc = (char)-1;
X  (void) ioctl(0, TIOCSLTC, (char *)&lbuf);
X
X  (void) ioctl (0, TIOCGETC, (char *)&buf);
X  buf.t_intrc = (char)3; /* control-C */
X  buf.t_quitc = (char)-1;
X  buf.t_startc = (char)17; /* control-Q */
X  buf.t_stopc = (char)19; /* control-S */
X  buf.t_eofc = (char)-1;
X  buf.t_brkc = (char)-1;
X  (void) ioctl(0, TIOCSETC, (char *)&buf);
X#endif
X#endif
X#endif
X#endif
X
X#ifdef ATARIST_TC
X  raw ();
X#endif
X`7D
X#endif
X
X
X/* Dump IO to buffer`09`09`09`09`09-RAK-`09*/
Xvoid put_buffer(out_str, row, col)
Xchar *out_str;
Xint row, col;
X#ifdef MAC
X`7B
X  /* The screen manager handles writes past the edge ok */
X  DSetScreenCursor(col, row);
X  DWriteScreenStringAttr(out_str, ATTR_NORMAL);
X`7D
X#else
X`7B
X  vtype tmp_str;
X
X  /* truncate the string, to make sure that it won't go past right edge of
X     screen */
X  if (col > 79)
X    col = 79;
X  (void) strncpy (tmp_str, out_str, 79 - col);
X  tmp_str `5B79 - col`5D = '\0';
X
X  if (mvaddstr(row, col, tmp_str) == 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 put_buffer, 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/* Dump the IO buffer to terminal`09`09`09-RAK-`09*/
Xvoid put_qio()
X`7B
X  screen_change = TRUE;`09   /* Let inven_command know something has changed
V. */
X#ifdef MAC
X  UpdateScreen();
X#else
X  (void) refresh();
X#endif
X`7D
X
X/* Put the terminal in the original mode.`09`09`09   -CJS- */
Xvoid restore_term()
X#ifdef MAC
X/* Nothing to do on Mac */
X`7B
X`7D
X#else
X`7B
X#ifdef AMIGA
X  closetimer ();
X#endif
X
X  if (!curses_on)
X    return;
X  put_qio();  /* Dump any remaining buffer */
X#ifdef MSDOS
X  (void) sleep(2);   /* And let it be read. */
X#endif
X#ifdef VMS
X  clear_screen();
X  pause_line(15);
X#endif
X  /* this moves curses to bottom right corner */
X  mvcur(stdscr->_cury, stdscr->_curx, LINES-1, 0);
X  endwin();  /* exit curses */
X  (void) fflush (stdout);
X#ifdef MSDOS
X  msdos_noraw();
X#endif
X  /* restore the saved values of the special chars */
X#ifdef USG
X#if !defined(MSDOS) && !defined(ATARI_ST) && !defined(VMS)
X#ifndef AMIGA
X  (void) ioctl(0, TCSETA, (char *)&save_termio);
X#endif
X#endif
X#else
X  (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
X  (void) ioctl(0, TIOCSETP, (char *)&save_ttyb);
X  (void) ioctl(0, TIOCSETC, (char *)&save_tchars);
X#if !defined(atarist) && !defined(__GNUC__)
X  (void) ioctl(0, TIOCLSET, (char *)&save_local_chars);
X#endif
X#endif
X  curses_on = FALSE;
X`7D
X#endif
X
X
Xvoid shell_out()
X#if defined(atarist) && defined(__GNUC__)
X`7B char fail_message`5B80`5D, arg_list`5B1`5D, *p;
X  int  escape_code;
X
X  save_screen();
X  clear_screen();
X  use_value nocbreak();         /* Must remember to reset terminal modes   *
V/
X  use_value echo();             /* or shell i/o will be quite messed up!   *
V/
X
X  p = (char *)getenv("SHELL");
X  if (p != (char *)NULL)
X    `7B put_buffer("Escaping to Shell\n",0,0);
X      put_qio();
X      arg_list`5B0`5D=0;
X      escape_code = Pexec(0,p,arg_list,0);   /* Launch the shell.          *
V/
X
X      if (escape_code != 0)
X         `7B sprintf(fail_message,"Pexec() error code = %d\n",escape_code);
X           put_buffer(fail_message,0,0);
X           put_qio();
X`09   sleep(5);
X`09 `7D
X    `7D
X  use_value cbreak();        /* Reset the terminal back to CBREAK/NOECHO   *
V/
X  use_value noecho();
X  clear_screen();            /* Do not want shell data on screen.          *
V/
X  restore_screen();
X`7D
X
X#else
X
X#ifdef MAC
X`7B
X  alert_error("This command is not implemented on the Macintosh.");
X`7D
X#else
X#if defined(AMIGA) `7C`7C defined(ATARIST_TC)
X`7B
X  put_buffer("This command is not implemented.\n", 0, 0);
X`7D
X#else
X#ifdef VMS /* TPP */
X`7B
X  int val, istat;
X  char *str;
X
X  save_screen();
X  /* clear screen and print 'exit' message */
X  clear_screen();
X  put_buffer("`5BEntering subprocess, type 'EOJ' to resume your game.`5D\n",
X`09     0, 0);
X  put_qio();
X
X  use_value vms_nocrmode();
X  use_value echo();
X  ignore_signals();
X
X  istat = lib$spawn();
X  if (!istat)
X    lib$signal (istat);
X
X  restore_signals();
X  use_value vms_crmode();
X  use_value noecho();
X  /* restore the cave to the screen */
X  restore_screen();
X  put_buffer("Welcome back to UMoria.\n", 0, 0);
X  save_screen();
X  clear_screen();
X  put_qio();
X  restore_screen();
X  (void) wrefresh(curscr);
X`7D
X#else
X`7B
X#ifdef USG
X#if !defined(MSDOS) && !defined(ATARI_ST) && !defined(AMIGA)
X  struct termio tbuf;
X#endif
X#else
X  struct sgttyb tbuf;
X  struct ltchars lcbuf;
X  struct tchars cbuf;
X  int lbuf;
X#endif
X#ifdef MSDOS
X  char`09*comspec, key;
X#else
X#ifdef ATARI_ST
X  char comstr`5B80`5D;
X  char *str;
X  extern char **environ;
X#else
X  int val;
X  char *str;
X#endif
X#endif
X
X  save_screen();
X  /* clear screen and print 'exit' message */
X  clear_screen();
X#ifndef ATARI_ST
X  put_buffer("`5BEntering shell, type 'exit' to resume your game.`5D\n",0,0)
V;
X#else
X  put_buffer("`5BEscaping to shell`5D\n",0,0);
X#endif
X  put_qio();
X
X#ifdef USG
X#if !defined(MSDOS) && !defined(ATARI_ST) && !defined(AMIGA)
X  (void) ioctl(0, TCGETA, (char *)&tbuf);
X#endif
X#else
X  (void) ioctl(0, TIOCGETP, (char *)&tbuf);
X  (void) ioctl(0, TIOCGETC, (char *)&cbuf);
X  (void) ioctl(0, TIOCGLTC, (char *)&lcbuf);
X  (void) ioctl(0, TIOCLGET, (char *)&lbuf);
X#endif
X  /* would call nl() here if could use nl()/nonl(), see moriaterm() */
X#ifndef BSD4_3
X  use_value nocrmode();
X#else
X#ifdef VMS
X  use_value vms_nocrmode ();
X#else
X  use_value nocbreak();
X#endif
X#endif
X#ifdef MSDOS
X  use_value msdos_noraw();
X#endif
X  use_value echo();
X  ignore_signals();
X#ifdef MSDOS`09`09/*`7B*/
X  if ((comspec = getenv("COMSPEC")) == CNIL
X  `7C`7C  spawnl(P_WAIT, comspec, comspec, CNIL) < 0) `7B
X`09clear_screen();`09/* BOSS key if shell failed */
X`09put_buffer("M:\\> ", 0, 0);
X`09do `7B
X`09  key = inkey();
X`09`7D while (key != '!');
X  `7D
X
X#else`09`09/* MSDOS `7D`7B*/
X#ifndef ATARI_ST
X  val = fork();
X  if (val == 0)
X    `7B
X#endif
X      default_signals();
X#ifdef USG
X#if !defined(MSDOS) && !defined(ATARI_ST) && !defined(AMIGA)
X      (void) ioctl(0, TCSETA, (char *)&save_termio);
X#endif
X#else
X      (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
X      (void) ioctl(0, TIOCSETP, (char *)&save_ttyb);
X      (void) ioctl(0, TIOCSETC, (char *)&save_tchars);
X      (void) ioctl(0, TIOCLSET, (char *)&save_local_chars);
X#endif
X#ifndef MSDOS
X      /* close scoreboard descriptor */
X      /* it is not open on MSDOS machines */
X      (void) fclose(highscore_fp);
X#endif
X      if (str = getenv("SHELL"))
X#ifndef ATARI_ST
X`09(void) execl(str, str, (char *) 0);
X#else
X`09system(str);
X#endif
X      else
X#ifndef ATARI_ST
X`09(void) execl("/bin/sh", "sh", (char *) 0);
X#endif
X      msg_print("Cannot execute shell.");
X#ifndef ATARI_ST
X      exit(1);
X    `7D
X  if (val == -1)
X    `7B
X      msg_print("Fork failed. Try again.");
X      return;
X    `7D
X#ifdef USG
X  (void) wait((int *) 0);
X#else
X  (void) wait((union wait *) 0);
X#endif
X#endif /* ATARI_ST */
X#endif`09`09 /* MSDOS `7D*/
X  restore_signals();
X  /* restore the cave to the screen */
X  restore_screen();
X#ifndef BSD4_3
X  use_value crmode();
X#else
X#ifdef VMS
X  use_value vms_crmode ();
X#else
+-+-+-+-+-+-+-+-  END  OF PART 24 +-+-+-+-+-+-+-+-
