--- /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 #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);