Source:NetHack 2.3e/termcap.c

Below is the full text to termcap.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/termcap.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)termcap.c	2.3	87/12/12 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include   5.    #include 	/* for isdigit */ 6.   #include "hack.h"	/* for ROWNO, COLNO, *HI, *HE */ 7.   #ifdef GENIX 8.   #define	void	int	/* jhn - mod to prevent compiler from bombing */ 9.   #endif 10.   11.   extern char *tgetstr, *tgoto, *getenv; 12.  extern long *alloc; 13.   14.   #ifndef SYSV 15.  # ifndef LINT 16.  extern			/* it is defined in libtermlib (libtermcap) */ 17.  # endif 18.  	short ospeed;	/* terminal baudrate; used by tputs */ 19.  #else 20.  short	ospeed = 0;	/* gets around "not defined" error message */ 21.  #endif 22.   23.   static char tbuf[512]; 24.  static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE; 25.  static char *VS, *VE, *US, *UE; 26.  static int SG; 27.  static char PC = '\0'; 28.  char *CD;		/* tested in pri.c: docorner */ 29.  int CO, LI;		/* used in pri.c and whatis.c */ 30.   31.   #if defined(MSDOS) && !defined(TERMLIB) 32.  static char tgotobuf[20]; 33.  #define tgoto(fmt, x, y)	(sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf) 34.  #endif /* MSDOS /**/ 35.   36.   startup 37.  {  38.   	register char *term; 39.  	register char *tptr; 40.  	char *tbufptr, *pc; 41.  	register int i;  42. 43.  	tptr = (char *) alloc(1024); 44.   45.   	tbufptr = tbuf; 46.  	if(!(term = getenv("TERM"))) 47.  		error("Can't get TERM."); 48.  	if(!strncmp(term, "5620", 4)) 49.  		flags.nonull = 1;	/* this should be a termcap flag */ 50.  	if(tgetent(tptr, term) < 1) 51.  		error("Unknown terminal type: %s.", term); 52.  	if(pc = tgetstr("pc", &tbufptr)) 53.  		PC = *pc; 54.  	if(!(BC = tgetstr("bc", &tbufptr))) { 55.  		if(!tgetflag("bs")) 56.  			error("Terminal must backspace."); 57.  		BC = tbufptr; 58.  		tbufptr += 2; 59.  		*BC = '\b'; 60.  	}  61.   	HO = tgetstr("ho", &tbufptr); 62.  	CO = tgetnum("co"); 63.  	LI = tgetnum("li"); 64.  	if(CO < COLNO || LI < ROWNO+2) 65.  		setclipped; 66.  	if(!(CL = tgetstr("cl", &tbufptr))) 67.  		error("Hack needs CL."); 68.  	ND = tgetstr("nd", &tbufptr); 69.  	if(tgetflag("os")) 70.  		error("Hack can't have OS."); 71.  	CE = tgetstr("ce", &tbufptr); 72.  	UP = tgetstr("up", &tbufptr); 73.  	/* It seems that xd is no longer supported, and we should use 74.  	   a linefeed instead; unfortunately this requires resetting 75.  	   CRMOD, and many output routines will have to be modified 76.  	   slightly. Let's leave that till the next release. */ 77.   	XD = tgetstr("xd", &tbufptr); 78.  /* not: 		XD = tgetstr("do", &tbufptr); */ 79.  	if(!(CM = tgetstr("cm", &tbufptr))) { 80.  		if(!UP && !HO) 81.  			error("Hack needs CM or UP or HO."); 82.  		printf("Playing hack on terminals without cm is suspect...\n"); 83.  		getret; 84.  	}  85.   	SO = tgetstr("so", &tbufptr); 86.  	SE = tgetstr("se", &tbufptr); 87.  	US = tgetstr("us", &tbufptr); 88.  	UE = tgetstr("ue", &tbufptr); 89.  	SG = tgetnum("sg");	/* -1: not fnd; else # of spaces left by so */ 90.  	if(!SO || !SE || (SG > 0)) SO = SE = US = UE = ""; 91.  	TI = tgetstr("ti", &tbufptr); 92.  	TE = tgetstr("te", &tbufptr); 93.  	VS = VE = ""; 94.  #if defined(SORTING) || defined(MSDOSCOLOR) 95.  	/* Get rid of padding numbers for HI and HE. Hope they 96.  	 * aren't really needed!!! HI and HE are ouputted to the 97.  	 * pager as a string - so how can you send it NULLS??? 98.  	 *  -jsb 99.  	 */  100.  	    HI = (char *) alloc((unsigned)(strlen(SO)+1)); 101. 	    HE = (char *) alloc((unsigned)(strlen(SE)+1)); 102. 	    i = 0; 103. 	    while(isdigit(SO[i])) i++; 104. 	    strcpy(HI, &SO[i]); 105. 	    i = 0; 106. 	    while(isdigit(SE[i])) i++; 107. 	    strcpy(HE, &SE[i]); 108. #endif 109. 	CD = tgetstr("cd", &tbufptr); 110. 	set_whole_screen;		/* uses LI and CD */ 111. 	if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n"); 112. 	free(tptr); 113. #ifdef MSDOSCOLOR 114. 	init_hilite; 115. #endif 116. }  117.   118.  start_screen 119. {  120.  	xputs(TI); 121. 	xputs(VS); 122. #ifdef DGK 123. 	/* Select normal ASCII and line drawing character sets. 124. 	 */  125.  	if (flags.DECRainbow) 126. 		xputs("\033(B\033)0"); 127. #endif 128. }  129.   130.  end_screen 131. {  132.  	clear_screen; 133. 	xputs(VE); 134. 	xputs(TE); 135. }  136.   137.  /* Cursor movements */ 138. extern xchar curx, cury; 139.  140.  curs(x, y)  141. register int x, y;	/* not xchar: perhaps xchar is unsigned and 142. 			   curx-x would be unsigned as well */ 143. {  144.   145.  	if (y == cury && x == curx) 146. 		return; 147. 	if(!ND && (curx != x || x <= 3)) {	/* Extremely primitive */ 148. 		cmov(x, y);			/* bunker!wtm */ 149. 		return; 150. 	}  151.  	if(abs(cury-y) <= 3 && abs(curx-x) <= 3) 152. 		nocmov(x, y); 153. 	else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x y) { 166. 		if(UP) { 167. 			while (cury > y) {	/* Go up. */ 168.  				xputs(UP); 169. 				cury--; 170. 			}  171.  		} else if(CM) { 172. 			cmov(x, y); 173. 		} else if(HO) { 174. 			home; 175. 			curs(x, y); 176. 		} /* else impossible("..."); */ 177. 	} else if (cury < y) { 178. 		if(XD) { 179. 			while(cury < y) { 180. 				xputs(XD); 181. 				cury++; 182. 			}  183.  		} else if(CM) { 184. 			cmov(x, y); 185. 		} else { 186. 			while(cury < y) { 187. 				xputc('\n'); 188. 				curx = 1; 189. 				cury++; 190. 			}  191.  		}  192.  	}  193.  	if (curx < x) {		/* Go to the right. */ 194.  		if(!ND) cmov(x, y); else	/* bah */ 195. 			/* should instead print what is there already */ 196. 		while (curx < x) { 197. 			xputs(ND); 198. 			curx++; 199. 		}  200.  	} else if (curx > x) { 201. 		while (curx > x) {	/* Go to the left. */ 202.  			xputs(BC); 203. 			curx--; 204. 		}  205.  	}  206.  }  207.   208.  cmov(x, y)  209. register x, y; 210. { 211.  	xputs(tgoto(CM, x-1, y-1)); 212. 	cury = y;  213. curx = x; 214. } 215.   216.  xputc(c) char c; { 217. 	(void) fputc(c, stdout); 218. }  219.   220.  xputs(s) char *s; { 221. #if defined(MSDOS) && !defined(TERMLIB) 222. 	fputs(s, stdout); 223. #else 224. 	tputs(s, 1, xputc); 225. #endif 226. }  227.   228.  cl_end { 229. 	if(CE) 230. 		xputs(CE); 231. 	else {	/* no-CE fix - free after Harold Rynes */ 232. 		/* this looks terrible, especially on a slow terminal 233. 		   but is better than nothing */ 234. 		register cx = curx, cy = cury; 235.  236.  		while(curx < COLNO) { 237. 			xputc(' '); 238. 			curx++; 239. 		}  240.  		curs(cx, cy); 241. 	}  242.  }  243.   244.  clear_screen { 245. 	xputs(CL); 246. 	home; 247. }  248.   249.  home 250. {  251.  	if(HO) 252. 		xputs(HO); 253. 	else if(CM) 254. 		xputs(tgoto(CM, 0, 0)); 255. 	else 256. 		curs(1, 1);	/* using UP ... */ 257.  	curx = cury = 1; 258. }  259.   260.  standoutbeg 261. {  262.  	if(SO) xputs(SO); 263. }  264.   265.  standoutend 266. {  267.  	if(SE) xputs(SE); 268. }  269.   270.  backsp 271. {  272.  	xputs(BC); 273. 	curx--; 274. }  275.   276.  bell 277. {  278.  #ifdef DGKMOD 279. 	if (flags.silent) return; 280. #endif /* DGKMOD /**/ 281. 	(void) putchar('\007');		/* curx does not change */ 282. 	(void) fflush(stdout); 283. }  284.   285.  static short tmspc10[] = {		/* from termcap */ 286. 	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5  287.  };  288.   289.  delay_output { 290. 	/* delay 50 ms - could also use a 'nap'-system call */ 291. 	/* BUG: if the padding character is visible, as it is on the 5620 292. 	   then this looks terrible. */ 293.  #ifdef MSDOS 294. 	/* simulate the delay with "cursor here" */ 295. 	register i;  296. for (i = 0; i < 3; i++) { 297. 		cmov(curx, cury); 298. 		(void) fflush(stdout); 299. 	}  300.  #else /* MSDOS /**/ 301. 	if(!flags.nonull) 302. #ifdef TERMINFO 303. 		tputs("$<50>", 1, xputs); 304. #else 305. 		tputs("50", 1, xputs); 306. #endif 307. 		/* cbosgd!cbcephus!pds for SYS V R2 */ 308. 		/* is this terminfo, or what? */ 309.  		/* tputs("$<50>", 1, xputc); */ 310.  311.  	else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) { 312. 		/* delay by sending cm(here) an appropriate number of times */ 313. 		register int cmlen = strlen(tgoto(CM, curx-1, cury-1)); 314. 		register int i = 500 + tmspc10[ospeed]/2; 315.  316.  		while(i > 0) { 317. 			cmov(curx, cury); 318. 			i -= cmlen*tmspc10[ospeed]; 319. 		}  320.  	}  321.  #endif /* MSDOS /**/ 322. }  323.   324.  cl_eos			/* free after Robert Viduya */ 325. {				/* must only be called with curx = 1 */ 326.  327.  	if(CD) 328. 		xputs(CD); 329. 	else { 330. 		register int cx = curx, cy = cury; 331. 		while(cury <= LI-2) { 332. 			cl_end; 333. 			xputc('\n'); 334. 			curx = 1; 335. 			cury++; 336. 		}  337.  		cl_end; 338. 		curs(cx, cy); 339. 	}  340.  }  341.   342.  #ifdef MSDOSCOLOR 343. /* Sets up highlighting, using ANSI escape sequences, for monsters and 344.  * objects (highlight code found in pri.c). 345.  * The termcap entry for HI (from SO) is scanned to find the background 346.  * color. If everything is o.k., monsters are displayed in the color 347.  * used to define HILITE_MONSTER and objects are displayed in the color 348.  * used to define HILITE_OBJECT. */ 349.   350.  #define ESC		0x1b 351. #define NONE		0 352. #define HIGH_INTENSITY	1 353. #define BLACK		0 354. #define RED		1 355. #define GREEN		2 356. #define YELLOW		3 357. #define BLUE		4 358. #define MAGENTA		5 359. #define CYAN		6 360. #define WHITE		7 361.  362.  #define HILITE_ATTRIB	NONE 363. #define HILITE_MONSTER	RED 364. #define HILITE_OBJECT	YELLOW 365.  366.  init_hilite 367. {  368.  	register int backg, len, mfore, ofore; 369.  370.  	backg = BLACK; 371. 	mfore = ofore = WHITE; 372. 	/* find the background color, HI[len] == 'm' */ 373. 	len = strlen(HI) - 1; 374. 	if (len > 3) 375. 	if (isdigit(HI[len-1]) &&  376.  	    isdigit(HI[len-2]) && HI[len-2] != 3) { 377. 			backg = HI[len-1] - '0'; 378. 			mfore = HILITE_MONSTER; 379. 			ofore = HILITE_OBJECT; 380. 	}  381.  	if (mfore == backg || ofore == backg) { 382. 		if (len < 7) mfore = ofore = WHITE; 383. 		else { 384. 			if (HI[2] == '3') mfore = ofore = HI[3] - '0'; 385. 			else if (HI[4] == '3') mfore = ofore = HI[5] - '0'; 386. 			else mfore = ofore = WHITE; /* give up! */ 387.  		}  388.  	}  389.   390.  	HI_MON = (char *) alloc(sizeof("E[0;33;44;54m")); 391. 	sprintf(HI_MON, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB,  392.  	        mfore, backg); 393. 	HI_OBJ = (char *) alloc(sizeof("E[0;33;44;54m")); 394. 	sprintf(HI_OBJ, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB,  395.  	        ofore, backg); 396. }  397.   398.  #endif