ftp.nice.ch/pub/next/games/strategic/NetHack.s.tar.gz#/NetHackSource/src/termcap.c

This is termcap.c in view mode; [Download] [Up]

/*	SCCS Id: @(#)termcap.c	3.0	88/11/20
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed.  See license for details. */
/* Changed for graphical version of NetHack on NextStep */
/*  by Christoph Marquardt 9/4/93 */


#define MONATTK_H	/* comment line for pre-compiled headers */
/* block some unused #defines to avoid overloading some cpp's */
#include "hack.h"	/* for ROWNO, COLNO, *HI, *HE, *AS, *AE */

#ifdef NEXT
#include "../next/nexttcap.c"
/* If OS is NEXT include special termcap file, else use old code */
#else

#include <ctype.h>	/* for isdigit() */

#include "termcap.h"

#if (!defined(SYSV) && !defined(HPUX)) || defined(TOS) || defined(UNIXPC)
# ifndef LINT
extern			/* it is defined in libtermlib (libtermcap) */
# endif
	short ospeed;	/* terminal baudrate; used by tputs */
#else
short	ospeed = 0;	/* gets around "not defined" error message */
#endif

#ifdef ASCIIGRAPH

#ifdef OVLB

boolean IBMgraphics = FALSE;

#endif /* OVLB */

#endif


#ifdef MICROPORT_286_BUG
#define Tgetstr(key) (tgetstr(key,tbuf))
#else
#define Tgetstr(key) (tgetstr(key,&tbufptr))
#endif /* MICROPORT_286_BUG **/

OSTATIC void FDECL(nocmov, (int, int));
#ifdef TEXTCOLOR
# ifdef TERMLIB
static void NDECL(init_hilite);
# endif
#endif

VSTATIC char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
VSTATIC char *VS, *VE, *US, *UE;
VSTATIC char *MR, *ME;
#if 0
VSTATIC char *MB, *MH;
VSTATIC char *MD;     /* may already be in use below */
#endif
#ifdef TERMLIB
# ifdef TEXTCOLOR
VSTATIC char *MD;
# endif
VSTATIC int SG;
#ifdef OVLB
XSTATIC char PC = '\0';
#else /* OVLB */
OSTATIC char PC;
#endif /* OVLB */
VSTATIC char tbuf[512];
#endif

#ifdef OVLB
static char nullstr[] = "";
#endif /* OVLB */

#ifndef TERMLIB
VSTATIC char tgotobuf[20];
# ifdef TOS
#define tgoto(fmt, x, y)	(Sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf)
# else
#define tgoto(fmt, x, y)	(Sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
# endif
#endif /* TERMLIB */

#ifdef OVLB

