Source:NetHack 1.3d/termcap.c

Below is the full text to termcap.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/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	1.3	87/07/14 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* termcap.c - version 1.0.3 */ 4.    5.    #include   6.    #include "config.h"	/* for ROWNO and COLNO */ 7.   #include "hack.h"	/* for  *HI, *HE */ 8.   extern char *tgetstr, *tgoto, *getenv; 9.   extern long *alloc; 10.   11.   #ifndef lint 12.  extern			/* it is defined in libtermlib (libtermcap) */ 13.  #endif 14.  	short ospeed;		/* terminal baudrate; used by tputs */ 15.  static char tbuf[512]; 16.  static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE; 17.  static char *VS, *VE; 18.  static int SG; 19.  static char PC = '\0'; 20.  char *CD;		/* tested in pri.c: docorner */ 21.  int CO, LI;		/* used in pri.c and whatis.c */ 22.   23.   #ifdef MSDOS 24.  static char tgotobuf[20]; 25.  #define tgoto(fmt, x, y)	(sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf) 26.  #endif /* MSDOS /**/ 27.   28.   startup 29.  {  30.   #ifdef MSDOS 31.  	HO = "\033[H"; 32.  	CL = "\033[2J"; 33.  	CE = "\033[K"; 34.  	UP = "\033[1A"; 35.  	CM = "\033[%d;%dH";	/* used with function tgoto */ 36.  	ND = "\033[1C"; 37.  	XD = "\033[1B"; 38.  	BC = "\033[1D"; 39.  	SO = "\033[7m"; 40.  	SE = "\033[0m"; 41.  	TI = TE = VS = VE = ""; 42.  	CD = "\033"; 43.  	CO = COLNO; 44.  	LI = ROWNO; 45.  #if defined(DGK) || defined(SORTING) 46.  	/* Both HI and HE have 4 characters. The function let_to_name 47.  	 * in msdos.c uses this length when creating a buffer. If you 48.  	 * make HI and HE longer, you must also change the length of buf[] 49.  	 * in let_to_name 50.  	 */  51.   	HI = "\033[4m"; 52.  	HE = "\033[0m"; 53.  #endif 54.  #else 55.  	register char *term; 56.  	register char *tptr; 57.  	char *tbufptr, *pc; 58.   59.   	tptr = (char *) alloc(1024); 60.   61.   	tbufptr = tbuf; 62.  	if(!(term = getenv("TERM"))) 63.  		error("Can't get TERM."); 64.  	if(!strncmp(term, "5620", 4)) 65.  		flags.nonull = 1;	/* this should be a termcap flag */ 66.  	if(tgetent(tptr, term) < 1) 67.  		error("Unknown terminal type: %s.", term); 68.  	if(pc = tgetstr("pc", &tbufptr)) 69.  		PC = *pc; 70.  	if(!(BC = tgetstr("bc", &tbufptr))) { 71.  		if(!tgetflag("bs")) 72.  			error("Terminal must backspace."); 73.  		BC = tbufptr; 74.  		tbufptr += 2; 75.  		*BC = '\b'; 76.  	}  77.   	HO = tgetstr("ho", &tbufptr); 78.  	CO = tgetnum("co"); 79.  	LI = tgetnum("li"); 80.  	if(CO < COLNO || LI < ROWNO+2) 81.  		setclipped; 82.  	if(!(CL = tgetstr("cl", &tbufptr))) 83.  		error("Hack needs CL."); 84.  	ND = tgetstr("nd", &tbufptr); 85.  	if(tgetflag("os")) 86.  		error("Hack can't have OS."); 87.  	CE = tgetstr("ce", &tbufptr); 88.  	UP = tgetstr("up", &tbufptr); 89.  	/* It seems that xd is no longer supported, and we should use 90.  	   a linefeed instead; unfortunately this requires resetting 91.  	   CRMOD, and many output routines will have to be modified 92.  	   slightly. Let's leave that till the next release. */ 93.   	XD = tgetstr("xd", &tbufptr); 94.  /* not: 		XD = tgetstr("do", &tbufptr); */ 95.  	if(!(CM = tgetstr("cm", &tbufptr))) { 96.  		if(!UP && !HO) 97.  			error("Hack needs CM or UP or HO."); 98.  		printf("Playing hack on terminals without cm is suspect...\n"); 99.  		getret; 100. 	}  101.  	SO = tgetstr("so", &tbufptr); 102. 	SE = tgetstr("se", &tbufptr); 103. 	SG = tgetnum("sg");	/* -1: not fnd; else # of spaces left by so */ 104. 	if(!SO || !SE || (SG > 0)) SO = SE = 0; 105. #ifdef SORTING 106. 	HI = SO;	/* I know... Its a kluge. (MRS) */ 107. 	HE = SE; 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. #endif /* MSDOS /**/ 114. }  115.   116.  start_screen 117. {  118.  	xputs(TI); 119. 	xputs(VS); 120. #ifdef DGK 121. 	/* Select normal ASCII and line drawing character sets. 122. 	 */  123.  	if (flags.DECRainbow) 124. 		xputs("\033(B\033)0"); 125. #endif 126. }  127.   128.  end_screen 129. {  130.  	clear_screen; 131. 	xputs(VE); 132. 	xputs(TE); 133. }  134.   135.  /* Cursor movements */ 136. extern xchar curx, cury; 137.  138.  curs(x, y)  139. register int x, y;	/* not xchar: perhaps xchar is unsigned and 140. 			   curx-x would be unsigned as well */ 141. {  142.   143.  	if (y == cury && x == curx) 144. 		return; 145. 	if(!ND && (curx != x || x <= 3)) {	/* Extremely primitive */ 146. 		cmov(x, y);			/* bunker!wtm */ 147. 		return; 148. 	}  149.  	if(abs(cury-y) <= 3 && abs(curx-x) <= 3) 150. 		nocmov(x, y); 151. 	else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x y) { 164. 		if(UP) { 165. 			while (cury > y) {	/* Go up. */ 166.  				xputs(UP); 167. 				cury--; 168. 			}  169.  		} else if(CM) { 170. 			cmov(x, y); 171. 		} else if(HO) { 172. 			home; 173. 			curs(x, y); 174. 		} /* else impossible("..."); */ 175. 	} else if (cury < y) { 176. 		if(XD) { 177. 			while(cury < y) { 178. 				xputs(XD); 179. 				cury++; 180. 			}  181.  		} else if(CM) { 182. 			cmov(x, y); 183. 		} else { 184. 			while(cury < y) { 185. 				xputc('\n'); 186. 				curx = 1; 187. 				cury++; 188. 			}  189.  		}  190.  	}  191.  	if (curx < x) {		/* Go to the right. */ 192.  		if(!ND) cmov(x, y); else	/* bah */ 193. 			/* should instead print what is there already */ 194. 		while (curx < x) { 195. 			xputs(ND); 196. 			curx++; 197. 		}  198.  	} else if (curx > x) { 199. 		while (curx > x) {	/* Go to the left. */ 200.  			xputs(BC); 201. 			curx--; 202. 		}  203.  	}  204.  }  205.   206.  cmov(x, y)  207. register x, y; 208. { 209.  	xputs(tgoto(CM, x-1, y-1)); 210. 	cury = y;  211. curx = x; 212. } 213.   214.  xputc(c) char c; { 215. 	(void) fputc(c, stdout); 216. }  217.   218.  xputs(s) char *s; { 219. #ifdef MSDOS 220. 	fputs(s, stdout); 221. #else 222. 	tputs(s, 1, xputc); 223. #endif 224. }  225.   226.  cl_end { 227. 	if(CE) 228. 		xputs(CE); 229. 	else {	/* no-CE fix - free after Harold Rynes */ 230. 		/* this looks terrible, especially on a slow terminal 231. 		   but is better than nothing */ 232. 		register cx = curx, cy = cury; 233.  234.  		while(curx < COLNO) { 235. 			xputc(' '); 236. 			curx++; 237. 		}  238.  		curs(cx, cy); 239. 	}  240.  }  241.   242.  clear_screen { 243. 	xputs(CL); 244. 	xputs(HO); 245. 	curx = cury = 1; 246. }  247.   248.  home 249. {  250.  	if(HO) 251. 		xputs(HO); 252. 	else if(CM) 253. 		xputs(tgoto(CM, 0, 0)); 254. 	else 255. 		curs(1, 1);	/* using UP ... */ 256.  	curx = cury = 1; 257. }  258.   259.  standoutbeg 260. {  261.  	if(SO) xputs(SO); 262. }  263.   264.  standoutend 265. {  266.  	if(SE) xputs(SE); 267. }  268.   269.  backsp 270. {  271.  	xputs(BC); 272. 	curx--; 273. }  274.   275.  bell 276. {  277.  #ifdef DGKMOD 278. 	if (flags.silent) return; 279. #endif /* DGKMOD /**/ 280. 	(void) putchar('\007');		/* curx does not change */ 281. 	(void) fflush(stdout); 282. }  283.   284.  static short tmspc10[] = {		/* from termcap */ 285. 	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5  286.  };  287.   288.  delay_output { 289. 	/* delay 50 ms - could also use a 'nap'-system call */ 290. 	/* BUG: if the padding character is visible, as it is on the 5620 291. 	   then this looks terrible. */ 292.  #ifdef MSDOS 293. 	/* simulate the delay with "cursor here" */ 294. 	register i;  295. for (i = 0; i < 3; i++) { 296. 		cmov(curx, cury); 297. 		(void) fflush(stdout); 298. 	}  299.  #else 300. 	if(!flags.nonull) 301. 		tputs("50", 1, xputc); 302.  303.  		/* cbosgd!cbcephus!pds for SYS V R2 */ 304. 		/* is this terminfo, or what? */ 305.  		/* tputs("$<50>", 1, xputc); */ 306.  307.  	else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) { 308. 		/* delay by sending cm(here) an appropriate number of times */ 309. 		register int cmlen = strlen(tgoto(CM, curx-1, cury-1)); 310. 		register int i = 500 + tmspc10[ospeed]/2; 311.  312.  		while(i > 0) { 313. 			cmov(curx, cury); 314. 			i -= cmlen*tmspc10[ospeed]; 315. 		}  316.  	}  317.  #endif /* MSDOS /**/ 318. }  319.   320.  cl_eos			/* free after Robert Viduya */ 321. {				/* must only be called with curx = 1 */ 322.  323.  	if(CD) 324. 		xputs(CD); 325. 	else { 326. 		register int cx = curx, cy = cury; 327. 		while(cury <= LI-2) { 328. 			cl_end; 329. 			xputc('\n'); 330. 			curx = 1; 331. 			cury++; 332. 		}  333.  		cl_end; 334. 		curs(cx, cy); 335. 	}  336.  }