Source:NetHack 2.2a/termcap.c

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