void
startup()
{
#ifdef TERMLIB
	register const char *term;
	register char *tptr;
	char *tbufptr, *pc;
#endif
	register int i;

#ifdef TERMLIB
# ifdef VMS
	term = getenv("EMACS_TERM");
	if (!term)
	    term = getenv("NETHACK_TERM");
	if (!term)
# endif
	term = getenv("TERM");
#endif
	/* Set the default map symbols */
	(void) memcpy((genericptr_t) showsyms, 
		(genericptr_t) defsyms, sizeof showsyms);

#ifdef ASCIIGRAPH
	/*
	 * If we're on an IBM box, default to the nice IBM Extended ASCII
	 * line-drawing characters (codepage 437).
	 *
	 * OS/2 defaults to a multilingual character set (codepage 850,
	 * corresponding to the ISO 8859 character set.  We should probably
	 * do a VioSetCp() call to set the codepage to 437.
	 *
	 * Someday we should do a full terminfo(4) check for ACS forms
	 * characters.
	 */
# if !defined(MSDOS) || defined(DECRAINBOW) || defined(OS2)
#  ifdef TERMLIB
	if (strncmp("AT", term, 2) == 0)
#  endif
# endif
	{
	    IBMgraphics = TRUE;
	    showsyms[S_vwall] = 0xb3;	/* meta-3, vertical rule */
	    showsyms[S_hodoor] = 0xb3;
	    showsyms[S_hwall] = 0xc4;	/* meta-D, horizontal rule */
	    showsyms[S_vodoor] = 0xc4;
	    showsyms[S_tlcorn] = 0xda;	/* meta-Z, top left corner */
	    showsyms[S_trcorn] = 0xbf;	/* meta-?, top right corner */
	    showsyms[S_blcorn] = 0xc0;	/* meta-@, bottom left */
	    showsyms[S_brcorn] = 0xd9;	/* meta-Y, bottom right */
	    showsyms[S_crwall] = 0xc5;	/* meta-E, cross */
	    showsyms[S_tuwall] = 0xc1;	/* meta-A, T up */
	    showsyms[S_tdwall] = 0xc2;	/* meta-B, T down */
	    showsyms[S_tlwall] = 0xb4;	/* meta-4, T left */
	    showsyms[S_trwall] = 0xc3;	/* meta-C, T right */
	    showsyms[S_vbeam] = 0xb3;	/* meta-3, vertical rule */
	    showsyms[S_hbeam] = 0xc4;	/* meta-D, horizontal rule */
	    showsyms[S_room] = 0xfa;	/* meta-z, centered dot */
	    showsyms[S_ndoor] = 0xfa;
	    showsyms[S_pool] = 0xf7;	/* meta-w, approx. equals */
	    showsyms[S_hodoor] = 0xfe;	/* meta-~, small centered square */
	    showsyms[S_vodoor] = 0xfe;
	}
#endif /* ASCIIGRAPH */

#ifdef TERMLIB
	if(!term)
#endif
#if defined(TOS) && defined(__GNUC__) && defined(TERMLIB)
		term = "builtin";		/* library has a default */
#else
# ifdef MACOS
	/* dummy termcap for the Mac */
	HO = "\033[H";
	CL = "\033[2J";     /* a pseudo-ANSI termcap */
	CE = "\033[K";
	CM = "\033[%d;%dH"; /* not used */
	UP = "\033[A";
	ND = "\033[C";
	XD = "\033[B";
 	BC = "\033[D";
 	TI = TE = SE = UE = US = HE = "\033[0m";
 	SO = "\033[1m";
 	AS = VS = VE = AE = "";
 	CO = COLNO;
 	LI = ROWNO + 3;
 	/* use special font ? */
	{
 	   extern short macflags;
 	   if (macflags & fUseCustomFont)
	    {
		Handle  theRes;
		unsigned char   *sym;
		short   i;

		sym = &showsyms[S_stone];
		theRes = GetResource(HACK_DATA,102);
		HLock(theRes);
		strncpy((char *)sym,(char *)(*theRes),32);
		HUnlock(theRes);
		ReleaseResource(theRes);
	    }
	}
#  ifdef TEXTCOLOR
	for (i = 0; i < MAXCOLORS; i++) {
	    hilites[i] = (char *) alloc(sizeof("E[cc"));
	    Sprintf(hilites[i], "\033[c%c", (char)(i+'a'));
	}
#  endif
# else /* MACOS */
# ifdef ANSI_DEFAULT
#  ifdef TOS
	{
		CO = 80; LI = 25;
		TI = VS = VE = TE = "";
		HO = "\033H";
		CL = "\033E";		/* the VT52 termcap */
		CE = "\033K";
		UP = "\033A";
		CM = "\033Y%c%c";	/* used with function tgoto() */
		ND = "\033C";
		XD = "\033B";
		BC = "\033D";
		SO = "\033p";
		SE = "\033q";
		HI = "\033p";
#ifdef TEXTCOLOR
		HE = "\033q\033b\017";
		for (i = 0; i < SIZE(hilites); i++) {
			hilites[i] = (char *) alloc(sizeof("Eb1"));
			Sprintf(hilites[i], (i%4)?"\033b%c" : "\033p", i);
		}
#else
		HE = "\033q";
#endif
	}
#  else /* TOS */
	{
#   ifdef DGK
		get_scr_size();
		if(CO < COLNO || LI < ROWNO+3)
			setclipped();
#   endif
		HO = "\033[H";
		CL = "\033[2J";		/* the ANSI termcap */
/*		CD = "\033[J"; */
		CE = "\033[K";
#   ifndef TERMLIB
		CM = "\033[%d;%dH";
#   else
		CM = "\033[%i%d;%dH";
#   endif
		UP = "\033[A";
		ND = "\033[C";
		XD = "\033[B";
#   ifdef MSDOS	/* backspaces are non-destructive */
		BC = "\b";
#   else
		BC = "\033[D";
#   endif
		HI = SO = "\033[1m";
		US = "\033[4m";
		MR = "\033[7m";
		TI = HE = SE = UE = ME = "\033[0m";
		/* strictly, SE should be 2, and UE should be 24,
		   but we can't trust all ANSI emulators to be
		   that complete.  -3. */
#   if !defined(MSDOS) || defined(DECRAINBOW)
		AS = "\016";
		AE = "\017";
#   endif
		TE = VS = VE = "";
#   ifdef TEXTCOLOR
		for (i = 0; i < MAXCOLORS / 2; i++) {
			hilites[i] = (char *) alloc(sizeof("\033[0;3%dm"));
			hilites[i+BRIGHT] = (char *) alloc(sizeof("\033[1;3%dm"));
#    ifdef MSDOS
			Sprintf(hilites[i], (i == BLUE ? "\033[1;3%dm" : "\033[0;3%dm"), i);
#    else
			Sprintf(hilites[i], "\033[0;3%dm", i);
#    endif
			Sprintf(hilites[i+BRIGHT], "\033[1;3%dm", i);
		}
#   endif
		return;
	}
#  endif /* TOS */
# else
		error("Can't get TERM.");
# endif /* ANSI_DEFAULT */
# endif /* MACOS */
#endif /* __GNUC__ && TOS && TERMCAP */
#ifdef TERMLIB
	tptr = (char *) alloc(1024);

	tbufptr = tbuf;
	if(!strncmp(term, "5620", 4))
		flags.nonull = 1;	/* this should be a termcap flag */
	if(tgetent(tptr, term) < 1)
		error("Unknown terminal type: %s.", term);
	if(pc = Tgetstr("pc"))
		PC = *pc;
# ifdef TERMINFO
	if(!(BC = Tgetstr("le"))) {	
# else
	if(!(BC = Tgetstr("bc"))) {	
# endif
# if !defined(MINIMAL_TERM) && !defined(HISX)
		if(!tgetflag("bs"))
			error("Terminal must backspace.");
# endif
		BC = tbufptr;
		tbufptr += 2;
		*BC = '\b';
	}
# ifdef MINIMAL_TERM
	HO = NULL;
# else
	HO = Tgetstr("ho");
# endif
	/*
	 * LI and CO are set in ioctl.c via a TIOCGWINSZ if available.  If
	 * the kernel has values for either we should use them rather than
	 * the values from TERMCAP ...
	 */
# ifndef DGK
	if (!CO) CO = tgetnum("co");
	if (!LI) LI = tgetnum("li");
# else
#  if defined(TOS) && defined(__GNUC__)
	if (!strcmp(term, "builtin"))
		get_scr_size();
	else {
#  endif
	CO = tgetnum("co");
	LI = tgetnum("li");
	if (!LI || !CO)			/* if we don't override it */
		get_scr_size();
#  if defined(TOS) && defined(__GNUC__)
	}
#  endif
# endif
	if(CO < COLNO || LI < ROWNO+3)
		setclipped();
	if(!(CL = Tgetstr("cl")))
		error("Hack needs CL.");
	ND = Tgetstr("nd");
	if(tgetflag("os"))
		error("Hack can't have OS.");
	CE = Tgetstr("ce");
	UP = Tgetstr("up");
	/* It seems that xd is no longer supported, and we should use
	   a linefeed instead; unfortunately this requires resetting
	   CRMOD, and many output routines will have to be modified
	   slightly. Let's leave that till the next release. */
	XD = Tgetstr("xd");
/* not: 		XD = Tgetstr("do"); */
	if(!(CM = Tgetstr("cm"))) {
		if(!UP && !HO)
			error("Hack needs CM or UP or HO.");
		Printf("Playing hack on terminals without cm is suspect...\n");
		getret();
	}
	SO = Tgetstr("so");
	SE = Tgetstr("se");
	US = Tgetstr("us");
	UE = Tgetstr("ue");
	SG = tgetnum("sg");	/* -1: not fnd; else # of spaces left by so */
	if(!SO || !SE || (SG > 0)) SO = SE = US = UE = nullstr;
	TI = Tgetstr("ti");
	TE = Tgetstr("te");
	VS = VE = nullstr;
# ifdef TERMINFO
	VS = Tgetstr("eA");	/* enable graphics */
# endif
# if 0
	MB = Tgetstr("mb");	/* blink */
	MD = Tgetstr("md");	/* boldface */
	MH = Tgetstr("mh");	/* dim */
# endif
	MR = Tgetstr("mr");	/* reverse */
	ME = Tgetstr("me");

	/* Get rid of padding numbers for HI and HE.  Hope they
	 * aren't really needed!!!  HI and HE are ouputted to the
	 * pager as a string - so how can you send it NULLS???
	 *  -jsb
	 */
	    HI = (char *) alloc((unsigned)(strlen(SO)+1));
	    HE = (char *) alloc((unsigned)(strlen(SE)+1));
	    i = 0;
	    while(isdigit(SO[i])) i++;
	    Strcpy(HI, &SO[i]);
	    i = 0;
	    while(isdigit(SE[i])) i++;
	    Strcpy(HE, &SE[i]);
	AS = Tgetstr("as");
	AE = Tgetstr("ae");
	CD = Tgetstr("cd");
# ifdef TEXTCOLOR
	MD = Tgetstr("md");
# endif
	set_whole_screen();		/* uses LI and CD */
	if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
	free((genericptr_t)tptr);
# ifdef TEXTCOLOR
	init_hilite();
# endif
#endif /* TERMLIB */
}

void
start_screen()
{
	xputs(TI);
	xputs(VS);
#ifdef DECRAINBOW
	/* Select normal ASCII and line drawing character sets.
	 */
	if (flags.DECRainbow) {
		xputs("\033(B\033)0");
		if (!AS) {
			AS = "\016";
			AE = "\017";
		}
	}
#endif /* DECRAINBOW */
}

void
end_screen()
{
	clear_screen();
	xputs(VE);
	xputs(TE);
}

/* Cursor movements */

#ifdef CLIPPING
/* if (x,y) is currently viewable, move the cursor there and return TRUE */
boolean
win_curs(x, y)
int x, y;
{
	if (clipping && (x<=clipx || x>=clipxmax || y<=clipy || y>=clipymax))
		return FALSE;
	y -= clipy;
	x -= clipx;
	curs(x, y+2);
	return TRUE;
}
#endif

void
curs(x, y)
register int x, y;	/* not xchar: perhaps xchar is unsigned and
			   curx-x would be unsigned as well */
{
	if (y == cury && x == curx)
		return;
	if(!ND && (curx != x || x <= 3)) {	/* Extremely primitive */
		cmov(x, y);			/* bunker!wtm */
		return;
	}
	if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
		nocmov(x, y);
	else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
		(void) putchar('\r');
		curx = 1;
		nocmov(x, y);
	} else if(!CM) {
		nocmov(x, y);
	} else
		cmov(x, y);
}

