Created
October 11, 2017 09:49
-
-
Save OwenGHB/036c30677f02152ffe53395d0027200d to your computer and use it in GitHub Desktop.
256-color terminal support for ToME2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* File: main-gcu.c */ | |
/* | |
* Copyright (c) 1997 Ben Harrison, and others | |
* | |
* This software may be copied and distributed for educational, research, | |
* and not for profit purposes provided that this copyright and statement | |
* are included in all such copies. | |
*/ | |
/* | |
* This file helps Angband run on Unix/Curses machines. | |
* | |
* | |
* To use this file, you must define "USE_GCU" in the Makefile. | |
* | |
* | |
* Note that this file is not "intended" to support non-Unix machines, | |
* nor is it intended to support VMS or other bizarre setups. | |
* | |
* Also, this package assumes that the underlying "curses" handles both | |
* the "nonl()" and "cbreak()" commands correctly, see the "OPTION" below. | |
* | |
* This code should work with most versions of "curses" or "ncurses", | |
* and the "main-ncu.c" file (and USE_NCU define) are no longer used. | |
* | |
* This file provides up to 4 term windows. | |
* | |
* This file will attempt to redefine the screen colors to conform to | |
* standard Angband colors. It will only do so if the terminal type | |
* indicates that it can do so. See the page: | |
* | |
* http://www.umr.edu/~keldon/ang-patch/ncurses_color.html | |
* | |
* for information on this. | |
* | |
* Consider the use of "savetty()" and "resetty()". XXX XXX XXX | |
*/ | |
#include "main.h" | |
#include "util.h" | |
#include "variable.h" | |
#include <limits.h> | |
/* | |
* Hack -- play games with "bool" and "term" | |
*/ | |
#undef bool | |
/* Avoid 'struct term' name conflict with <curses.h> (via <term.h>) on AIX */ | |
#define term System_term | |
/* | |
* Include the proper "header" file | |
*/ | |
#ifdef USE_NCURSES | |
# include <ncurses.h> | |
#else | |
# include <curses.h> | |
#endif | |
#undef term | |
/* | |
* Try redefining the colors at startup. | |
*/ | |
#define REDEFINE_COLORS | |
/* | |
* 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(linux) | |
# 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> | |
#endif | |
#include <sys/types.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <dirent.h> | |
/* | |
* XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY" | |
* | |
* They should both work due to the "(i != 1)" test below. | |
*/ | |
#ifndef O_NDELAY | |
# define O_NDELAY O_NONBLOCK | |
#endif | |
/* | |
* OPTION: some machines lack "cbreak()" | |
* On these machines, we use an older definition | |
*/ | |
/* #define cbreak() crmode() */ | |
/* | |
* OPTION: some machines cannot handle "nonl()" and "nl()" | |
* On these machines, we can simply ignore those commands. | |
*/ | |
/* #define nonl() */ | |
/* #define nl() */ | |
/* | |
* 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 ltchars norm_special_chars; | |
static struct sgttyb norm_ttyb; | |
static struct tchars norm_tchars; | |
static int norm_local_chars; | |
static struct ltchars game_special_chars; | |
static struct sgttyb game_ttyb; | |
static struct tchars game_tchars; | |
static int game_local_chars; | |
#endif | |
/* | |
* Information about a term | |
*/ | |
typedef struct term_data term_data; | |
struct term_data | |
{ | |
term t; /* All term info */ | |
WINDOW *win; /* Pointer to the curses window */ | |
}; | |
/* Max number of windows on screen */ | |
#define MAX_TERM_DATA 4 | |
/* Information about our windows */ | |
static term_data data[MAX_TERM_DATA]; | |
/* | |
* Hack -- Number of initialized "term" structures | |
*/ | |
static int active = 0; | |
#ifdef A_COLOR | |
/* | |
* Hack -- define "A_BRIGHT" to be "A_BOLD", because on many | |
* machines, "A_BRIGHT" produces ugly "inverse" video. | |
*/ | |
#ifndef A_BRIGHT | |
# define A_BRIGHT A_BOLD | |
#endif | |
/* | |
* Software flag -- we are allowed to use color | |
*/ | |
static int can_use_color = FALSE; | |
/* | |
* Software flag -- we are allowed to change the colors | |
*/ | |
static int can_fix_color = FALSE; | |
/* | |
* Simple Angband to Curses color conversion table | |
*/ | |
static int colortable[16]; | |
/** | |
* Background color we should draw with; either BLACK or DEFAULT | |
*/ | |
static int bg_color = COLOR_BLACK; | |
#endif | |
/* | |
* 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, TIOCSLTC, (char *)&norm_special_chars); | |
(void)ioctl(0, TIOCSETP, (char *)&norm_ttyb); | |
(void)ioctl(0, TIOCSETC, (char *)&norm_tchars); | |
(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, TIOCSLTC, (char *)&game_special_chars); | |
(void)ioctl(0, TIOCSETP, (char *)&game_ttyb); | |
(void)ioctl(0, TIOCSETC, (char *)&game_tchars); | |
(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, TIOCGLTC, (char *)&norm_special_chars); | |
(void)ioctl(0, TIOCGETC, (char *)&norm_tchars); | |
(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; | |
#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; | |
/* Normally, block until a character is read */ | |
game_termio.c_cc[VMIN] = 1; | |
game_termio.c_cc[VTIME] = 0; | |
#endif | |
#ifdef USE_TCHARS | |
/* Get the default game characters */ | |
(void)ioctl(0, TIOCGETP, (char *)&game_ttyb); | |
(void)ioctl(0, TIOCGLTC, (char *)&game_special_chars); | |
(void)ioctl(0, TIOCGETC, (char *)&game_tchars); | |
(void)ioctl(0, TIOCLGET, (char *)&game_local_chars); | |
/* Force suspend (^Z) */ | |
game_special_chars.t_suspc = (char)26; | |
/* Cancel some things */ | |
game_special_chars.t_dsuspc = (char) - 1; | |
game_special_chars.t_rprntc = (char) - 1; | |
game_special_chars.t_flushc = (char) - 1; | |
game_special_chars.t_werasc = (char) - 1; | |
game_special_chars.t_lnextc = (char) - 1; | |
/* 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; | |
#endif | |
} | |
/* | |
* Suspend/Resume | |
*/ | |
static errr Term_xtra_gcu_alive(int v) | |
{ | |
int x, y; | |
/* Suspend */ | |
if (!v) | |
{ | |
/* Go to normal keymap mode */ | |
keymap_norm(); | |
/* Restore modes */ | |
noraw(); | |
echo(); | |
nl(); | |
/* Hack -- make sure the cursor is visible */ | |
Term_xtra(TERM_XTRA_SHAPE, 1); | |
/* Flush the curses buffer */ | |
(void)refresh(); | |
/* Get current cursor position */ | |
getyx(curscr, y, x); | |
/* Move the cursor to bottom right corner */ | |
mvcur(y, x, LINES - 1, 0); | |
/* Exit curses */ | |
endwin(); | |
/* Flush the output */ | |
(void)fflush(stdout); | |
} | |
/* Resume */ | |
else | |
{ | |
/* Refresh */ | |
/* (void)touchwin(curscr); */ | |
/* (void)wrefresh(curscr); */ | |
/* Restore the settings */ | |
raw(); | |
noecho(); | |
nonl(); | |
/* Go to angband keymap mode */ | |
keymap_game(); | |
} | |
/* Success */ | |
return (0); | |
} | |
/* | |
* Init the "curses" system | |
*/ | |
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 window */ | |
(void)wclear(td->win); | |
/* Reset the cursor */ | |
(void)wmove(td->win, 0, 0); | |
/* Flush changes */ | |
(void)wrefresh(td->win); | |
/* Game keymap */ | |
keymap_game(); | |
} | |
/* | |
* Nuke the "curses" system | |
*/ | |
static void Term_nuke_gcu(term *t) | |
{ | |
int x, y; | |
term_data *td = (term_data *)(t->data); | |
/* Delete this window */ | |
delwin(td->win); | |
/* Count nuke's, handle last */ | |
if (--active != 0) return; | |
/* Hack -- make sure the cursor is visible */ | |
Term_xtra(TERM_XTRA_SHAPE, 1); | |
#ifdef A_COLOR | |
/* Reset colors to defaults */ | |
start_color(); | |
#endif | |
/* Get current cursor position */ | |
getyx(curscr, y, x); | |
/* Move the cursor to bottom right corner */ | |
mvcur(y, x, LINES - 1, 0); | |
/* Flush the curses buffer */ | |
(void)refresh(); | |
/* Exit curses */ | |
endwin(); | |
/* Flush the output */ | |
(void)fflush(stdout); | |
/* Normal keymap */ | |
keymap_norm(); | |
} | |
/* | |
* Process events (with optional wait) | |
*/ | |
static errr Term_xtra_gcu_event(int v) | |
{ | |
int i, k; | |
char buf[2]; | |
/* Wait */ | |
if (v) | |
{ | |
/* Wait for one byte */ | |
i = read(0, buf, 1); | |
/* Hack -- Handle bizarre "errors" */ | |
if ((i <= 0) && (errno != EINTR)) abort(); | |
} | |
/* Do not wait */ | |
else | |
{ | |
/* Get the current flags for stdin */ | |
k = fcntl(0, F_GETFL, 0); | |
/* Oops */ | |
if (k < 0) return (1); | |
/* Tell stdin not to block */ | |
if (fcntl(0, F_SETFL, k | 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, k)) return (1); | |
} | |
/* Ignore "invalid" keys */ | |
if ((i != 1) || (!buf[0])) return (1); | |
/* Enqueue the keypress */ | |
Term_keypress(buf[0]); | |
/* Success */ | |
return (0); | |
} | |
static int scale_color(int i, int j, int scale) | |
{ | |
return (angband_color_table[i][j] * (scale - 1) + 127) / 255; | |
} | |
static int create_color(int i, int scale) | |
{ | |
int r = scale_color(i, 1, scale); | |
int g = scale_color(i, 2, scale); | |
int b = scale_color(i, 3, scale); | |
int rgb = 16 + scale * scale * r + scale * g + b; | |
/* In the case of white and black we need to use the ANSI colors */ | |
if (r == g && g == b) | |
{ | |
if (b == 0) rgb = 0; | |
if (b == scale) rgb = 15; | |
} | |
return rgb; | |
} | |
/* | |
* React to changes | |
*/ | |
static errr Term_xtra_gcu_react(void) | |
{ | |
#ifdef A_COLOR | |
if (COLORS == 256 || COLORS == 88) | |
{ | |
/* CTK: I snagged this color handling from current Vanilla */ | |
/* If we have more than 16 colors, find the best matches. These numbers | |
* correspond to xterm/rxvt's builtin color numbers--they do not | |
* correspond to curses' constants OR with curses' color pairs. | |
* | |
* XTerm has 216 (6*6*6) RGB colors, with each RGB setting 0-5. | |
* RXVT has 64 (4*4*4) RGB colors, with each RGB setting 0-3. | |
* | |
* Both also have the basic 16 ANSI colors, plus some extra grayscale | |
* colors which we do not use. | |
*/ | |
int i; | |
int scale = COLORS == 256 ? 6 : 4; | |
for (i = 0; i < 16; i++) | |
{ | |
int fg = create_color(i, scale); | |
init_pair(i + 1, fg, bg_color); | |
colortable[i] = COLOR_PAIR(i + 1) | A_NORMAL; | |
} | |
} | |
#endif | |
/* Success */ | |
return (0); | |
} | |
/* | |
* Handle a "special request" | |
*/ | |
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(td->win); | |
(void)wclear(td->win); | |
return (0); | |
/* Make a noise */ | |
case TERM_XTRA_NOISE: | |
(void)write(1, "\007", 1); | |
return (0); | |
/* Flush the Curses buffer */ | |
case TERM_XTRA_FRESH: | |
(void)wrefresh(td->win); | |
return (0); | |
/* Suspend/Resume curses */ | |
case TERM_XTRA_ALIVE: | |
return (Term_xtra_gcu_alive(v)); | |
/* Process events */ | |
case TERM_XTRA_EVENT: | |
return (Term_xtra_gcu_event(v)); | |
/* Flush events */ | |
case TERM_XTRA_FLUSH: | |
while (!Term_xtra_gcu_event(FALSE)); | |
return (0); | |
/* React to events */ | |
case TERM_XTRA_REACT: | |
Term_xtra_gcu_react(); | |
return (0); | |
} | |
/* Unknown */ | |
return (1); | |
} | |
/* | |
* Actually MOVE the hardware cursor | |
*/ | |
static errr Term_curs_gcu(int x, int y) | |
{ | |
term_data *td = (term_data *)(Term->data); | |
/* Literally move the cursor */ | |
wmove(td->win, y, x); | |
/* Success */ | |
return (0); | |
} | |
/* | |
* Place some text on the screen using an attribute | |
*/ | |
static errr Term_text_gcu(int x, int y, int n, byte a, cptr s) | |
{ | |
term_data *td = (term_data *)(Term->data); | |
int i; | |
#ifdef A_COLOR | |
/* Set the color */ | |
if (can_use_color) wattrset(td->win, colortable[a & 0x0F]); | |
#endif | |
/* Move the cursor */ | |
wmove(td->win, y, x); | |
/* Draw each character */ | |
for (i = 0; i < n; i++) | |
{ | |
/* Draw a normal character */ | |
waddch(td->win, (byte)s[i]); | |
} | |
/* Success */ | |
return (0); | |
} | |
/* | |
* Create a window for the given "term_data" argument. | |
* | |
* Assumes legal arguments. | |
*/ | |
static errr term_data_init_gcu(term_data *td, int rows, int cols, int y, int x) | |
{ | |
term *t = &td->t; | |
/* Create new window */ | |
td->win = newwin(rows, cols, y, x); | |
/* Check for failure */ | |
if (!td->win) | |
{ | |
/* Error */ | |
quit("Failed to setup curses window."); | |
} | |
/* Initialize the term */ | |
term_init(t, cols, rows, 256); | |
/* Avoid bottom right corner */ | |
t->icky_corner = TRUE; | |
/* 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->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); | |
} | |
static void hook_quit(cptr str) | |
{ | |
/* Unused */ | |
(void)str; | |
/* Exit curses */ | |
endwin(); | |
} | |
/* | |
* Prepare "curses" for use by the file "z-term.c" | |
* | |
* Installs the "hook" functions defined above, and then activates | |
* the main screen "term", which clears the screen and such things. | |
* | |
* Someone should really check the semantics of "initscr()" | |
*/ | |
int init_gcu(int argc, char **argv) | |
{ | |
int i; | |
int num_term = MAX_TERM_DATA, next_win = 0; | |
bool_ use_big_screen = FALSE; | |
/* Parse args */ | |
for (i = 1; i < argc; i++) | |
{ | |
if (prefix(argv[i], "-b")) | |
{ | |
use_big_screen = TRUE; | |
continue; | |
} | |
fprintf(stderr, "Ignoring option: %s", argv[i]); | |
} | |
/* Extract the normal keymap */ | |
keymap_norm_prepare(); | |
/* Initialize for other systems */ | |
if (initscr() == (WINDOW*)ERR) return ( -1); | |
/* Activate hooks */ | |
quit_aux = hook_quit; | |
/* Require standard size screen */ | |
if ((LINES < 24) || (COLS < 80)) | |
{ | |
quit("Angband needs at least an 80x24 'curses' screen"); | |
} | |
#ifdef A_COLOR | |
/*** Init the Color-pairs and set up a translation table ***/ | |
/* Do we have color, and enough color, available? */ | |
can_use_color = ((start_color() != ERR) && has_colors() && | |
(COLORS >= 8) && (COLOR_PAIRS >= 8)); | |
#ifdef REDEFINE_COLORS | |
/* Can we change colors? */ | |
can_fix_color = (can_use_color && can_change_color() && | |
(COLORS >= 16) && (COLOR_PAIRS > 8)); | |
#endif | |
/* Attempt to use customized colors */ | |
if (can_fix_color) | |
{ | |
/* Prepare the color pairs */ | |
for (i = 1; i <= 8; i++) | |
{ | |
/* Reset the color */ | |
if (init_pair(i, i - 1, 0) == ERR) | |
{ | |
quit("Color pair init failed"); | |
} | |
/* Set up the colormap */ | |
colortable[i - 1] = (COLOR_PAIR(i) | A_NORMAL); | |
colortable[i + 7] = (COLOR_PAIR(i) | A_BRIGHT); | |
} | |
/* Take account of "gamma correction" XXX XXX XXX */ | |
/* Prepare the "Angband Colors" */ | |
Term_xtra_gcu_react(); | |
} | |
/* Attempt to use colors */ | |
else if (can_use_color) | |
{ | |
/* Color-pair 0 is *always* WHITE on BLACK */ | |
/* Prepare the color pairs */ | |
init_pair(1, COLOR_RED, COLOR_BLACK); | |
init_pair(2, COLOR_GREEN, COLOR_BLACK); | |
init_pair(3, COLOR_YELLOW, COLOR_BLACK); | |
init_pair(4, COLOR_BLUE, COLOR_BLACK); | |
init_pair(5, COLOR_MAGENTA, COLOR_BLACK); | |
init_pair(6, COLOR_CYAN, COLOR_BLACK); | |
init_pair(7, COLOR_BLACK, COLOR_BLACK); | |
/* Prepare the "Angband Colors" -- Bright white is too bright */ | |
colortable[0] = (COLOR_PAIR(7) | A_NORMAL); /* Black */ | |
colortable[1] = (COLOR_PAIR(0) | A_NORMAL); /* White */ | |
colortable[2] = (COLOR_PAIR(6) | A_NORMAL); /* Grey XXX */ | |
colortable[3] = (COLOR_PAIR(1) | A_BRIGHT); /* Orange XXX */ | |
colortable[4] = (COLOR_PAIR(1) | A_NORMAL); /* Red */ | |
colortable[5] = (COLOR_PAIR(2) | A_NORMAL); /* Green */ | |
colortable[6] = (COLOR_PAIR(4) | A_NORMAL); /* Blue */ | |
colortable[7] = (COLOR_PAIR(3) | A_NORMAL); /* Umber */ | |
colortable[8] = (COLOR_PAIR(7) | A_BRIGHT); /* Dark-grey XXX */ | |
colortable[9] = (COLOR_PAIR(6) | A_BRIGHT); /* Light-grey XXX */ | |
colortable[10] = (COLOR_PAIR(5) | A_NORMAL); /* Purple */ | |
colortable[11] = (COLOR_PAIR(3) | A_BRIGHT); /* Yellow */ | |
colortable[12] = (COLOR_PAIR(5) | A_BRIGHT); /* Light Red XXX */ | |
colortable[13] = (COLOR_PAIR(2) | A_BRIGHT); /* Light Green */ | |
colortable[14] = (COLOR_PAIR(4) | A_BRIGHT); /* Light Blue */ | |
colortable[15] = (COLOR_PAIR(3) | A_NORMAL); /* Light Umber XXX */ | |
} | |
#endif | |
/*** Low level preparation ***/ | |
/* Prepare */ | |
raw(); | |
noecho(); | |
nonl(); | |
/* Extract the game keymap */ | |
keymap_game_prepare(); | |
/*** Now prepare the term(s) ***/ | |
/* Big screen -- one big term */ | |
if (use_big_screen) | |
{ | |
/* Create a term */ | |
term_data_init_gcu(&data[0], LINES, COLS, 0, 0); | |
/* Remember the term */ | |
angband_term[0] = &data[0].t; | |
} | |
/* No big screen -- create as many term windows as possible */ | |
else | |
{ | |
/* Create several terms */ | |
for (i = 0; i < num_term; i++) | |
{ | |
int rows, cols, y, x; | |
/* Decide on size and position */ | |
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 = y = x = 0; | |
break; | |
} | |
} | |
/* Skip non-existant windows */ | |
if (rows <= 0 || cols <= 0) continue; | |
/* Create a term */ | |
term_data_init_gcu(&data[next_win], rows, cols, y, x); | |
/* Remember the term */ | |
angband_term[next_win] = &data[next_win].t; | |
/* One more window */ | |
next_win++; | |
} | |
} | |
/* Activate the "Angband" window screen */ | |
Term_activate(&data[0].t); | |
/* Remember the active screen */ | |
term_screen = &data[0].t; | |
/* Success */ | |
return (0); | |
} | |
int main(int argc, char *argv[]) | |
{ | |
return main_real( | |
argc, | |
argv, | |
"gcu", | |
init_gcu, | |
" -- -b Requests big screen\n"); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment