-+-+-+-+-+-+-+-+ 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 +-+-+-+-+-+-+-+-