Source:NetHack 2.2a/termcap.c

From NetHackWiki
Revision as of 02:50, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 2.2a/termcap.c moved to Source:NetHack 2.2a/termcap.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

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

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)termcap.c	2.1	87/10/19
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include <stdio.h>
5.    #include <ctype.h>	/* 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<abs(curx-x))) {
185.  		(void) putchar('\r');
186.  		curx = 1;
187.  		nocmov(x, y);
188.  	} else if(!CM) {
189.  		nocmov(x, y);
190.  	} else
191.  		cmov(x, y);
192.  }
193.  
194.  nocmov(x, y)
195.  {
196.  	if (cury > 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 */