xref: /dflybsd-src/games/hack/hack.terminfo.c (revision 4318c66eac379e15105fe145d406dfef81b795f6)
1*4318c66eSSascha Wildner /*	$NetBSD: hack.terminfo.c,v 1.2 2011/10/03 12:32:28 roy Exp $	*/
2*4318c66eSSascha Wildner 
3*4318c66eSSascha Wildner /*
4*4318c66eSSascha Wildner  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5*4318c66eSSascha Wildner  * Amsterdam
6*4318c66eSSascha Wildner  * All rights reserved.
7*4318c66eSSascha Wildner  *
8*4318c66eSSascha Wildner  * Redistribution and use in source and binary forms, with or without
9*4318c66eSSascha Wildner  * modification, are permitted provided that the following conditions are
10*4318c66eSSascha Wildner  * met:
11*4318c66eSSascha Wildner  *
12*4318c66eSSascha Wildner  * - Redistributions of source code must retain the above copyright notice,
13*4318c66eSSascha Wildner  * this list of conditions and the following disclaimer.
14*4318c66eSSascha Wildner  *
15*4318c66eSSascha Wildner  * - Redistributions in binary form must reproduce the above copyright
16*4318c66eSSascha Wildner  * notice, this list of conditions and the following disclaimer in the
17*4318c66eSSascha Wildner  * documentation and/or other materials provided with the distribution.
18*4318c66eSSascha Wildner  *
19*4318c66eSSascha Wildner  * - Neither the name of the Stichting Centrum voor Wiskunde en
20*4318c66eSSascha Wildner  * Informatica, nor the names of its contributors may be used to endorse or
21*4318c66eSSascha Wildner  * promote products derived from this software without specific prior
22*4318c66eSSascha Wildner  * written permission.
23*4318c66eSSascha Wildner  *
24*4318c66eSSascha Wildner  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25*4318c66eSSascha Wildner  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26*4318c66eSSascha Wildner  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27*4318c66eSSascha Wildner  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28*4318c66eSSascha Wildner  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29*4318c66eSSascha Wildner  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30*4318c66eSSascha Wildner  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31*4318c66eSSascha Wildner  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32*4318c66eSSascha Wildner  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33*4318c66eSSascha Wildner  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34*4318c66eSSascha Wildner  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35*4318c66eSSascha Wildner  */
36*4318c66eSSascha Wildner 
37*4318c66eSSascha Wildner /*
38*4318c66eSSascha Wildner  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39*4318c66eSSascha Wildner  * All rights reserved.
40*4318c66eSSascha Wildner  *
41*4318c66eSSascha Wildner  * Redistribution and use in source and binary forms, with or without
42*4318c66eSSascha Wildner  * modification, are permitted provided that the following conditions
43*4318c66eSSascha Wildner  * are met:
44*4318c66eSSascha Wildner  * 1. Redistributions of source code must retain the above copyright
45*4318c66eSSascha Wildner  *    notice, this list of conditions and the following disclaimer.
46*4318c66eSSascha Wildner  * 2. Redistributions in binary form must reproduce the above copyright
47*4318c66eSSascha Wildner  *    notice, this list of conditions and the following disclaimer in the
48*4318c66eSSascha Wildner  *    documentation and/or other materials provided with the distribution.
49*4318c66eSSascha Wildner  * 3. The name of the author may not be used to endorse or promote products
50*4318c66eSSascha Wildner  *    derived from this software without specific prior written permission.
51*4318c66eSSascha Wildner  *
52*4318c66eSSascha Wildner  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53*4318c66eSSascha Wildner  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54*4318c66eSSascha Wildner  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
55*4318c66eSSascha Wildner  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56*4318c66eSSascha Wildner  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57*4318c66eSSascha Wildner  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58*4318c66eSSascha Wildner  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59*4318c66eSSascha Wildner  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60*4318c66eSSascha Wildner  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61*4318c66eSSascha Wildner  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62*4318c66eSSascha Wildner  */
63*4318c66eSSascha Wildner 
64*4318c66eSSascha Wildner #include <string.h>
65*4318c66eSSascha Wildner #include <termios.h>
66*4318c66eSSascha Wildner #include <term.h>
67*4318c66eSSascha Wildner #include <stdlib.h>
68*4318c66eSSascha Wildner #include <unistd.h>
69*4318c66eSSascha Wildner #include "hack.h"
70*4318c66eSSascha Wildner #include "extern.h"
71*4318c66eSSascha Wildner #include "def.flag.h"		/* for flags.nonull */
72*4318c66eSSascha Wildner 
73*4318c66eSSascha Wildner char           *CD;		/* tested in pri.c: docorner() */
74*4318c66eSSascha Wildner int             CO, LI;		/* used in pri.c and whatis.c */
75*4318c66eSSascha Wildner 
76*4318c66eSSascha Wildner void
startup(void)77*4318c66eSSascha Wildner startup(void)
78*4318c66eSSascha Wildner {
79*4318c66eSSascha Wildner 
80*4318c66eSSascha Wildner 	/* Will exit if no suitable term found */
81*4318c66eSSascha Wildner 	setupterm(NULL, 0, NULL);
82*4318c66eSSascha Wildner 	CO = columns;
83*4318c66eSSascha Wildner 	LI = lines;
84*4318c66eSSascha Wildner 	if (CO < COLNO || LI < ROWNO + 2)
85*4318c66eSSascha Wildner 		setclipped();
86*4318c66eSSascha Wildner 	if (clear_screen == NULL)
87*4318c66eSSascha Wildner 		error("Hack needs clear_screen.");
88*4318c66eSSascha Wildner 	if (over_strike)
89*4318c66eSSascha Wildner 		error("Hack can't have over_strike.");
90*4318c66eSSascha Wildner 	if (cursor_address == NULL) {
91*4318c66eSSascha Wildner 		printf("Playing hack without cursor_address is suspect...");
92*4318c66eSSascha Wildner 		getret();
93*4318c66eSSascha Wildner 	}
94*4318c66eSSascha Wildner 	set_whole_screen();
95*4318c66eSSascha Wildner }
96*4318c66eSSascha Wildner 
97*4318c66eSSascha Wildner void
startscreen(void)98*4318c66eSSascha Wildner startscreen(void)
99*4318c66eSSascha Wildner {
100*4318c66eSSascha Wildner }
101*4318c66eSSascha Wildner 
102*4318c66eSSascha Wildner void
endscreen(void)103*4318c66eSSascha Wildner endscreen(void)
104*4318c66eSSascha Wildner {
105*4318c66eSSascha Wildner }
106*4318c66eSSascha Wildner 
107*4318c66eSSascha Wildner static int
xputc(int c)108*4318c66eSSascha Wildner xputc(int c)
109*4318c66eSSascha Wildner {
110*4318c66eSSascha Wildner 	return (fputc(c, stdout));
111*4318c66eSSascha Wildner }
112*4318c66eSSascha Wildner 
113*4318c66eSSascha Wildner static void
xputs(const char * s)114*4318c66eSSascha Wildner xputs(const char *s)
115*4318c66eSSascha Wildner {
116*4318c66eSSascha Wildner 	tputs(s, 1, xputc);
117*4318c66eSSascha Wildner }
118*4318c66eSSascha Wildner 
119*4318c66eSSascha Wildner static void
cmov(int x,int y)120*4318c66eSSascha Wildner cmov(int x, int y)
121*4318c66eSSascha Wildner {
122*4318c66eSSascha Wildner 	char *p;
123*4318c66eSSascha Wildner 
124*4318c66eSSascha Wildner 	p = tiparm(cursor_address, y - 1, x - 1);
125*4318c66eSSascha Wildner 	if (p) {
126*4318c66eSSascha Wildner 		xputs(p);
127*4318c66eSSascha Wildner 		cury = y;
128*4318c66eSSascha Wildner 		curx = x;
129*4318c66eSSascha Wildner 	}
130*4318c66eSSascha Wildner }
131*4318c66eSSascha Wildner 
132*4318c66eSSascha Wildner static void
nocmov(int x,int y)133*4318c66eSSascha Wildner nocmov(int x, int y)
134*4318c66eSSascha Wildner {
135*4318c66eSSascha Wildner 	if (cury > y) {
136*4318c66eSSascha Wildner 		if (cursor_up) {
137*4318c66eSSascha Wildner 			while (cury > y) {	/* Go up. */
138*4318c66eSSascha Wildner 				xputs(cursor_up);
139*4318c66eSSascha Wildner 				cury--;
140*4318c66eSSascha Wildner 			}
141*4318c66eSSascha Wildner 		} else if (cursor_address) {
142*4318c66eSSascha Wildner 			cmov(x, y);
143*4318c66eSSascha Wildner 		} else if (cursor_home) {
144*4318c66eSSascha Wildner 			home();
145*4318c66eSSascha Wildner 			curs(x, y);
146*4318c66eSSascha Wildner 		}		/* else impossible("..."); */
147*4318c66eSSascha Wildner 	} else if (cury < y) {
148*4318c66eSSascha Wildner 		if (cursor_address) {
149*4318c66eSSascha Wildner 			cmov(x, y);
150*4318c66eSSascha Wildner #if 0
151*4318c66eSSascha Wildner 		} else if (XD) {
152*4318c66eSSascha Wildner 			while (cury < y) {
153*4318c66eSSascha Wildner 				xputs(XD);
154*4318c66eSSascha Wildner 				cury++;
155*4318c66eSSascha Wildner 			}
156*4318c66eSSascha Wildner #endif
157*4318c66eSSascha Wildner 		} else {
158*4318c66eSSascha Wildner 			while (cury < y) {
159*4318c66eSSascha Wildner 				xputc('\n');
160*4318c66eSSascha Wildner 				curx = 1;
161*4318c66eSSascha Wildner 				cury++;
162*4318c66eSSascha Wildner 			}
163*4318c66eSSascha Wildner 		}
164*4318c66eSSascha Wildner 	}
165*4318c66eSSascha Wildner 	if (curx < x) {		/* Go to the right. */
166*4318c66eSSascha Wildner 		if (!cursor_right)
167*4318c66eSSascha Wildner 			cmov(x, y);
168*4318c66eSSascha Wildner 		else		/* bah */
169*4318c66eSSascha Wildner 			/* should instead print what is there already */
170*4318c66eSSascha Wildner 			while (curx < x) {
171*4318c66eSSascha Wildner 				xputs(cursor_right);
172*4318c66eSSascha Wildner 				curx++;
173*4318c66eSSascha Wildner 			}
174*4318c66eSSascha Wildner 	} else if (curx > x) {
175*4318c66eSSascha Wildner 		while (curx > x)
176*4318c66eSSascha Wildner 			backsp();
177*4318c66eSSascha Wildner 	}
178*4318c66eSSascha Wildner }
179*4318c66eSSascha Wildner 
180*4318c66eSSascha Wildner /*
181*4318c66eSSascha Wildner  * Cursor movements
182*4318c66eSSascha Wildner  *
183*4318c66eSSascha Wildner  * x,y not xchar: perhaps xchar is unsigned and
184*4318c66eSSascha Wildner  * curx-x would be unsigned as well
185*4318c66eSSascha Wildner  */
186*4318c66eSSascha Wildner void
curs(int x,int y)187*4318c66eSSascha Wildner curs(int x, int y)
188*4318c66eSSascha Wildner {
189*4318c66eSSascha Wildner 
190*4318c66eSSascha Wildner 	if (y == cury && x == curx)
191*4318c66eSSascha Wildner 		return;
192*4318c66eSSascha Wildner 	if (!cursor_right && (curx != x || x <= 3)) { /* Extremely primitive */
193*4318c66eSSascha Wildner 		cmov(x, y);	/* bunker!wtm */
194*4318c66eSSascha Wildner 		return;
195*4318c66eSSascha Wildner 	}
196*4318c66eSSascha Wildner 	if (abs(cury - y) <= 3 && abs(curx - x) <= 3)
197*4318c66eSSascha Wildner 		nocmov(x, y);
198*4318c66eSSascha Wildner 	else if ((x <= 3 && abs(cury - y) <= 3) ||
199*4318c66eSSascha Wildner 	    (!cursor_address && x < abs(curx - x)))
200*4318c66eSSascha Wildner 	{
201*4318c66eSSascha Wildner 		(void) putchar('\r');
202*4318c66eSSascha Wildner 		curx = 1;
203*4318c66eSSascha Wildner 		nocmov(x, y);
204*4318c66eSSascha Wildner 	} else if (!cursor_address) {
205*4318c66eSSascha Wildner 		nocmov(x, y);
206*4318c66eSSascha Wildner 	} else
207*4318c66eSSascha Wildner 		cmov(x, y);
208*4318c66eSSascha Wildner }
209*4318c66eSSascha Wildner 
210*4318c66eSSascha Wildner void
cl_end(void)211*4318c66eSSascha Wildner cl_end(void)
212*4318c66eSSascha Wildner {
213*4318c66eSSascha Wildner 	if (clr_eol)
214*4318c66eSSascha Wildner 		xputs(clr_eol);
215*4318c66eSSascha Wildner 	else {			/* no-CE fix - free after Harold Rynes */
216*4318c66eSSascha Wildner 		/*
217*4318c66eSSascha Wildner 		 * this looks terrible, especially on a slow terminal but is
218*4318c66eSSascha Wildner 		 * better than nothing
219*4318c66eSSascha Wildner 		 */
220*4318c66eSSascha Wildner 		int cx = curx, cy = cury;
221*4318c66eSSascha Wildner 
222*4318c66eSSascha Wildner 		while (curx < COLNO) {
223*4318c66eSSascha Wildner 			xputc(' ');
224*4318c66eSSascha Wildner 			curx++;
225*4318c66eSSascha Wildner 		}
226*4318c66eSSascha Wildner 		curs(cx, cy);
227*4318c66eSSascha Wildner 	}
228*4318c66eSSascha Wildner }
229*4318c66eSSascha Wildner 
230*4318c66eSSascha Wildner void
clearscreen(void)231*4318c66eSSascha Wildner clearscreen(void)
232*4318c66eSSascha Wildner {
233*4318c66eSSascha Wildner 	xputs(clear_screen);
234*4318c66eSSascha Wildner 	curx = cury = 1;
235*4318c66eSSascha Wildner }
236*4318c66eSSascha Wildner 
237*4318c66eSSascha Wildner void
home(void)238*4318c66eSSascha Wildner home(void)
239*4318c66eSSascha Wildner {
240*4318c66eSSascha Wildner 	char *out;
241*4318c66eSSascha Wildner 
242*4318c66eSSascha Wildner 	if (cursor_home)
243*4318c66eSSascha Wildner 		xputs(cursor_home);
244*4318c66eSSascha Wildner 	else if ((cursor_address) && (out = tiparm(cursor_address, 0, 0)))
245*4318c66eSSascha Wildner 		xputs(out);
246*4318c66eSSascha Wildner 	else
247*4318c66eSSascha Wildner 		curs(1, 1);	/* using UP ... */
248*4318c66eSSascha Wildner 	curx = cury = 1;
249*4318c66eSSascha Wildner }
250*4318c66eSSascha Wildner 
251*4318c66eSSascha Wildner void
standoutbeg(void)252*4318c66eSSascha Wildner standoutbeg(void)
253*4318c66eSSascha Wildner {
254*4318c66eSSascha Wildner 	if (enter_standout_mode && exit_standout_mode && !magic_cookie_glitch)
255*4318c66eSSascha Wildner 		xputs(enter_standout_mode);
256*4318c66eSSascha Wildner }
257*4318c66eSSascha Wildner 
258*4318c66eSSascha Wildner void
standoutend(void)259*4318c66eSSascha Wildner standoutend(void)
260*4318c66eSSascha Wildner {
261*4318c66eSSascha Wildner 	if (exit_standout_mode && enter_standout_mode && !magic_cookie_glitch)
262*4318c66eSSascha Wildner 		xputs(exit_standout_mode);
263*4318c66eSSascha Wildner }
264*4318c66eSSascha Wildner 
265*4318c66eSSascha Wildner void
backsp(void)266*4318c66eSSascha Wildner backsp(void)
267*4318c66eSSascha Wildner {
268*4318c66eSSascha Wildner 	if (cursor_left)
269*4318c66eSSascha Wildner 		xputs(cursor_left);
270*4318c66eSSascha Wildner 	else
271*4318c66eSSascha Wildner 		(void) putchar('\b');
272*4318c66eSSascha Wildner 	curx--;
273*4318c66eSSascha Wildner }
274*4318c66eSSascha Wildner 
275*4318c66eSSascha Wildner void
sound_bell(void)276*4318c66eSSascha Wildner sound_bell(void)
277*4318c66eSSascha Wildner {
278*4318c66eSSascha Wildner 	(void) putchar('\007');	/* curx does not change */
279*4318c66eSSascha Wildner 	(void) fflush(stdout);
280*4318c66eSSascha Wildner }
281*4318c66eSSascha Wildner 
282*4318c66eSSascha Wildner void
delay_output(void)283*4318c66eSSascha Wildner delay_output(void)
284*4318c66eSSascha Wildner {
285*4318c66eSSascha Wildner 
286*4318c66eSSascha Wildner 	/* delay 50 ms - could also use a 'nap'-system call */
287*4318c66eSSascha Wildner 	  /* or the usleep call like this :-) */
288*4318c66eSSascha Wildner 	usleep(50000);
289*4318c66eSSascha Wildner }
290*4318c66eSSascha Wildner 
291*4318c66eSSascha Wildner void
cl_eos(void)292*4318c66eSSascha Wildner cl_eos(void)
293*4318c66eSSascha Wildner {				/* free after Robert Viduya *//* must only be
294*4318c66eSSascha Wildner 				 * called with curx = 1 */
295*4318c66eSSascha Wildner 
296*4318c66eSSascha Wildner 	if (clr_eos)
297*4318c66eSSascha Wildner 		xputs(clr_eos);
298*4318c66eSSascha Wildner 	else {
299*4318c66eSSascha Wildner 		int             cx = curx, cy = cury;
300*4318c66eSSascha Wildner 		while (cury <= LI - 2) {
301*4318c66eSSascha Wildner 			cl_end();
302*4318c66eSSascha Wildner 			xputc('\n');
303*4318c66eSSascha Wildner 			curx = 1;
304*4318c66eSSascha Wildner 			cury++;
305*4318c66eSSascha Wildner 		}
306*4318c66eSSascha Wildner 		cl_end();
307*4318c66eSSascha Wildner 		curs(cx, cy);
308*4318c66eSSascha Wildner 	}
309*4318c66eSSascha Wildner }
310