#endif /* OVLB */
#ifdef OVL0

XSTATIC void
nocmov(x, y)
int x,y;
{
	if (cury > y) {
		if(UP) {
			while (cury > y) {	/* Go up. */
				xputs(UP);
				cury--;
			}
		} else if(CM) {
			cmov(x, y);
		} else if(HO) {
			home();
			curs(x, y);
		} /* else impossible("..."); */
	} else if (cury < y) {
		if(XD) {
			while(cury < y) {
				xputs(XD);
				cury++;
			}
		} else if(CM) {
			cmov(x, y);
		} else {
			while(cury < y) {
				xputc('\n');
				curx = 1;
				cury++;
			}
		}
	}
	if (curx < x) {		/* Go to the right. */
		if(!ND) cmov(x, y); else	/* bah */
			/* should instead print what is there already */
		while (curx < x) {
			xputs(ND);
			curx++;
		}
	} else if (curx > x) {
		while (curx > x) {	/* Go to the left. */
			xputs(BC);
			curx--;
		}
	}
}

void
cmov(x, y)
register int x, y;
{
#ifdef MACOS
	mcurs(x-1, y-1);
#else
	xputs(tgoto(CM, x-1, y-1));
#endif
	cury = y;
	curx = x;
}

void
xputc(c)
char c;
{
#ifdef MACOS
	mputc(c);
#else
	(void) fputc(c, stdout);
#endif
}

