xref: /csrg-svn/games/hack/hack.termcap.c (revision 41263)
1*41263Sbostic /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2*41263Sbostic /* hack.termcap.c - version 1.0.3 */
3*41263Sbostic 
4*41263Sbostic #include <stdio.h>
5*41263Sbostic #include "config.h"	/* for ROWNO and COLNO */
6*41263Sbostic #include "def.flag.h"	/* for flags.nonull */
7*41263Sbostic extern char *tgetstr(), *tgoto(), *getenv();
8*41263Sbostic extern long *alloc();
9*41263Sbostic 
10*41263Sbostic #ifndef lint
11*41263Sbostic extern			/* it is defined in libtermlib (libtermcap) */
12*41263Sbostic #endif lint
13*41263Sbostic 	short ospeed;		/* terminal baudrate; used by tputs */
14*41263Sbostic static char tbuf[512];
15*41263Sbostic static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
16*41263Sbostic static char *VS, *VE;
17*41263Sbostic static int SG;
18*41263Sbostic static char PC = '\0';
19*41263Sbostic char *CD;		/* tested in pri.c: docorner() */
20*41263Sbostic int CO, LI;		/* used in pri.c and whatis.c */
21*41263Sbostic 
startup()22*41263Sbostic startup()
23*41263Sbostic {
24*41263Sbostic 	register char *term;
25*41263Sbostic 	register char *tptr;
26*41263Sbostic 	char *tbufptr, *pc;
27*41263Sbostic 
28*41263Sbostic 	tptr = (char *) alloc(1024);
29*41263Sbostic 
30*41263Sbostic 	tbufptr = tbuf;
31*41263Sbostic 	if(!(term = getenv("TERM")))
32*41263Sbostic 		error("Can't get TERM.");
33*41263Sbostic 	if(!strncmp(term, "5620", 4))
34*41263Sbostic 		flags.nonull = 1;	/* this should be a termcap flag */
35*41263Sbostic 	if(tgetent(tptr, term) < 1)
36*41263Sbostic 		error("Unknown terminal type: %s.", term);
37*41263Sbostic 	if(pc = tgetstr("pc", &tbufptr))
38*41263Sbostic 		PC = *pc;
39*41263Sbostic 	if(!(BC = tgetstr("bc", &tbufptr))) {
40*41263Sbostic 		if(!tgetflag("bs"))
41*41263Sbostic 			error("Terminal must backspace.");
42*41263Sbostic 		BC = tbufptr;
43*41263Sbostic 		tbufptr += 2;
44*41263Sbostic 		*BC = '\b';
45*41263Sbostic 	}
46*41263Sbostic 	HO = tgetstr("ho", &tbufptr);
47*41263Sbostic 	CO = tgetnum("co");
48*41263Sbostic 	LI = tgetnum("li");
49*41263Sbostic 	if(CO < COLNO || LI < ROWNO+2)
50*41263Sbostic 		setclipped();
51*41263Sbostic 	if(!(CL = tgetstr("cl", &tbufptr)))
52*41263Sbostic 		error("Hack needs CL.");
53*41263Sbostic 	ND = tgetstr("nd", &tbufptr);
54*41263Sbostic 	if(tgetflag("os"))
55*41263Sbostic 		error("Hack can't have OS.");
56*41263Sbostic 	CE = tgetstr("ce", &tbufptr);
57*41263Sbostic 	UP = tgetstr("up", &tbufptr);
58*41263Sbostic 	/* It seems that xd is no longer supported, and we should use
59*41263Sbostic 	   a linefeed instead; unfortunately this requires resetting
60*41263Sbostic 	   CRMOD, and many output routines will have to be modified
61*41263Sbostic 	   slightly. Let's leave that till the next release. */
62*41263Sbostic 	XD = tgetstr("xd", &tbufptr);
63*41263Sbostic /* not: 		XD = tgetstr("do", &tbufptr); */
64*41263Sbostic 	if(!(CM = tgetstr("cm", &tbufptr))) {
65*41263Sbostic 		if(!UP && !HO)
66*41263Sbostic 			error("Hack needs CM or UP or HO.");
67*41263Sbostic 		printf("Playing hack on terminals without cm is suspect...\n");
68*41263Sbostic 		getret();
69*41263Sbostic 	}
70*41263Sbostic 	SO = tgetstr("so", &tbufptr);
71*41263Sbostic 	SE = tgetstr("se", &tbufptr);
72*41263Sbostic 	SG = tgetnum("sg");	/* -1: not fnd; else # of spaces left by so */
73*41263Sbostic 	if(!SO || !SE || (SG > 0)) SO = SE = 0;
74*41263Sbostic 	CD = tgetstr("cd", &tbufptr);
75*41263Sbostic 	set_whole_screen();		/* uses LI and CD */
76*41263Sbostic 	if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
77*41263Sbostic 	free(tptr);
78*41263Sbostic }
79*41263Sbostic 
start_screen()80*41263Sbostic start_screen()
81*41263Sbostic {
82*41263Sbostic 	xputs(TI);
83*41263Sbostic 	xputs(VS);
84*41263Sbostic }
85*41263Sbostic 
end_screen()86*41263Sbostic end_screen()
87*41263Sbostic {
88*41263Sbostic 	xputs(VE);
89*41263Sbostic 	xputs(TE);
90*41263Sbostic }
91*41263Sbostic 
92*41263Sbostic /* Cursor movements */
93*41263Sbostic extern xchar curx, cury;
94*41263Sbostic 
curs(x,y)95*41263Sbostic curs(x, y)
96*41263Sbostic register int x, y;	/* not xchar: perhaps xchar is unsigned and
97*41263Sbostic 			   curx-x would be unsigned as well */
98*41263Sbostic {
99*41263Sbostic 
100*41263Sbostic 	if (y == cury && x == curx)
101*41263Sbostic 		return;
102*41263Sbostic 	if(!ND && (curx != x || x <= 3)) {	/* Extremely primitive */
103*41263Sbostic 		cmov(x, y);			/* bunker!wtm */
104*41263Sbostic 		return;
105*41263Sbostic 	}
106*41263Sbostic 	if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
107*41263Sbostic 		nocmov(x, y);
108*41263Sbostic 	else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
109*41263Sbostic 		(void) putchar('\r');
110*41263Sbostic 		curx = 1;
111*41263Sbostic 		nocmov(x, y);
112*41263Sbostic 	} else if(!CM) {
113*41263Sbostic 		nocmov(x, y);
114*41263Sbostic 	} else
115*41263Sbostic 		cmov(x, y);
116*41263Sbostic }
117*41263Sbostic 
nocmov(x,y)118*41263Sbostic nocmov(x, y)
119*41263Sbostic {
120*41263Sbostic 	if (cury > y) {
121*41263Sbostic 		if(UP) {
122*41263Sbostic 			while (cury > y) {	/* Go up. */
123*41263Sbostic 				xputs(UP);
124*41263Sbostic 				cury--;
125*41263Sbostic 			}
126*41263Sbostic 		} else if(CM) {
127*41263Sbostic 			cmov(x, y);
128*41263Sbostic 		} else if(HO) {
129*41263Sbostic 			home();
130*41263Sbostic 			curs(x, y);
131*41263Sbostic 		} /* else impossible("..."); */
132*41263Sbostic 	} else if (cury < y) {
133*41263Sbostic 		if(XD) {
134*41263Sbostic 			while(cury < y) {
135*41263Sbostic 				xputs(XD);
136*41263Sbostic 				cury++;
137*41263Sbostic 			}
138*41263Sbostic 		} else if(CM) {
139*41263Sbostic 			cmov(x, y);
140*41263Sbostic 		} else {
141*41263Sbostic 			while(cury < y) {
142*41263Sbostic 				xputc('\n');
143*41263Sbostic 				curx = 1;
144*41263Sbostic 				cury++;
145*41263Sbostic 			}
146*41263Sbostic 		}
147*41263Sbostic 	}
148*41263Sbostic 	if (curx < x) {		/* Go to the right. */
149*41263Sbostic 		if(!ND) cmov(x, y); else	/* bah */
150*41263Sbostic 			/* should instead print what is there already */
151*41263Sbostic 		while (curx < x) {
152*41263Sbostic 			xputs(ND);
153*41263Sbostic 			curx++;
154*41263Sbostic 		}
155*41263Sbostic 	} else if (curx > x) {
156*41263Sbostic 		while (curx > x) {	/* Go to the left. */
157*41263Sbostic 			xputs(BC);
158*41263Sbostic 			curx--;
159*41263Sbostic 		}
160*41263Sbostic 	}
161*41263Sbostic }
162*41263Sbostic 
cmov(x,y)163*41263Sbostic cmov(x, y)
164*41263Sbostic register x, y;
165*41263Sbostic {
166*41263Sbostic 	xputs(tgoto(CM, x-1, y-1));
167*41263Sbostic 	cury = y;
168*41263Sbostic 	curx = x;
169*41263Sbostic }
170*41263Sbostic 
xputc(c)171*41263Sbostic xputc(c) char c; {
172*41263Sbostic 	(void) fputc(c, stdout);
173*41263Sbostic }
174*41263Sbostic 
xputs(s)175*41263Sbostic xputs(s) char *s; {
176*41263Sbostic 	tputs(s, 1, xputc);
177*41263Sbostic }
178*41263Sbostic 
cl_end()179*41263Sbostic cl_end() {
180*41263Sbostic 	if(CE)
181*41263Sbostic 		xputs(CE);
182*41263Sbostic 	else {	/* no-CE fix - free after Harold Rynes */
183*41263Sbostic 		/* this looks terrible, especially on a slow terminal
184*41263Sbostic 		   but is better than nothing */
185*41263Sbostic 		register cx = curx, cy = cury;
186*41263Sbostic 
187*41263Sbostic 		while(curx < COLNO) {
188*41263Sbostic 			xputc(' ');
189*41263Sbostic 			curx++;
190*41263Sbostic 		}
191*41263Sbostic 		curs(cx, cy);
192*41263Sbostic 	}
193*41263Sbostic }
194*41263Sbostic 
clear_screen()195*41263Sbostic clear_screen() {
196*41263Sbostic 	xputs(CL);
197*41263Sbostic 	curx = cury = 1;
198*41263Sbostic }
199*41263Sbostic 
home()200*41263Sbostic home()
201*41263Sbostic {
202*41263Sbostic 	if(HO)
203*41263Sbostic 		xputs(HO);
204*41263Sbostic 	else if(CM)
205*41263Sbostic 		xputs(tgoto(CM, 0, 0));
206*41263Sbostic 	else
207*41263Sbostic 		curs(1, 1);	/* using UP ... */
208*41263Sbostic 	curx = cury = 1;
209*41263Sbostic }
210*41263Sbostic 
standoutbeg()211*41263Sbostic standoutbeg()
212*41263Sbostic {
213*41263Sbostic 	if(SO) xputs(SO);
214*41263Sbostic }
215*41263Sbostic 
standoutend()216*41263Sbostic standoutend()
217*41263Sbostic {
218*41263Sbostic 	if(SE) xputs(SE);
219*41263Sbostic }
220*41263Sbostic 
backsp()221*41263Sbostic backsp()
222*41263Sbostic {
223*41263Sbostic 	xputs(BC);
224*41263Sbostic 	curx--;
225*41263Sbostic }
226*41263Sbostic 
bell()227*41263Sbostic bell()
228*41263Sbostic {
229*41263Sbostic 	(void) putchar('\007');		/* curx does not change */
230*41263Sbostic 	(void) fflush(stdout);
231*41263Sbostic }
232*41263Sbostic 
233*41263Sbostic static short tmspc10[] = {		/* from termcap */
234*41263Sbostic 	0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
235*41263Sbostic };
236*41263Sbostic 
delay_output()237*41263Sbostic delay_output() {
238*41263Sbostic 	/* delay 50 ms - could also use a 'nap'-system call */
239*41263Sbostic 	/* BUG: if the padding character is visible, as it is on the 5620
240*41263Sbostic 	   then this looks terrible. */
241*41263Sbostic 	if(!flags.nonull)
242*41263Sbostic 		tputs("50", 1, xputc);
243*41263Sbostic 
244*41263Sbostic 		/* cbosgd!cbcephus!pds for SYS V R2 */
245*41263Sbostic 		/* is this terminfo, or what? */
246*41263Sbostic 		/* tputs("$<50>", 1, xputc); */
247*41263Sbostic 
248*41263Sbostic 	else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
249*41263Sbostic 		/* delay by sending cm(here) an appropriate number of times */
250*41263Sbostic 		register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
251*41263Sbostic 		register int i = 500 + tmspc10[ospeed]/2;
252*41263Sbostic 
253*41263Sbostic 		while(i > 0) {
254*41263Sbostic 			cmov(curx, cury);
255*41263Sbostic 			i -= cmlen*tmspc10[ospeed];
256*41263Sbostic 		}
257*41263Sbostic 	}
258*41263Sbostic }
259*41263Sbostic 
cl_eos()260*41263Sbostic cl_eos()			/* free after Robert Viduya */
261*41263Sbostic {				/* must only be called with curx = 1 */
262*41263Sbostic 
263*41263Sbostic 	if(CD)
264*41263Sbostic 		xputs(CD);
265*41263Sbostic 	else {
266*41263Sbostic 		register int cx = curx, cy = cury;
267*41263Sbostic 		while(cury <= LI-2) {
268*41263Sbostic 			cl_end();
269*41263Sbostic 			xputc('\n');
270*41263Sbostic 			curx = 1;
271*41263Sbostic 			cury++;
272*41263Sbostic 		}
273*41263Sbostic 		cl_end();
274*41263Sbostic 		curs(cx, cy);
275*41263Sbostic 	}
276*41263Sbostic }
277