OSDN Git Service

Initial revision
[hengband/hengband.git] / src / main-cap.c
diff --git a/src/main-cap.c b/src/main-cap.c
new file mode 100644 (file)
index 0000000..d3df03b
--- /dev/null
@@ -0,0 +1,1069 @@
+/* File: main-cap.c */
+
+/* Purpose: Support for "term.c" using "termcap" calls */
+
+#include "angband.h"
+
+
+#ifdef USE_CAP
+
+
+/*
+ * This file is a total hack, but is often very helpful.  :-)
+ *
+ * This file allows use of the terminal without requiring the
+ * "curses" routines.  In fact, if "USE_HARDCODE" is defined,
+ * this file will attempt to use various hard-coded "vt100"
+ * escape sequences to also avoid the use of the "termcap"
+ * routines.  I do not know if this will work on System V.
+ *
+ * This file is intended for use only on those machines which are
+ * unable, for whatever reason, to compile the "main-gcu.c" file,
+ * but which seem to be able to support the "termcap" library, or
+ * which at least seem able to support "vt100" terminals.
+ *
+ * Large portions of this file were stolen from "main-gcu.c"
+ *
+ * This file incorrectly handles output to column 80, I think.
+ */
+
+
+/*
+ * Require a "system"
+ */
+#if !defined(USE_TERMCAP) && !defined(USE_HARDCODE)
+# define USE_TERMCAP
+#endif
+
+/*
+ * Hack -- try to guess which systems use what commands
+ * Hack -- allow one of the "USE_Txxxxx" flags to be pre-set.
+ * Mega-Hack -- try to guess when "POSIX" is available.
+ * If the user defines two of these, we will probably crash.
+ */
+#if !defined(USE_TPOSIX)
+# if !defined(USE_TERMIO) && !defined(USE_TCHARS)
+#  if defined(_POSIX_VERSION)
+#   define USE_TPOSIX
+#  else
+#   if defined(USG) || defined(linux) || defined(SOLARIS)
+#    define USE_TERMIO
+#   else
+#    define USE_TCHARS
+#   endif
+#  endif
+# endif
+#endif
+
+
+
+/*
+ * POSIX stuff
+ */
+#ifdef USE_TPOSIX
+# include <sys/ioctl.h>
+# include <termios.h>
+#endif
+
+/*
+ * One version needs these files
+ */
+#ifdef USE_TERMIO
+# include <sys/ioctl.h>
+# include <termio.h>
+#endif
+
+/*
+ * The other needs these files
+ */
+#ifdef USE_TCHARS
+# include <sys/ioctl.h>
+# include <sys/resource.h>
+# include <sys/param.h>
+# include <sys/file.h>
+# include <sys/types.h>
+#endif
+
+
+/*
+ * XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY"
+ *
+ * They should both work due to the "(i != 1)" test in the code
+ * which checks for the result of the "read()" command.
+ */
+#ifndef O_NDELAY
+# define O_NDELAY O_NONBLOCK
+#endif
+
+
+
+
+#ifdef USE_TERMCAP
+
+/*
+ * Termcap string information
+ */
+
+static char blob[1024];                /* The "termcap" entry */
+static char area[1024];                /* The string extraction buffer */
+static char *next = area;      /* The current "index" into "area" */
+static char *desc;             /* The terminal name */
+
+#endif
+
+
+/*
+ * Pointers into the "area"
+ */
+
+static char *cm;       /* Move cursor */
+static char *ch;       /* Move cursor to horizontal location */
+static char *cv;       /* Move cursor to vertical location */
+static char *ho;       /* Move cursor to top left */
+static char *ll;       /* Move cursor to bottom left */
+static char *cs;       /* Set scroll area */
+static char *cl;       /* Clear screen */
+static char *cd;       /* Clear to end of display */
+static char *ce;       /* Clear to end of line */
+static char *cr;       /* Move to start of line */
+static char *so;       /* Turn on standout */
+static char *se;       /* Turn off standout */
+static char *md;       /* Turn on bold */
+static char *me;       /* Turn off bold */
+static char *vi;       /* Cursor - invisible */
+static char *ve;       /* Cursor - normal */
+static char *vs;       /* Cursor - bright */
+
+
+/*
+ * State variables
+ */
+
+static int rows;       /* Screen size (Y) */
+static int cols;       /* Screen size (X) */
+static int curx;       /* Cursor location (X) */
+static int cury;       /* Cursor location (Y) */
+static int curv;       /* Cursor visibility */
+
+
+/*
+ * Extern functions
+ */
+extern char *getenv();
+extern char *tgoto();
+extern char *tgetstr();
+
+
+/*
+ * Write some chars to the terminal
+ */
+static void ewrite(char *str)
+{
+       int numtowrite, numwritten;
+
+       /* See how much work we have */
+       numtowrite = strlen(str);
+
+       /* Write until done */
+       while (numtowrite > 0)
+       {
+               /* Try to write the chars */
+               numwritten = write(1, str, numtowrite);
+
+               /* Handle FIFOs and EINTR */
+               if (numwritten < 0) numwritten = 0;
+
+               /* See what we completed */
+               numtowrite -= numwritten;
+               str += numwritten;
+
+               /* Hack -- sleep if not done */
+               if (numtowrite > 0) sleep(1);
+       }
+}
+
+
+
+#ifdef USE_TERMCAP
+
+static char write_buffer[128];
+static char *write_buffer_ptr;
+
+static void output_one(char c)
+{
+       *write_buffer_ptr++ = c;
+}
+
+static void tp(char *s)
+{
+       /* Dump the string into us */
+       write_buffer_ptr = write_buffer;
+
+       /* Write the string with padding */
+       tputs (s, 1, output_one);
+
+       /* Finish the string */
+       *write_buffer_ptr = '\0';
+
+       /* Dump the recorded buffer */
+       ewrite (write_buffer);
+}
+
+#endif
+
+#ifdef USE_HARDCODE
+
+static void tp(char *s)
+{
+       ewrite(s);
+}
+
+#endif
+
+
+
+
+
+
+
+/*
+ * Clear the screen
+ */
+static void do_cl(void)
+{
+       if (cl) tp (cl);
+}
+
+/*
+ * Clear to the end of the line
+ */
+static void do_ce(void)
+{
+       if (ce) tp(ce);
+}
+
+
+/*
+ * Set the cursor visibility (0 = invis, 1 = normal, 2 = bright)
+ */
+static void curs_set(int vis)
+{
+       char *v = NULL;
+
+       if (!vis)
+       {
+               v = vi;
+       }
+       else if (vis > 1)
+       {
+               v = vs ? vs : ve;
+       }
+       else
+       {
+               v = ve ? ve : vs;
+       }
+
+       if (v) tp(v);
+}
+
+
+
+/*
+ * Restrict scrolling to within these rows
+ */
+static void do_cs(int y1, int y2)
+{
+
+#ifdef USE_TERMCAP
+       if (cs) tp(tgoto(cs, y2, y1));
+#endif
+
+#ifdef USE_HARDCODE
+       char temp[64];
+       sprintf(temp, cs, y1, y2);
+       tp (temp);
+#endif
+
+}
+
+
+
+/*
+ * Go to the given screen location directly
+ */
+static void do_cm(int x, int y)
+{
+
+#ifdef USE_TERMCAP
+       if (cm) tp(tgoto(cm, x, y));
+#endif
+
+#ifdef USE_HARDCODE
+       char temp[64];
+       sprintf(temp, cm, y+1, x+1);
+       tp(temp);
+#endif
+
+}
+
+
+/*
+ * Go to the given screen location in a "clever" manner
+ *
+ * XXX XXX XXX This function could use some work!
+ */
+static void do_move(int x1, int y1, int x2, int y2)
+{
+       /* Hack -- unknown start location */
+       if ((x1 == x2) && (y1 == y2)) do_cm(x2, y2);
+
+       /* Left edge */
+       else if (x2 == 0)
+       {
+               if ((y2 <= 0) && ho) tp(ho);
+               else if ((y2 >= rows-1) && ll) tp(ll);
+               else if ((y2 == y1) && cr) tp(cr);
+#if 0
+               else if ((y2 == y1+1) && cr && dn)
+               { tp(cr); tp(dn); }
+               else if ((y2 == y1-1) && cr && up)
+               { tp(cr); tp(up); }
+#endif
+               else do_cm(x2, y2);
+       }
+
+#if 0
+       /* Up/Down one line */
+       else if ((x2 == x1) && (y2 == y1+1) && dn) tp(dn);
+       else if ((x2 == x1) && (y2 == y1-1) && up) tp(up);
+#endif
+
+       /* Default -- go directly there */
+       else do_cm(x2, y2);
+}
+
+
+
+
+/*
+ * Help initialize this file (see below)
+ */
+errr init_cap_aux(void)
+{
+
+#ifdef USE_TERMCAP
+
+       /* Get the terminal name (if possible) */
+       desc = getenv("TERM");
+       if (!desc) return (1);
+
+       /* Get the terminal info */
+       if (tgetent(blob, desc) != 1) return (2);
+
+       /* Get the (initial) columns and rows, or default */
+       if ((cols = tgetnum("co")) == -1) cols = 80;
+       if ((rows = tgetnum("li")) == -1) rows = 24;
+
+       /* Find out how to move the cursor to a given location */
+       cm = tgetstr("cm", &next);
+       if (!cm) return (10);
+
+       /* Find out how to move the cursor to a given position */
+       ch = tgetstr("ch", &next);
+       cv = tgetstr("cv", &next);
+
+       /* Find out how to "home" the screen */
+       ho = tgetstr("ho", &next);
+
+       /* Find out how to "last-line" the screen */
+       ll = tgetstr("ll", &next);
+
+       /* Find out how to do a "carriage return" */
+       cr = tgetstr("cr", &next);
+       if (!cr) cr = "\r";
+
+       /* Find out how to clear the screen */
+       cl = tgetstr("cl", &next);
+       if (!cl) return (11);
+
+       /* Find out how to clear to the end of display */
+       cd = tgetstr("cd", &next);
+
+       /* Find out how to clear to the end of the line */
+       ce = tgetstr("ce", &next);
+
+       /* Find out how to scroll (set the scroll region) */
+       cs = tgetstr("cs", &next);
+
+       /* Find out how to hilite */
+       so = tgetstr("so", &next);
+       se = tgetstr("se", &next);
+       if (!so || !se) so = se = NULL;
+
+       /* Find out how to bold */
+       md = tgetstr("md", &next);
+       me = tgetstr("me", &next);
+       if (!md || !me) md = me = NULL;
+
+       /* Check the cursor visibility stuff */
+       vi = tgetstr("vi", &next);
+       vs = tgetstr("vs", &next);
+       ve = tgetstr("ve", &next);
+
+#endif
+
+#ifdef USE_HARDCODE
+
+       /* Assume some defualt information */
+       rows = 24;
+       cols = 80;
+
+       /* Clear screen */
+       cl = "\033[2J\033[H";   /* --]--]-- */
+
+       /* Clear to end of line */
+       ce = "\033[K";  /* --]-- */
+
+       /* Hilite on/off */
+       so = "\033[7m"; /* --]-- */
+       se = "\033[m";  /* --]-- */
+
+       /* Scroll region */
+       cs = "\033[%d;%dr";     /* --]-- */
+
+       /* Move cursor */
+       cm = "\033[%d;%dH";     /* --]-- */
+
+#endif
+
+       /* Success */
+       return (0);
+}
+
+
+
+
+
+
+
+/*
+ * Save the "normal" and "angband" terminal settings
+ */
+
+#ifdef USE_TPOSIX
+
+static struct termios  norm_termios;
+
+static struct termios  game_termios;
+
+#endif
+
+#ifdef USE_TERMIO
+
+static struct termio  norm_termio;
+
+static struct termio  game_termio;
+
+#endif
+
+#ifdef USE_TCHARS
+
+static struct sgttyb  norm_ttyb;
+static struct tchars  norm_tchars;
+static struct ltchars norm_ltchars;
+static int            norm_local_chars;
+
+static struct sgttyb  game_ttyb;
+static struct tchars  game_tchars;
+static struct ltchars game_ltchars;
+static int            game_local_chars;
+
+#endif
+
+
+
+/*
+ * Are we active?  Not really needed.
+ */
+static int active = FALSE;
+
+
+/*
+ * The main screen (no sub-screens)
+ */
+static term term_screen_body;
+
+
+
+/*
+ * Place the "keymap" into its "normal" state
+ */
+static void keymap_norm(void)
+{
+
+#ifdef USE_TPOSIX
+
+       /* restore the saved values of the special chars */
+       (void)tcsetattr(0, TCSAFLUSH, &norm_termios);
+
+#endif
+
+#ifdef USE_TERMIO
+
+       /* restore the saved values of the special chars */
+       (void)ioctl(0, TCSETA, (char *)&norm_termio);
+
+#endif
+
+#ifdef USE_TCHARS
+
+       /* restore the saved values of the special chars */
+       (void)ioctl(0, TIOCSETP, (char *)&norm_ttyb);
+       (void)ioctl(0, TIOCSETC, (char *)&norm_tchars);
+       (void)ioctl(0, TIOCSLTC, (char *)&norm_ltchars);
+       (void)ioctl(0, TIOCLSET, (char *)&norm_local_chars);
+
+#endif
+
+}
+
+
+/*
+ * Place the "keymap" into the "game" state
+ */
+static void keymap_game(void)
+{
+
+#ifdef USE_TPOSIX
+
+       /* restore the saved values of the special chars */
+       (void)tcsetattr(0, TCSAFLUSH, &game_termios);
+
+#endif
+
+#ifdef USE_TERMIO
+
+       /* restore the saved values of the special chars */
+       (void)ioctl(0, TCSETA, (char *)&game_termio);
+
+#endif
+
+#ifdef USE_TCHARS
+
+       /* restore the saved values of the special chars */
+       (void)ioctl(0, TIOCSETP, (char *)&game_ttyb);
+       (void)ioctl(0, TIOCSETC, (char *)&game_tchars);
+       (void)ioctl(0, TIOCSLTC, (char *)&game_ltchars);
+       (void)ioctl(0, TIOCLSET, (char *)&game_local_chars);
+
+#endif
+
+}
+
+
+/*
+ * Save the normal keymap
+ */
+static void keymap_norm_prepare(void)
+{
+
+#ifdef USE_TPOSIX
+
+       /* Get the normal keymap */
+       tcgetattr(0, &norm_termios);
+
+#endif
+
+#ifdef USE_TERMIO
+
+       /* Get the normal keymap */
+       (void)ioctl(0, TCGETA, (char *)&norm_termio);
+
+#endif
+
+#ifdef USE_TCHARS
+
+       /* Get the normal keymap */
+       (void)ioctl(0, TIOCGETP, (char *)&norm_ttyb);
+       (void)ioctl(0, TIOCGETC, (char *)&norm_tchars);
+       (void)ioctl(0, TIOCGLTC, (char *)&norm_ltchars);
+       (void)ioctl(0, TIOCLGET, (char *)&norm_local_chars);
+
+#endif
+
+}
+
+
+/*
+ * Save the keymaps (normal and game)
+ */
+static void keymap_game_prepare(void)
+{
+
+#ifdef USE_TPOSIX
+
+       /* Acquire the current mapping */
+       tcgetattr(0, &game_termios);
+
+       /* Force "Ctrl-C" to interupt */
+       game_termios.c_cc[VINTR] = (char)3;
+
+       /* Force "Ctrl-Z" to suspend */
+       game_termios.c_cc[VSUSP] = (char)26;
+
+       /* Hack -- Leave "VSTART/VSTOP" alone */
+
+       /* Disable the standard control characters */
+       game_termios.c_cc[VQUIT] = (char)-1;
+       game_termios.c_cc[VERASE] = (char)-1;
+       game_termios.c_cc[VKILL] = (char)-1;
+       game_termios.c_cc[VEOF] = (char)-1;
+       game_termios.c_cc[VEOL] = (char)-1;
+
+       /* Normally, block until a character is read */
+       game_termios.c_cc[VMIN] = 1;
+       game_termios.c_cc[VTIME] = 0;
+
+       /* Hack -- Turn off "echo" and "canonical" mode */
+       game_termios.c_lflag &= ~(ECHO | ICANON);
+
+#endif
+
+#ifdef USE_TERMIO
+
+       /* Acquire the current mapping */
+       (void)ioctl(0, TCGETA, (char *)&game_termio);
+
+       /* Force "Ctrl-C" to interupt */
+       game_termio.c_cc[VINTR] = (char)3;
+
+       /* Force "Ctrl-Z" to suspend */
+       game_termio.c_cc[VSUSP] = (char)26;
+
+       /* Hack -- Leave "VSTART/VSTOP" alone */
+
+       /* Disable the standard control characters */
+       game_termio.c_cc[VQUIT] = (char)-1;
+       game_termio.c_cc[VERASE] = (char)-1;
+       game_termio.c_cc[VKILL] = (char)-1;
+       game_termio.c_cc[VEOF] = (char)-1;
+       game_termio.c_cc[VEOL] = (char)-1;
+
+#if 0
+       /* Disable the non-posix control characters */
+       game_termio.c_cc[VEOL2] = (char)-1;
+       game_termio.c_cc[VSWTCH] = (char)-1;
+       game_termio.c_cc[VDSUSP] = (char)-1;
+       game_termio.c_cc[VREPRINT] = (char)-1;
+       game_termio.c_cc[VDISCARD] = (char)-1;
+       game_termio.c_cc[VWERASE] = (char)-1;
+       game_termio.c_cc[VLNEXT] = (char)-1;
+       game_termio.c_cc[VSTATUS] = (char)-1;
+#endif
+
+       /* Normally, block until a character is read */
+       game_termio.c_cc[VMIN] = 1;
+       game_termio.c_cc[VTIME] = 0;
+
+       /* Hack -- Turn off "echo" and "canonical" mode */
+       game_termio.c_lflag &= ~(ECHO | ICANON);
+
+#endif
+
+#ifdef USE_TCHARS
+
+       /* Get the default game characters */
+       (void)ioctl(0, TIOCGETP, (char *)&game_ttyb);
+       (void)ioctl(0, TIOCGETC, (char *)&game_tchars);
+       (void)ioctl(0, TIOCGLTC, (char *)&game_ltchars);
+       (void)ioctl(0, TIOCLGET, (char *)&game_local_chars);
+
+       /* Force interupt (^C) */
+       game_tchars.t_intrc = (char)3;
+
+       /* Force start/stop (^Q, ^S) */
+       game_tchars.t_startc = (char)17;
+       game_tchars.t_stopc = (char)19;
+
+       /* Cancel some things */
+       game_tchars.t_quitc = (char)-1;
+       game_tchars.t_eofc = (char)-1;
+       game_tchars.t_brkc = (char)-1;
+
+       /* Force suspend (^Z) */
+       game_ltchars.t_suspc = (char)26;
+
+       /* Cancel some things */
+       game_ltchars.t_dsuspc = (char)-1;
+       game_ltchars.t_rprntc = (char)-1;
+       game_ltchars.t_flushc = (char)-1;
+       game_ltchars.t_werasc = (char)-1;
+       game_ltchars.t_lnextc = (char)-1;
+
+       /* XXX XXX XXX XXX Verify this before use */
+       /* Hack -- Turn off "echo" and "canonical" mode */
+       /* game_termios.c_lflag &= ~(ECHO | ICANON); */
+       game_ttyb.flag &= ~(ECHO | ICANON);
+
+#endif
+
+}
+
+
+
+
+
+
+
+
+/*
+ * Suspend/Resume
+ */
+static errr Term_xtra_cap_alive(int v)
+{
+       /* Suspend */
+       if (!v)
+       {
+               if (!active) return (1);
+
+               /* Hack -- make sure the cursor is visible */
+               curs_set(1);
+
+               /* Move to bottom right */
+               do_move(0, rows - 1, 0, rows - 1);
+
+               /* Go to normal keymap mode */
+               keymap_norm();
+
+               /* No longer active */
+               active = FALSE;
+       }
+
+       /* Resume */
+       else
+       {
+               if (active) return (1);
+
+               /* Hack -- restore the cursor location */
+               do_move(curx, cury, curx, cury);
+
+               /* Hack -- restore the cursor visibility */
+               curs_set(curv);
+
+               /* Go to angband keymap mode */
+               keymap_game();
+
+               /* Now we are active */
+               active = TRUE;
+       }
+
+       /* Success */
+       return (0);
+}
+
+
+
+/*
+ * Process an event
+ */
+static errr Term_xtra_cap_event(int v)
+{
+       int i, arg;
+       char buf[2];
+
+       /* Wait */
+       if (v)
+       {
+               /* Wait for one byte */
+               i = read(0, buf, 1);
+
+               /* Hack -- Handle "errors" */
+               if ((i <= 0) && (errno != EINTR)) exit_game_panic();
+       }
+
+       /* Do not wait */
+       else
+       {
+               /* Get the current flags for stdin */
+               if ((arg = fcntl(0, F_GETFL, 0)) < 1) return (1);
+
+               /* Tell stdin not to block */
+               if (fcntl(0, F_SETFL, arg | O_NDELAY) < 0) return (1);
+
+               /* Read one byte, if possible */
+               i = read(0, buf, 1);
+
+               /* Replace the flags for stdin */
+               if (fcntl(0, F_SETFL, arg)) return (1);
+       }
+
+       /* No keys ready */
+       if ((i != 1) || (!buf[0])) return (1);
+
+       /* Enqueue the keypress */
+       Term_keypress(buf[0]);
+
+       /* Success */
+       return (0);
+}
+
+
+
+
+/*
+ * Actually move the hardware cursor
+ */
+static errr Term_curs_cap(int x, int y)
+{
+       /* Literally move the cursor */
+       do_move(curx, cury, x, y);
+
+       /* Save the cursor location */
+       curx = x;
+       cury = y;
+
+       /* Success */
+       return (0);
+}
+
+
+/*
+ * Erase a grid of space
+ *
+ * XXX XXX XXX Note that we will never be asked to clear the
+ * bottom line all the way to the bottom right edge, since we
+ * have set the "avoid the bottom right corner" flag.
+ */
+static errr Term_wipe_cap(int x, int y, int n)
+{
+       int dx;
+
+       /* Place the cursor */
+       Term_curs_cap(x, y);
+
+       /* Wipe to end of line */
+       if (x + n >= 80)
+       {
+               do_ce();
+       }
+
+       /* Wipe region */
+       else
+       {
+               for (dx = 0; dx < n; ++dx)
+               {
+                       putc(' ', stdout);
+                       curx++;
+               }
+       }
+
+       /* Success */
+       return (0);
+}
+
+
+/*
+ * Place some text on the screen using an attribute
+ */
+static errr Term_text_cap(int x, int y, int n, byte a, cptr s)
+{
+       int i;
+
+       /* Move the cursor */
+       Term_curs_cap(x, y);
+
+       /* Dump the text, advance the cursor */
+       for (i = 0; s[i]; i++)
+       {
+               /* Dump the char */
+               putc(s[i], stdout);
+
+               /* Advance cursor 'X', and wrap */
+               if (++curx >= cols)
+               {
+                       /* Reset cursor 'X' */
+                       curx = 0;
+
+                       /* Hack -- Advance cursor 'Y', and wrap */
+                       if (++cury == rows) cury = 0;
+               }
+       }
+
+       /* Success */
+       return (0);
+}
+
+
+/*
+ * Handle a "special request"
+ */
+static errr Term_xtra_cap(int n, int v)
+{
+       /* Analyze the request */
+       switch (n)
+       {
+               /* Clear the screen */
+               case TERM_XTRA_CLEAR:
+               do_cl();
+               do_move(0, 0, 0, 0);
+               return (0);
+
+               /* Make a noise */
+               case TERM_XTRA_NOISE:
+               (void)write(1, "\007", 1);
+               return (0);
+
+               /* Change the cursor visibility */
+               case TERM_XTRA_SHAPE:
+               curv = v;
+               curs_set(v);
+               return (0);
+
+               /* Suspend/Resume */
+               case TERM_XTRA_ALIVE:
+               return (Term_xtra_cap_alive(v));
+
+               /* Process events */
+               case TERM_XTRA_EVENT:
+               return (Term_xtra_cap_event(v));
+
+               /* Flush events */
+               case TERM_XTRA_FLUSH:
+               while (!Term_xtra_cap_event(FALSE));
+               return (0);
+
+               /* Delay */
+               case TERM_XTRA_DELAY:
+               usleep(1000 * v);
+               return (0);
+       }
+
+       /* Not parsed */
+       return (1);
+}
+
+
+
+
+/*
+ * Init a "term" for this file
+ */
+static void Term_init_cap(term *t)
+{
+       if (active) return;
+
+       /* Assume cursor at top left */
+       curx = 0;
+       cury = 0;
+
+       /* Assume visible cursor */
+       curv = 1;
+
+       /* Clear the screen */
+       do_cl();
+
+       /* Hack -- visible cursor */
+       curs_set(1);
+
+       /* Assume active */
+       active = TRUE;
+}
+
+
+/*
+ * Nuke a "term" for this file
+ */
+static void Term_nuke_cap(term *t)
+{
+       if (!active) return;
+
+       /* Hack -- make sure the cursor is visible */
+       curs_set(1);
+
+       /* Move to bottom right */
+       do_move(0, rows - 1, 0, rows - 1);
+
+       /* Normal keymap */
+       keymap_norm();
+
+       /* No longer active */
+       active = FALSE;
+}
+
+
+
+
+
+
+
+
+
+
+/*
+ * Prepare this file for Angband usage
+ */
+errr init_cap(void)
+{
+       term *t = &term_screen_body;
+
+
+       /*** Initialize ***/
+
+       /* Initialize the screen */
+       if (init_cap_aux()) return (-1);
+
+       /* Hack -- Require large screen, or Quit with message */
+       if ((rows < 24) || (cols < 80)) quit("Screen too small!");
+
+
+       /*** Prepare to play ***/
+
+       /* Extract the normal keymap */
+       keymap_norm_prepare();
+
+       /* Extract the game keymap */
+       keymap_game_prepare();
+
+       /* Hack -- activate the game keymap */
+       keymap_game();
+
+       /* Hack -- Do NOT buffer stdout */
+       setbuf(stdout, NULL);
+
+
+       /*** Now prepare the term ***/
+
+       /* Initialize the term */
+       term_init(t, 80, 24, 256);
+
+       /* Avoid the bottom right corner */
+       t->icky_corner = TRUE;
+
+       /* Erase with "white space" */
+       t->attr_blank = TERM_WHITE;
+       t->char_blank = ' ';
+
+       /* Set some hooks */
+       t->init_hook = Term_init_cap;
+       t->nuke_hook = Term_nuke_cap;
+
+       /* Set some more hooks */
+       t->text_hook = Term_text_cap;
+       t->wipe_hook = Term_wipe_cap;
+       t->curs_hook = Term_curs_cap;
+       t->xtra_hook = Term_xtra_cap;
+
+       /* Save the term */
+       term_screen = t;
+
+       /* Activate it */
+       Term_activate(term_screen);
+
+       /* Success */
+       return (0);
+}
+
+
+#endif /* USE_CAP */
+
+