--- /usr/src/angband-282/src/main-gcu.c	Thu Sep  4 09:17:52 1997
+++ main-gcu.c	Sat Oct  4 02:56:10 1997
@@ -10,6 +10,10 @@
 
 /* Purpose: Allow use of Unix "curses" with Angband -BEN- */
 
+/*
+ * This file has been modified to use multiple text windows if your screen
+ * is larger than 80x25.  By Keldon Jones (keldon@umr.edu).
+ */
 
 /*
  * To use this file, you must define "USE_GCU" in the Makefile.
@@ -30,16 +34,6 @@
  * and uses the "termcap" information directly, or even bypasses the
  * "termcap" information and sends direct vt100 escape sequences.
  *
- * XXX XXX XXX This file provides only a single "term" window.
- *
- * The "init" and "nuke" hooks are built so that only the first init and
- * the last nuke actually do anything, but the other functions are not
- * "correct" for multiple windows.  Minor changes would also be needed
- * to allow the system to handle the "locations" of the various windows.
- *
- * But in theory, it should be possible to allow a 50 line screen to be
- * split into two (or more) sub-screens.
- *
  * XXX XXX XXX Consider the use of "savetty()" and "resetty()".
  */
 
@@ -63,6 +57,18 @@
 # include <curses.h>
 #endif
 
+typedef struct term_data term_data;
+
+struct term_data
+{
+	term t;
+
+	WINDOW *win;
+};
+
+#define MAX_TERM_DATA 4
+
+static term_data data[MAX_TERM_DATA];
 
 
 /*
@@ -192,11 +198,6 @@
 static int active = 0;
 
 
-/*
- * The main screen information
- */
-static term term_screen_body;
-
 
 #ifdef A_COLOR
 
