/* File: main-sla.c */ /* Purpose: Actual Unix "slang" support for Angband */ /* * Author: hans@grumbeer.pfalz.de (Hans-Joachim Baader) * * Most of this code is adapted directly from "main-gcu.c" */ #include "angband.h" #ifdef USE_SLA #include /* * Are we "active"? */ static int slang_on = FALSE; /* * Can we use "color"? */ static bool_ can_use_color = FALSE; /* * Angband to SLang color conversion table */ static int colortable[16]; /* * Currently, only a single "term" is supported here */ static term term_screen_body; /* * Hack -- see below */ void init_pair (int index, char *foreground, char *background) { SLtt_set_color (index, "", foreground, background); } #define A_NORMAL 0 #define A_BOLD 8 #define A_REVERSE 0 #define REVERSE 8 #define COLOR_BLACK "black" #define COLOR_BLUE "blue" #define COLOR_GREEN "green" #define COLOR_CYAN "cyan" #define COLOR_RED "red" #define COLOR_MAGENTA "magenta" #define COLOR_YELLOW "brown" #define COLOR_WHITE "lightgray" #define COLOR_BBLACK "gray" #define COLOR_BBLUE "brightblue" #define COLOR_BGREEN "brightgreen" #define COLOR_BCYAN "brightcyan" #define COLOR_BRED "brightred" #define COLOR_BMAGENTA "brightmagenta" #define COLOR_BYELLOW "yellow" #define COLOR_BWHITE "white" static char *color_terminals [] = { #ifdef linux "console", #endif "linux", "xterm-color", "color-xterm", "xtermc", "ansi", 0 }; /* * Stolen from the Midnight Commander */ int has_colors(void) { int i; char *terminal; /* Access the terminal type */ terminal = getenv("TERM"); /* Check for colors */ SLtt_Use_Ansi_Colors = 0; if (NULL != getenv ("COLORTERM")) { SLtt_Use_Ansi_Colors = 1; } /* We want to allow overriding */ for (i = 0; color_terminals [i]; i++) { if (strcmp (color_terminals [i], terminal) == 0) { SLtt_Use_Ansi_Colors = 1; } } /* Setup emulated colors */ if (SLtt_Use_Ansi_Colors) { /*init_pair (REVERSE, "black", "white");*/ } /* Setup bizarre colors */ else { SLtt_set_mono (A_BOLD, NULL, SLTT_BOLD_MASK); SLtt_set_mono (A_REVERSE, NULL, SLTT_REV_MASK); SLtt_set_mono (A_BOLD | A_REVERSE, NULL, SLTT_BOLD_MASK | SLTT_REV_MASK); } return SLtt_Use_Ansi_Colors; } /* * Nuke SLang */ static void Term_nuke_sla(term *t) { if (!slang_on) return; /* Show the cursor */ /* curs_set(1); */ /* Clear the screen */ (void)SLsmg_cls(); /* Refresh */ SLsmg_refresh(); /* We are now off */ slang_on = FALSE; /* Shut down */ SLsmg_reset_smg(); SLang_reset_tty(); } /* * Init SLang */ static void Term_init_sla(term *t) { /* Note that we are on */ slang_on = TRUE; } /* * Process an event, wait if requested */ static errr Term_xtra_sla_event(int v) { /* Do not wait unless requested */ if (!v && (SLang_input_pending (0) == 0)) return (1); /* Get and enqueue the key */ Term_keypress(SLang_getkey ()); /* Success */ return 0; } /* * Suspend / Resume */ static errr Term_xtra_sla_alive(int v) { /* Suspend */ if (!v) { /* Oops */ if (!slang_on) return (1); /* We are now off */ slang_on = FALSE; /* Shut down (temporarily) */ SLsmg_reset_smg(); SLang_reset_tty(); } /* Resume */ else { /* Oops */ if (slang_on) return (1); /* Fix the screen */ SLsmg_refresh(); /* Note that we are on */ slang_on = TRUE; } /* Success */ return (0); } /* * Handle a "special request" */ static errr Term_xtra_sla(int n, int v) { /* Analyze the request */ switch (n) { /* Make a noise */ case TERM_XTRA_NOISE: (void)SLsmg_write_char('\007'); return (0); /* Flush the ncurses buffer */ case TERM_XTRA_FRESH: (void)SLsmg_refresh(); return (0); /* Make the cursor invisible or visible */ case TERM_XTRA_SHAPE: /* curs_set(v); */ return (0); /* Handle events */ case TERM_XTRA_EVENT: return (Term_xtra_sla_event(v)); /* Handle events */ case TERM_XTRA_FLUSH: while (!Term_xtra_sla_event(FALSE)); return (0); /* Suspend/Resume */ case TERM_XTRA_ALIVE: return (Term_xtra_sla_alive(v)); /* Clear the screen */ case TERM_XTRA_CLEAR: (void)SLsmg_cls(); SLsmg_gotorc(0, 0); return (0); /* Delay */ case TERM_XTRA_DELAY: usleep(1000 * v); return (0); } /* Oops */ return (1); } /* * Actually MOVE the hardware cursor */ static errr Term_curs_sla(int x, int y, int z) { /* Literally move the cursor */ SLsmg_gotorc (y, x); /* Success */ return 0; } /* * Erase some characters */ static errr Term_wipe_sla(int x, int y, int n) { int i; /* Place the cursor */ SLsmg_gotorc(y, x); /* Dump spaces */ for (i = 0; i < n; i++) SLsmg_write_char(' '); /* Success */ return 0; } /* * Place some text on the screen using an attribute */ static errr Term_text_sla(int x, int y, int n, byte a, cptr s) { /* Move the cursor */ SLsmg_gotorc(y, x); /* Set the color */ if (can_use_color) SLsmg_set_color(colortable[a&0x0F]); /* Dump the string */ SLsmg_write_nchars(s, n); /* Success */ return 0; } /* * Prepare "SLang" for use by the file "term.c" * Installs the "hook" functions defined above */ errr init_sla(void) { int i, err; term *t = &term_screen_body; /* Initialize, check for errors */ err = (SLang_init_tty( -1, TRUE, 0) == -1); /* Quit on error */ if (err) quit("SLang initialization failed"); /* Get terminal info */ SLtt_get_terminfo (); /* Initialize some more */ if (SLsmg_init_smg() == 0) { quit("Could not get virtual display memory"); } /* Check we have enough screen. */ err = ((SLtt_Screen_Rows < 24) || (SLtt_Screen_Cols < 80)); /* Quit with message */ if (err) quit("SLang screen must be at least 80x24"); /* Now let's go for a little bit of color! */ err = !has_colors(); /* Do we have color available? */ can_use_color = !err; /* Init the Color-pairs and set up a translation table */ /* If the terminal has enough colors */ /* Color-pair 0 is *always* WHITE on BLACK */ /* XXX XXX XXX See "main-gcu.c" for proper method */ /* Only do this on color machines */ if (can_use_color) { /* 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); init_pair(9, COLOR_BRED, COLOR_BLACK); init_pair(10, COLOR_BGREEN, COLOR_BLACK); init_pair(11, COLOR_BYELLOW, COLOR_BLACK); init_pair(12, COLOR_BBLUE, COLOR_BLACK); init_pair(13, COLOR_BMAGENTA, COLOR_BLACK); init_pair(14, COLOR_BCYAN, COLOR_BLACK); init_pair(15, COLOR_BBLACK, COLOR_BLACK); /* Prepare the color table */ colortable[0] = 7; /* Black */ colortable[1] = 0; /* White */ colortable[2] = 6; /* Grey XXX */ colortable[3] = 11; /* Orange XXX */ colortable[4] = 1; /* Red */ colortable[5] = 2; /* Green */ colortable[6] = 4; /* Blue */ colortable[7] = 3; /* Brown */ colortable[8] = 15; /* Dark-grey XXX */ colortable[9] = 14; /* Light-grey XXX */ colortable[10] = 5; /* Purple */ colortable[11] = 11; /* Yellow */ colortable[12] = 9; /* Light Red */ colortable[13] = 10; /* Light Green */ colortable[14] = 12; /* Light Blue */ colortable[15] = 3; /* Light Brown XXX */ } /* Initialize the term */ term_init(t, 80, 24, 64); /* Stick in some hooks */ t->nuke_hook = Term_nuke_sla; t->init_hook = Term_init_sla; /* Stick in some more hooks */ t->xtra_hook = Term_xtra_sla; t->curs_hook = Term_curs_sla; t->wipe_hook = Term_wipe_sla; t->text_hook = Term_text_sla; /* Save the term */ term_screen = t; /* Activate it */ Term_activate(t); /* Success */ return 0; } #endif /* USE_SLA */