xref: /openbsd/games/hack/hack.termcap.c (revision aed906e4)
1*aed906e4Smestre /*	$OpenBSD: hack.termcap.c,v 1.9 2016/01/09 18:33:15 mestre Exp $	*/
2d0b779f3Sniklas 
3df930be7Sderaadt /*
4d25013f2Scamield  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
5d25013f2Scamield  * Amsterdam
6d25013f2Scamield  * All rights reserved.
7d25013f2Scamield  *
8d25013f2Scamield  * Redistribution and use in source and binary forms, with or without
9d25013f2Scamield  * modification, are permitted provided that the following conditions are
10d25013f2Scamield  * met:
11d25013f2Scamield  *
12d25013f2Scamield  * - Redistributions of source code must retain the above copyright notice,
13d25013f2Scamield  * this list of conditions and the following disclaimer.
14d25013f2Scamield  *
15d25013f2Scamield  * - Redistributions in binary form must reproduce the above copyright
16d25013f2Scamield  * notice, this list of conditions and the following disclaimer in the
17d25013f2Scamield  * documentation and/or other materials provided with the distribution.
18d25013f2Scamield  *
19d25013f2Scamield  * - Neither the name of the Stichting Centrum voor Wiskunde en
20d25013f2Scamield  * Informatica, nor the names of its contributors may be used to endorse or
21d25013f2Scamield  * promote products derived from this software without specific prior
22d25013f2Scamield  * written permission.
23d25013f2Scamield  *
24d25013f2Scamield  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
25d25013f2Scamield  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26d25013f2Scamield  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
27d25013f2Scamield  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
28d25013f2Scamield  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29d25013f2Scamield  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30d25013f2Scamield  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31d25013f2Scamield  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32d25013f2Scamield  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33d25013f2Scamield  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34d25013f2Scamield  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35d25013f2Scamield  */
36d25013f2Scamield 
37d25013f2Scamield /*
38d25013f2Scamield  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
39d25013f2Scamield  * All rights reserved.
40d25013f2Scamield  *
41d25013f2Scamield  * Redistribution and use in source and binary forms, with or without
42d25013f2Scamield  * modification, are permitted provided that the following conditions
43d25013f2Scamield  * are met:
44d25013f2Scamield  * 1. Redistributions of source code must retain the above copyright
45d25013f2Scamield  *    notice, this list of conditions and the following disclaimer.
46d25013f2Scamield  * 2. Redistributions in binary form must reproduce the above copyright
47d25013f2Scamield  *    notice, this list of conditions and the following disclaimer in the
48d25013f2Scamield  *    documentation and/or other materials provided with the distribution.
49d25013f2Scamield  * 3. The name of the author may not be used to endorse or promote products
50d25013f2Scamield  *    derived from this software without specific prior written permission.
51d25013f2Scamield  *
52d25013f2Scamield  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
53d25013f2Scamield  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
54d25013f2Scamield  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
55d25013f2Scamield  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
56d25013f2Scamield  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
57d25013f2Scamield  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
58d25013f2Scamield  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
59d25013f2Scamield  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
60d25013f2Scamield  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
61d25013f2Scamield  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62df930be7Sderaadt  */
63df930be7Sderaadt 
644a5fbbc4Spjanzen #include <curses.h>
65*aed906e4Smestre #include <stdlib.h>
664a5fbbc4Spjanzen #include <term.h>
67df930be7Sderaadt 
684a5fbbc4Spjanzen #include "hack.h"
694a5fbbc4Spjanzen 
70df930be7Sderaadt static char tbuf[512];
71df930be7Sderaadt static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
72df930be7Sderaadt static char *VS, *VE;
73df930be7Sderaadt static int SG;
74df930be7Sderaadt static char PC = '\0';
75df930be7Sderaadt char *CD;		/* tested in pri.c: docorner() */
76df930be7Sderaadt int CO, LI;		/* used in pri.c and whatis.c */
77df930be7Sderaadt 
784a5fbbc4Spjanzen static void nocmov(int, int);
794a5fbbc4Spjanzen static void cmov(int, int);
804a5fbbc4Spjanzen static int  xputc(int);
814a5fbbc4Spjanzen static void xputs(char *);
824a5fbbc4Spjanzen 
834a5fbbc4Spjanzen void
startup(void)84*aed906e4Smestre startup(void)
85df930be7Sderaadt {
864a5fbbc4Spjanzen 	char *term;
874a5fbbc4Spjanzen 	char *tptr;
88df930be7Sderaadt 	char *tbufptr, *pc;
89df930be7Sderaadt 
90df930be7Sderaadt 	tptr = (char *) alloc(1024);
91df930be7Sderaadt 
92df930be7Sderaadt 	tbufptr = tbuf;
93df930be7Sderaadt 	if(!(term = getenv("TERM")))
94df930be7Sderaadt 		error("Can't get TERM.");
95df930be7Sderaadt 	if(!strncmp(term, "5620", 4))
96df930be7Sderaadt 		flags.nonull = 1;	/* this should be a termcap flag */
97df930be7Sderaadt 	if(tgetent(tptr, term) < 1)
98df930be7Sderaadt 		error("Unknown terminal type: %s.", term);
994a5fbbc4Spjanzen 	if ((pc = tgetstr("pc", &tbufptr)))
100df930be7Sderaadt 		PC = *pc;
1014e007cc2Skstailey 	if(!(BC = tgetstr("le", &tbufptr))) {
102df930be7Sderaadt 		if(!tgetflag("bs"))
103df930be7Sderaadt 			error("Terminal must backspace.");
104df930be7Sderaadt 		BC = tbufptr;
105df930be7Sderaadt 		tbufptr += 2;
106df930be7Sderaadt 		*BC = '\b';
107df930be7Sderaadt 	}
108df930be7Sderaadt 	HO = tgetstr("ho", &tbufptr);
109df930be7Sderaadt 	CO = tgetnum("co");
110df930be7Sderaadt 	LI = tgetnum("li");
111df930be7Sderaadt 	if(CO < COLNO || LI < ROWNO+2)
112df930be7Sderaadt 		setclipped();
113df930be7Sderaadt 	if(!(CL = tgetstr("cl", &tbufptr)))
114df930be7Sderaadt 		error("Hack needs CL.");
115df930be7Sderaadt 	ND = tgetstr("nd", &tbufptr);
116df930be7Sderaadt 	if(tgetflag("os"))
117df930be7Sderaadt 		error("Hack can't have OS.");
118df930be7Sderaadt 	CE = tgetstr("ce", &tbufptr);
119df930be7Sderaadt 	UP = tgetstr("up", &tbufptr);
120df930be7Sderaadt 	/* It seems that xd is no longer supported, and we should use
121df930be7Sderaadt 	   a linefeed instead; unfortunately this requires resetting
122df930be7Sderaadt 	   CRMOD, and many output routines will have to be modified
123df930be7Sderaadt 	   slightly. Let's leave that till the next release. */
124df930be7Sderaadt 	XD = tgetstr("xd", &tbufptr);
125df930be7Sderaadt /* not: 		XD = tgetstr("do", &tbufptr); */
126df930be7Sderaadt 	if(!(CM = tgetstr("cm", &tbufptr))) {
127df930be7Sderaadt 		if(!UP && !HO)
128df930be7Sderaadt 			error("Hack needs CM or UP or HO.");
129df930be7Sderaadt 		printf("Playing hack on terminals without cm is suspect...\n");
130df930be7Sderaadt 		getret();
131df930be7Sderaadt 	}
132df930be7Sderaadt 	SO = tgetstr("so", &tbufptr);
133df930be7Sderaadt 	SE = tgetstr("se", &tbufptr);
134df930be7Sderaadt 	SG = tgetnum("sg");	/* -1: not fnd; else # of spaces left by so */
135df930be7Sderaadt 	if(!SO || !SE || (SG > 0)) SO = SE = 0;
136df930be7Sderaadt 	CD = tgetstr("cd", &tbufptr);
137df930be7Sderaadt 	set_whole_screen();		/* uses LI and CD */
138df930be7Sderaadt 	if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
139df930be7Sderaadt 	free(tptr);
140df930be7Sderaadt }
141df930be7Sderaadt 
1424a5fbbc4Spjanzen void
start_screen(void)143*aed906e4Smestre start_screen(void)
144df930be7Sderaadt {
145df930be7Sderaadt 	xputs(TI);
146df930be7Sderaadt 	xputs(VS);
147df930be7Sderaadt }
148df930be7Sderaadt 
1494a5fbbc4Spjanzen void
end_screen(void)150*aed906e4Smestre end_screen(void)
151df930be7Sderaadt {
152df930be7Sderaadt 	xputs(VE);
153df930be7Sderaadt 	xputs(TE);
154df930be7Sderaadt }
155df930be7Sderaadt 
156df930be7Sderaadt /* Cursor movements */
157df930be7Sderaadt extern xchar curx, cury;
158df930be7Sderaadt 
159*aed906e4Smestre /* int x, y;     not xchar: perhaps xchar is unsigned and
160*aed906e4Smestre  * curx-x would be unsigned as well
161*aed906e4Smestre  */
1624a5fbbc4Spjanzen void
curs(int x,int y)1634a5fbbc4Spjanzen curs(int x, int y)
164df930be7Sderaadt {
165df930be7Sderaadt 	if (y == cury && x == curx)
166df930be7Sderaadt 		return;
167df930be7Sderaadt 	if(!ND && (curx != x || x <= 3)) {	/* Extremely primitive */
168df930be7Sderaadt 		cmov(x, y);			/* bunker!wtm */
169df930be7Sderaadt 		return;
170df930be7Sderaadt 	}
171df930be7Sderaadt 	if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
172df930be7Sderaadt 		nocmov(x, y);
173df930be7Sderaadt 	else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
174df930be7Sderaadt 		(void) putchar('\r');
175df930be7Sderaadt 		curx = 1;
176df930be7Sderaadt 		nocmov(x, y);
177df930be7Sderaadt 	} else if(!CM) {
178df930be7Sderaadt 		nocmov(x, y);
179df930be7Sderaadt 	} else
180df930be7Sderaadt 		cmov(x, y);
181df930be7Sderaadt }
182df930be7Sderaadt 
1834a5fbbc4Spjanzen static void
nocmov(int x,int y)1844a5fbbc4Spjanzen nocmov(int x, int y)
185df930be7Sderaadt {
186df930be7Sderaadt 	if (cury > y) {
187df930be7Sderaadt 		if(UP) {
188df930be7Sderaadt 			while (cury > y) {	/* Go up. */
189df930be7Sderaadt 				xputs(UP);
190df930be7Sderaadt 				cury--;
191df930be7Sderaadt 			}
192df930be7Sderaadt 		} else if(CM) {
193df930be7Sderaadt 			cmov(x, y);
194df930be7Sderaadt 		} else if(HO) {
195df930be7Sderaadt 			home();
196df930be7Sderaadt 			curs(x, y);
197df930be7Sderaadt 		} /* else impossible("..."); */
198df930be7Sderaadt 	} else if (cury < y) {
199df930be7Sderaadt 		if(XD) {
200df930be7Sderaadt 			while(cury < y) {
201df930be7Sderaadt 				xputs(XD);
202df930be7Sderaadt 				cury++;
203df930be7Sderaadt 			}
204df930be7Sderaadt 		} else if(CM) {
205df930be7Sderaadt 			cmov(x, y);
206df930be7Sderaadt 		} else {
207df930be7Sderaadt 			while(cury < y) {
208df930be7Sderaadt 				xputc('\n');
209df930be7Sderaadt 				curx = 1;
210df930be7Sderaadt 				cury++;
211df930be7Sderaadt 			}
212df930be7Sderaadt 		}
213df930be7Sderaadt 	}
214df930be7Sderaadt 	if (curx < x) {		/* Go to the right. */
215df930be7Sderaadt 		if(!ND) cmov(x, y); else	/* bah */
216df930be7Sderaadt 			/* should instead print what is there already */
217df930be7Sderaadt 		while (curx < x) {
218df930be7Sderaadt 			xputs(ND);
219df930be7Sderaadt 			curx++;
220df930be7Sderaadt 		}
221df930be7Sderaadt 	} else if (curx > x) {
222df930be7Sderaadt 		while (curx > x) {	/* Go to the left. */
223df930be7Sderaadt 			xputs(BC);
224df930be7Sderaadt 			curx--;
225df930be7Sderaadt 		}
226df930be7Sderaadt 	}
227df930be7Sderaadt }
228df930be7Sderaadt 
2294a5fbbc4Spjanzen static void
cmov(int x,int y)2304a5fbbc4Spjanzen cmov(int x, int y)
231df930be7Sderaadt {
232df930be7Sderaadt 	xputs(tgoto(CM, x-1, y-1));
233df930be7Sderaadt 	cury = y;
234df930be7Sderaadt 	curx = x;
235df930be7Sderaadt }
236df930be7Sderaadt 
2374a5fbbc4Spjanzen static int
xputc(int c)2384a5fbbc4Spjanzen xputc(int c)
2394a5fbbc4Spjanzen {
2404a5fbbc4Spjanzen 	return fputc(c, stdout);
241df930be7Sderaadt }
242df930be7Sderaadt 
2434a5fbbc4Spjanzen static void
xputs(char * s)2444a5fbbc4Spjanzen xputs(char *s)
2454a5fbbc4Spjanzen {
246df930be7Sderaadt 	tputs(s, 1, xputc);
247df930be7Sderaadt }
248df930be7Sderaadt 
2494a5fbbc4Spjanzen void
cl_end(void)250*aed906e4Smestre cl_end(void)
2514a5fbbc4Spjanzen {
252df930be7Sderaadt 	if(CE)
253df930be7Sderaadt 		xputs(CE);
254df930be7Sderaadt 	else {	/* no-CE fix - free after Harold Rynes */
255df930be7Sderaadt 		/* this looks terrible, especially on a slow terminal
256df930be7Sderaadt 		   but is better than nothing */
2574a5fbbc4Spjanzen 		int cx = curx, cy = cury;
258df930be7Sderaadt 
259df930be7Sderaadt 		while(curx < COLNO) {
260df930be7Sderaadt 			xputc(' ');
261df930be7Sderaadt 			curx++;
262df930be7Sderaadt 		}
263df930be7Sderaadt 		curs(cx, cy);
264df930be7Sderaadt 	}
265df930be7Sderaadt }
266df930be7Sderaadt 
2674a5fbbc4Spjanzen void
clr_screen(void)268*aed906e4Smestre clr_screen(void)
2694a5fbbc4Spjanzen {
270df930be7Sderaadt 	xputs(CL);
271df930be7Sderaadt 	curx = cury = 1;
272df930be7Sderaadt }
273df930be7Sderaadt 
2744a5fbbc4Spjanzen void
home(void)275*aed906e4Smestre home(void)
276df930be7Sderaadt {
277df930be7Sderaadt 	if(HO)
278df930be7Sderaadt 		xputs(HO);
279df930be7Sderaadt 	else if(CM)
280df930be7Sderaadt 		xputs(tgoto(CM, 0, 0));
281df930be7Sderaadt 	else
282df930be7Sderaadt 		curs(1, 1);	/* using UP ... */
283df930be7Sderaadt 	curx = cury = 1;
284df930be7Sderaadt }
285df930be7Sderaadt 
2864a5fbbc4Spjanzen void
standoutbeg(void)287*aed906e4Smestre standoutbeg(void)
288df930be7Sderaadt {
289df930be7Sderaadt 	if(SO) xputs(SO);
290df930be7Sderaadt }
291df930be7Sderaadt 
2924a5fbbc4Spjanzen void
standoutend(void)293*aed906e4Smestre standoutend(void)
294df930be7Sderaadt {
295df930be7Sderaadt 	if(SE) xputs(SE);
296df930be7Sderaadt }
297df930be7Sderaadt 
2984a5fbbc4Spjanzen void
backsp(void)299*aed906e4Smestre backsp(void)
300df930be7Sderaadt {
301df930be7Sderaadt 	xputs(BC);
302df930be7Sderaadt 	curx--;
303df930be7Sderaadt }
304df930be7Sderaadt 
3054a5fbbc4Spjanzen void
hackbell(void)306*aed906e4Smestre hackbell(void)
307df930be7Sderaadt {
308df930be7Sderaadt 	(void) putchar('\007');		/* curx does not change */
309df930be7Sderaadt 	(void) fflush(stdout);
310df930be7Sderaadt }
311df930be7Sderaadt 
312*aed906e4Smestre /* free after Robert Viduya
313*aed906e4Smestre  * must only be called with curx = 1
314*aed906e4Smestre  */
3154a5fbbc4Spjanzen void
cl_eos(void)316*aed906e4Smestre cl_eos(void)
317*aed906e4Smestre {
318df930be7Sderaadt 
319df930be7Sderaadt 	if(CD)
320df930be7Sderaadt 		xputs(CD);
321df930be7Sderaadt 	else {
3224a5fbbc4Spjanzen 		int cx = curx, cy = cury;
323df930be7Sderaadt 		while(cury <= LI-2) {
324df930be7Sderaadt 			cl_end();
325df930be7Sderaadt 			xputc('\n');
326df930be7Sderaadt 			curx = 1;
327df930be7Sderaadt 			cury++;
328df930be7Sderaadt 		}
329df930be7Sderaadt 		cl_end();
330df930be7Sderaadt 		curs(cx, cy);
331df930be7Sderaadt 	}
332df930be7Sderaadt }
333