void
xputs(s)
const char *s;
{
#ifndef MACOS
# ifndef TERMLIB
	(void) fputs(s, stdout);
# else
#  ifdef __STDC__
	tputs(s, 1, (int (*)())xputc);
#  else
	tputs(s, 1, xputc);
#  endif
# endif
#else
	mputs(s);
#endif
}

void
cl_end() {
	if(CE)
		xputs(CE);
	else {	/* no-CE fix - free after Harold Rynes */
		/* this looks terrible, especially on a slow terminal
		   but is better than nothing */
		register int cx = curx, cy = cury;

		while(curx < CO) {
			xputc(' ');
			curx++;
		}
		curs(cx, cy);
	}
}

#endif /* OVL0 */
#ifdef OVLB

void
clear_screen() {
	xputs(CL);
	home();
}

#endif /* OVLB */
#ifdef OVL0

void
home()
{
	if(HO)
		xputs(HO);
	else if(CM)
		xputs(tgoto(CM, 0, 0));
	else
		curs(1, 1);	/* using UP ... */
	curx = cury = 1;
}

void
standoutbeg()
{
	if(SO) xputs(SO);
}

void
standoutend()
{
	if(SE) xputs(SE);
}

void
revbeg()
{
	if(MR) xputs(MR);
}

#if 0	/* if you need one of these, uncomment it (here and in extern.h) */
void
boldbeg()
{
	if(MD) xputs(MD);
}

