Source:NetHack 1.4f/termcap.c

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