@@ -498,17 +499,19 @@
  */
 static void Term_init_gcu(term *t)
 {
+	term_data *td = (term_data *)(t->data);
+
 	/* Count init's, handle first */
 	if (active++ != 0) return;
 
 	/* Erase the screen */
-	(void)clear();
+	(void)wclear(td->win);
 
 	/* Reset the cursor */
-	(void)move(0, 0);
+	(void)wmove(td->win, 0, 0);
 
 	/* Flush changes */
-	(void)refresh();
+	(void)wrefresh(td->win);
 
 	/* Game keymap */
 	keymap_game();
@@ -520,6 +523,11 @@
  */
 static void Term_nuke_gcu(term *t)
 {
+	term_data *td = (term_data *)(t->data);
+
+	/* Delete this window */
+	delwin(td->win);
+
 	/* Count nuke's, handle last */
 	if (--active != 0) return;
 
@@ -658,13 +666,15 @@
  */
 static errr Term_xtra_gcu(int n, int v)
 {
+	term_data *td = (term_data *)(Term->data);
+
 	/* Analyze the request */
 	switch (n)
 	{
 		/* Clear screen */
 		case TERM_XTRA_CLEAR:
-		touchwin(stdscr);
-		(void)clear();
+		touchwin(td->win);
+		(void)wclear(td->win);
 		return (0);
 
 		/* Make a noise */
@@ -674,7 +684,7 @@
 
 		/* Flush the Curses buffer */
 		case TERM_XTRA_FRESH:
-		(void)refresh();
+		(void)wrefresh(td->win);
 		return (0);
 
 #ifdef USE_CURS_SET
@@ -715,8 +725,10 @@
  */
 static errr Term_curs_gcu(int x, int y)
 {
+	term_data *td = (term_data *)(Term->data);
+
 	/* Literally move the cursor */
-	move(y, x);
+	wmove(td->win, y, x);
 
 	/* Success */
 	return (0);
@@ -729,19 +741,21 @@
  */
 static errr Term_wipe_gcu(int x, int y, int n)
 {
+	term_data *td = (term_data *)(Term->data);
+
 	/* Place cursor */
-	move(y, x);
+	wmove(td->win, y, x);
 
 	/* Clear to end of line */
 	if (x + n >= 80)
 	{
-		clrtoeol();
+		wclrtoeol(td->win);
 	}
 
 	/* Clear some characters */
 	else
 	{
-		while (n-- > 0) addch(' ');
+		while (n-- > 0) waddch(td->win, ' ');
 	}
 
 	/* Success */
@@ -758,6 +772,8 @@
  */
 static errr Term_text_gcu(int x, int y, int n, byte a, cptr s)
 {
+	term_data *td = (term_data *)(Term->data);
+
 	int i;
 
 	char text[81];
@@ -767,15 +783,15 @@
 	text[n] = 0;
 
 	/* Move the cursor and dump the string */
-	move(y, x);
+	wmove(td->win, y, x);
 
 #ifdef A_COLOR
 	/* Set the color */
-	if (can_use_color) attrset(colortable[a & 0x0F]);
+	if (can_use_color) wattrset(td->win, colortable[a & 0x0F]);
 #endif
 
 	/* Add the text */
-	addstr(text);
+	waddstr(td->win, text);
 
 	/* Success */
 	return (0);
@@ -783,6 +799,53 @@
 
 
 
+static errr term_data_init(term_data *td, int rows, int cols, int y, int x)
+{
+	term *t = &td->t;
+
+	/* Make sure the window has a positive size */
+	if (rows <= 0 || cols <= 0) return (0);
+
+	/* Create a window */
+	td->win = newwin(rows, cols, y, x);
+
+	/* Make sure we succeed */
+	if (!td->win)
+	{
+		plog("Failed to setup curses window.");
+		return (-1);
+	}
+
+	/* Initialize the term */
+	term_init(t, cols, rows, 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_gcu;
+	t->nuke_hook = Term_nuke_gcu;
+
+	/* Set some more hooks */
+	t->text_hook = Term_text_gcu;
+	t->wipe_hook = Term_wipe_gcu;
+	t->curs_hook = Term_curs_gcu;
+	t->xtra_hook = Term_xtra_gcu;
+
+	/* Save the data */
+	t->data = td;
+
+	/* Activate it */
+	Term_activate(t);
+
+
+	/* Success */
+	return (0);
+}
 
 /*
  * Prepare "curses" for use by the file "term.c"
@@ -796,8 +859,7 @@
 {
 	int i;
 
-	term *t = &term_screen_body;
-
+	int num_term = 4, next_win = 0;
 
 	/* Extract the normal keymap */
 	keymap_norm_prepare();
@@ -816,6 +878,7 @@
 	i = ((LINES < 24) || (COLS < 80));
 	if (i) quit("Angband needs an 80x24 'curses' screen");
 
+
 #ifdef A_COLOR
 
 	/*** Init the Color-pairs and set up a translation table ***/
@@ -918,34 +981,60 @@
 	keymap_game_prepare();
 
 
-	/*** Now prepare the term ***/
-
-	/* Initialize the term */
-	term_init(t, 80, 24, 256);
+	/*** Now prepare the term(s) ***/
+	for (i = 0; i < num_term; i++)
+	{
+		int rows, cols;
+		int y, x;
 
-	/* Avoid the bottom right corner */
-	t->icky_corner = TRUE;
+		switch (i)
+		{
+			/* Upper left */
+			case 0: rows = 24;
+				cols = 80;
+				y = x = 0;
+				break;
+			/* Lower left */
+			case 1: rows = LINES - 25;
+				cols = 80;
+				y = 25;
+				x = 0;
+				break;
+			/* Upper right */
+			case 2: rows = 24;
+				cols = COLS - 81;
+				y = 0;
+				x = 81;
+				break;
+			/* Lower right */
+			case 3: rows = LINES - 25;
+				cols = COLS - 81;
+				y = 25;
+				x = 81;
+				break;
+			/* XXX */
+			default: rows = cols = 0;
+				 y = x = 0;
+				 break;
+		}
 
-	/* Erase with "white space" */
-	t->attr_blank = TERM_WHITE;
-	t->char_blank = ' ';
+		/* No non-windows */
+		if (rows <= 0 || cols <= 0) continue;
 
-	/* Set some hooks */
-	t->init_hook = Term_init_gcu;
-	t->nuke_hook = Term_nuke_gcu;
+		/* Initialize */
+		term_data_init(&data[next_win], rows, cols, y, x);
 
-	/* Set some more hooks */
-	t->text_hook = Term_text_gcu;
-	t->wipe_hook = Term_wipe_gcu;
-	t->curs_hook = Term_curs_gcu;
-	t->xtra_hook = Term_xtra_gcu;
+		/* Store */
+		angband_term[next_win] = Term;
 
-	/* Save the term */
-	term_screen = t;
+		next_win++;
+	}
 
-	/* Activate it */
-	Term_activate(term_screen);
+	/* Activate the "Angband" window screen */
+	Term_activate(&data[0].t);
 
+	/* Store */
+	term_screen = &data[0].t;
 
 	/* Success */
 	return (0);