void
blinkbeg()
{
	if(MB) xputs(MB);
}

void
dimbeg()
/* not in most termcap entries */
{
	if(MH) xputs(MH);
}
#endif

void
m_end()
{
	if(ME) xputs(ME);
}

void
backsp()
{
	xputs(BC);
}

void
bell()
{
	if (flags.silent) return;
	(void) putchar('\007');		/* curx does not change */
	(void) fflush(stdout);
}

#ifdef ASCIIGRAPH
void
graph_on() {
	if (AS) xputs(AS);
}

void
graph_off() {
	if (AE) xputs(AE);
}
#endif

#endif /* OVL0 */
#ifdef OVL1

#if !defined(MSDOS) && !defined(MACOS)
# ifdef VMS
static const short tmspc10[] = {		/* from termcap */
	0, 2000, 1333, 909, 743, 666, 333, 166, 83, 55, 50, 41, 27, 20, 13, 10,
	5
};
# else
static const short tmspc10[] = {		/* from termcap */
	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
};
# endif
#endif

void
delay_output() {
	/* delay 50 ms - could also use a 'nap'-system call */
	/* BUG: if the padding character is visible, as it is on the 5620
	   then this looks terrible. */
#if defined(MSDOS) || defined(MACOS)
	/* simulate the delay with "cursor here" */
	register int i;
	for (i = 0; i < 3; i++) {
		cmov(curx, cury);
		(void) fflush(stdout);
	}
#else /* MSDOS || MACOS */
	if(!flags.nonull)
# ifdef TERMINFO
		/* cbosgd!cbcephus!pds for SYS V R2 */
#  ifdef __STDC__
		tputs("$<50>", 1, (int (*)())xputc);
#  else
		tputs("$<50>", 1, xputc);
#  endif
# else
#  ifdef __STDC__
		tputs("50", 1, (int (*)())xputc);
#  else
		tputs("50", 1, xputc);
#  endif
# endif

	else if(ospeed > 0 && ospeed < SIZE(tmspc10)) if(CM) {
		/* delay by sending cm(here) an appropriate number of times */
		register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
		register int i = 500 + tmspc10[ospeed]/2;

		while(i > 0) {
			cmov(curx, cury);
			i -= cmlen*tmspc10[ospeed];
		}
	}
#endif /* MSDOS || MACOS */
}

#endif /* OVL1 */
#ifdef OVLB

void
cl_eos()			/* free after Robert Viduya */
{				/* must only be called with curx = 1 */

	if(CD)
		xputs(CD);
	else {
		register int cx = curx, cy = cury;
		while(cury <= LI-2) {
			cl_end();
			xputc('\n');
			curx = 1;
			cury++;
		}
		cl_end();
		curs(cx, cy);
	}
}

#if defined(TEXTCOLOR) && defined(TERMLIB)
# ifdef UNIX
/*
 * Sets up color highlighting, using terminfo(4) escape sequences (highlight
 * code found in pri.c).  It is assumed that the background color is black.
 */
/* terminfo indexes for the basic colors it guarantees */
#define COLOR_BLACK   1		/* fake out to avoid black on black */
#define COLOR_BLUE    1
#define COLOR_GREEN   2
#define COLOR_CYAN    3
#define COLOR_RED     4
#define COLOR_MAGENTA 5
#define COLOR_YELLOW  6
#define COLOR_WHITE   7

/* map ANSI RGB to terminfo BGR */
const int ti_map[8] = {
	COLOR_BLACK, COLOR_RED, COLOR_GREEN, COLOR_YELLOW,
	COLOR_BLUE, COLOR_MAGENTA, COLOR_CYAN, COLOR_WHITE };

static void
init_hilite()
{
	register int c;
#  ifdef TERMINFO
	char *setf, *scratch;
	extern char *tparm();
#  endif

	for (c = 0; c < MAXCOLORS; c++)
		hilites[c] = HI;

#  ifdef TERMINFO
	if (tgetnum("Co") < 8 || (setf = tgetstr("Sf", 0)) == NULL)
		return;

	for (c = 0; c < MAXCOLORS / 2; c++) {
  		scratch = tparm(setf, ti_map[c]);
		hilites[c] = (char *) alloc(strlen(scratch) + 1);
		hilites[c+BRIGHT] = (char*) alloc(strlen(scratch)+strlen(MD)+1);
		Strcpy(hilites[c], scratch);
		Strcpy(hilites[c+BRIGHT], MD);
		Strcat(hilites[c+BRIGHT], scratch);
	}
#  endif
}

# else /* UNIX */

/*
 * Sets up highlighting sequences, using ANSI escape sequences (highlight code
 * found in pri.c).  The termcap entry for HI (from SO) is scanned to find the
 * background color.
 */

static void
init_hilite()
{
#  ifdef TOS
	int c;
	static char unhilite[] = "\033q\033b3\033c0";
#  else
	int backg = BLACK, foreg = WHITE, len;
	register int c, color;
#  endif

	for (c = 0; c < SIZE(hilites); c++)
		hilites[c] = HI;

#  ifdef TOS
	hilites[BROWN] = "\033b0\033c1";
	hilites[RED] = "\033b1";
	hilites[MAGENTA] = hilites[MAGENTA|BRIGHT] = "\033b1\033c2";
	hilites[CYAN] = hilites[CYAN|BRIGHT] = "\033b3\033c2";
	hilites[BLUE] = hilites[BLUE|BRIGHT] = "\033b2";
	hilites[GREEN] = hilites[GREEN|BRIGHT] = "\033b2\033c3";
	hilites[GRAY] = "\033b3\033c0";
	hilites[ORANGE_COLORED] = "\033b3\033c1";
	hilites[YELLOW] = "\033b1\033c3";
	hilites[WHITE] = "\033b0\033c3";
	HE = unhilite;	/* to turn off the color stuff too */
#  else /* TOS */
	/* find the background color, HI[len] == 'm' */
	len = strlen(HI) - 1;

	if (HI[len] != 'm' || len < 3) return;

	c = 2;
	while (c < len) {
	    if ((color = atoi(&HI[c])) == 0) {
		/* this also catches errors */
		foreg = WHITE; backg = BLACK;
	    /*
	    } else if (color == 1) {
		foreg |= BRIGHT;
	    */
	    } else if (color >= 30 && color <= 37) {
		foreg = color - 30;
	    } else if (color >= 40 && color <= 47) {
		backg = color - 40;
	    }
	    while (isdigit(HI[++c]));
	    c++;
	}

	for (c = 0; c < MAXCOLORS / 2; c++)
	    /* avoid invisibility */
	    if (foreg != c && backg != c) {
		hilites[c] = (char *) alloc(sizeof("\033[0;3%d;4%dm"));
		hilites[c+BRIGHT] = (char *) alloc(sizeof("\033[1;3%d;4%dm"));
#ifdef MSDOS    /* brighten low-visibility colors */
		if (c == BLUE)
		    Sprintf(hilites[c], "\033[1;3%d;4%dm", c, backg);
		else
#endif
		Sprintf(hilites[c], "\033[0;3%d;4%dm", c, backg);
		Sprintf(hilites[c+BRIGHT], "\033[1;3%d;4%dm", c, backg);
	    }
#  endif /* TOS */
}
# endif /* UNIX */
#endif /* TEXTCOLOR */

#endif /* OVLB */

#endif /* !NEXT */

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.