xref: /netbsd-src/games/hack/hack.terminfo.c (revision 1182a44c59cae4d586117d55eca24b4b8b173211)
1*1182a44cSrillig /*	$NetBSD: hack.terminfo.c,v 1.3 2021/05/02 12:50:44 rillig Exp $	*/
298eb8895Sroy 
398eb8895Sroy /*
498eb8895Sroy  * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
598eb8895Sroy  * Amsterdam
698eb8895Sroy  * All rights reserved.
798eb8895Sroy  *
898eb8895Sroy  * Redistribution and use in source and binary forms, with or without
998eb8895Sroy  * modification, are permitted provided that the following conditions are
1098eb8895Sroy  * met:
1198eb8895Sroy  *
1298eb8895Sroy  * - Redistributions of source code must retain the above copyright notice,
1398eb8895Sroy  * this list of conditions and the following disclaimer.
1498eb8895Sroy  *
1598eb8895Sroy  * - Redistributions in binary form must reproduce the above copyright
1698eb8895Sroy  * notice, this list of conditions and the following disclaimer in the
1798eb8895Sroy  * documentation and/or other materials provided with the distribution.
1898eb8895Sroy  *
1998eb8895Sroy  * - Neither the name of the Stichting Centrum voor Wiskunde en
2098eb8895Sroy  * Informatica, nor the names of its contributors may be used to endorse or
2198eb8895Sroy  * promote products derived from this software without specific prior
2298eb8895Sroy  * written permission.
2398eb8895Sroy  *
2498eb8895Sroy  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
2598eb8895Sroy  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2698eb8895Sroy  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
2798eb8895Sroy  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
2898eb8895Sroy  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2998eb8895Sroy  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
3098eb8895Sroy  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
3198eb8895Sroy  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
3298eb8895Sroy  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
3398eb8895Sroy  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3498eb8895Sroy  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3598eb8895Sroy  */
3698eb8895Sroy 
3798eb8895Sroy /*
3898eb8895Sroy  * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
3998eb8895Sroy  * All rights reserved.
4098eb8895Sroy  *
4198eb8895Sroy  * Redistribution and use in source and binary forms, with or without
4298eb8895Sroy  * modification, are permitted provided that the following conditions
4398eb8895Sroy  * are met:
4498eb8895Sroy  * 1. Redistributions of source code must retain the above copyright
4598eb8895Sroy  *    notice, this list of conditions and the following disclaimer.
4698eb8895Sroy  * 2. Redistributions in binary form must reproduce the above copyright
4798eb8895Sroy  *    notice, this list of conditions and the following disclaimer in the
4898eb8895Sroy  *    documentation and/or other materials provided with the distribution.
4998eb8895Sroy  * 3. The name of the author may not be used to endorse or promote products
5098eb8895Sroy  *    derived from this software without specific prior written permission.
5198eb8895Sroy  *
5298eb8895Sroy  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
5398eb8895Sroy  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
5498eb8895Sroy  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
5598eb8895Sroy  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
5698eb8895Sroy  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
5798eb8895Sroy  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
5898eb8895Sroy  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
5998eb8895Sroy  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
6098eb8895Sroy  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
6198eb8895Sroy  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6298eb8895Sroy  */
6398eb8895Sroy 
6498eb8895Sroy #include <sys/cdefs.h>
6598eb8895Sroy #ifndef lint
66*1182a44cSrillig __RCSID("$NetBSD: hack.terminfo.c,v 1.3 2021/05/02 12:50:44 rillig Exp $");
6798eb8895Sroy #endif				/* not lint */
6898eb8895Sroy 
6998eb8895Sroy #include <string.h>
7098eb8895Sroy #include <termios.h>
7198eb8895Sroy #include <term.h>
7298eb8895Sroy #include <stdlib.h>
7398eb8895Sroy #include <unistd.h>
7498eb8895Sroy #include "hack.h"
7598eb8895Sroy #include "extern.h"
7698eb8895Sroy #include "def.flag.h"		/* for flags.nonull */
7798eb8895Sroy 
7898eb8895Sroy char           *CD;		/* tested in pri.c: docorner() */
7998eb8895Sroy int             CO, LI;		/* used in pri.c and whatis.c */
8098eb8895Sroy 
8198eb8895Sroy void
startup(void)8298eb8895Sroy startup(void)
8398eb8895Sroy {
8498eb8895Sroy 
8598eb8895Sroy 	/* Will exit if no suitable term found */
8698eb8895Sroy 	setupterm(NULL, 0, NULL);
8798eb8895Sroy 	CO = columns;
8898eb8895Sroy 	LI = lines;
8998eb8895Sroy 	if (CO < COLNO || LI < ROWNO + 2)
9098eb8895Sroy 		setclipped();
9198eb8895Sroy 	if (clear_screen == NULL)
9298eb8895Sroy 		error("Hack needs clear_screen.");
9398eb8895Sroy 	if (over_strike)
9498eb8895Sroy 		error("Hack can't have over_strike.");
9598eb8895Sroy 	if (cursor_address == NULL) {
9698eb8895Sroy 		printf("Playing hack without cursor_address is suspect...");
9798eb8895Sroy 		getret();
9898eb8895Sroy 	}
9998eb8895Sroy 	set_whole_screen();
10098eb8895Sroy }
10198eb8895Sroy 
10298eb8895Sroy void
startscreen(void)10398eb8895Sroy startscreen(void)
10498eb8895Sroy {
10598eb8895Sroy }
10698eb8895Sroy 
10798eb8895Sroy void
endscreen(void)10898eb8895Sroy endscreen(void)
10998eb8895Sroy {
11098eb8895Sroy }
11198eb8895Sroy 
11298eb8895Sroy static int
xputc(int c)11398eb8895Sroy xputc(int c)
11498eb8895Sroy {
11598eb8895Sroy 	return (fputc(c, stdout));
11698eb8895Sroy }
11798eb8895Sroy 
11898eb8895Sroy static void
xputs(const char * s)11998eb8895Sroy xputs(const char *s)
12098eb8895Sroy {
12198eb8895Sroy 	tputs(s, 1, xputc);
12298eb8895Sroy }
12398eb8895Sroy 
12498eb8895Sroy static void
cmov(int x,int y)12598eb8895Sroy cmov(int x, int y)
12698eb8895Sroy {
12798eb8895Sroy 	char *p;
12898eb8895Sroy 
1294060cbcdSroy 	p = tiparm(cursor_address, y - 1, x - 1);
13098eb8895Sroy 	if (p) {
13198eb8895Sroy 		xputs(p);
13298eb8895Sroy 		cury = y;
13398eb8895Sroy 		curx = x;
13498eb8895Sroy 	}
13598eb8895Sroy }
13698eb8895Sroy 
13798eb8895Sroy static void
nocmov(int x,int y)13898eb8895Sroy nocmov(int x, int y)
13998eb8895Sroy {
14098eb8895Sroy 	if (cury > y) {
14198eb8895Sroy 		if (cursor_up) {
14298eb8895Sroy 			while (cury > y) {	/* Go up. */
14398eb8895Sroy 				xputs(cursor_up);
14498eb8895Sroy 				cury--;
14598eb8895Sroy 			}
14698eb8895Sroy 		} else if (cursor_address) {
14798eb8895Sroy 			cmov(x, y);
14898eb8895Sroy 		} else if (cursor_home) {
14998eb8895Sroy 			home();
15098eb8895Sroy 			curs(x, y);
15198eb8895Sroy 		}		/* else impossible("..."); */
15298eb8895Sroy 	} else if (cury < y) {
15398eb8895Sroy 		if (cursor_address) {
15498eb8895Sroy 			cmov(x, y);
15598eb8895Sroy #if 0
15698eb8895Sroy 		} else if (XD) {
15798eb8895Sroy 			while (cury < y) {
15898eb8895Sroy 				xputs(XD);
15998eb8895Sroy 				cury++;
16098eb8895Sroy 			}
16198eb8895Sroy #endif
16298eb8895Sroy 		} else {
16398eb8895Sroy 			while (cury < y) {
16498eb8895Sroy 				xputc('\n');
16598eb8895Sroy 				curx = 1;
16698eb8895Sroy 				cury++;
16798eb8895Sroy 			}
16898eb8895Sroy 		}
16998eb8895Sroy 	}
17098eb8895Sroy 	if (curx < x) {		/* Go to the right. */
17198eb8895Sroy 		if (!cursor_right)
17298eb8895Sroy 			cmov(x, y);
17398eb8895Sroy 		else		/* bah */
17498eb8895Sroy 			/* should instead print what is there already */
17598eb8895Sroy 			while (curx < x) {
17698eb8895Sroy 				xputs(cursor_right);
17798eb8895Sroy 				curx++;
17898eb8895Sroy 			}
17998eb8895Sroy 	} else if (curx > x) {
18098eb8895Sroy 		while (curx > x)
18198eb8895Sroy 			backsp();
18298eb8895Sroy 	}
18398eb8895Sroy }
18498eb8895Sroy 
18598eb8895Sroy /*
18698eb8895Sroy  * Cursor movements
18798eb8895Sroy  *
18898eb8895Sroy  * x,y not xchar: perhaps xchar is unsigned and
18998eb8895Sroy  * curx-x would be unsigned as well
19098eb8895Sroy  */
19198eb8895Sroy void
curs(int x,int y)19298eb8895Sroy curs(int x, int y)
19398eb8895Sroy {
19498eb8895Sroy 
19598eb8895Sroy 	if (y == cury && x == curx)
19698eb8895Sroy 		return;
19798eb8895Sroy 	if (!cursor_right && (curx != x || x <= 3)) { /* Extremely primitive */
19898eb8895Sroy 		cmov(x, y);	/* bunker!wtm */
19998eb8895Sroy 		return;
20098eb8895Sroy 	}
20198eb8895Sroy 	if (abs(cury - y) <= 3 && abs(curx - x) <= 3)
20298eb8895Sroy 		nocmov(x, y);
20398eb8895Sroy 	else if ((x <= 3 && abs(cury - y) <= 3) ||
20498eb8895Sroy 	    (!cursor_address && x < abs(curx - x)))
20598eb8895Sroy 	{
20698eb8895Sroy 		(void) putchar('\r');
20798eb8895Sroy 		curx = 1;
20898eb8895Sroy 		nocmov(x, y);
20998eb8895Sroy 	} else if (!cursor_address) {
21098eb8895Sroy 		nocmov(x, y);
21198eb8895Sroy 	} else
21298eb8895Sroy 		cmov(x, y);
21398eb8895Sroy }
21498eb8895Sroy 
21598eb8895Sroy void
cl_end(void)21698eb8895Sroy cl_end(void)
21798eb8895Sroy {
21898eb8895Sroy 	if (clr_eol)
21998eb8895Sroy 		xputs(clr_eol);
22098eb8895Sroy 	else {			/* no-CE fix - free after Harold Rynes */
22198eb8895Sroy 		/*
22298eb8895Sroy 		 * this looks terrible, especially on a slow terminal but is
22398eb8895Sroy 		 * better than nothing
22498eb8895Sroy 		 */
22598eb8895Sroy 		int cx = curx, cy = cury;
22698eb8895Sroy 
22798eb8895Sroy 		while (curx < COLNO) {
22898eb8895Sroy 			xputc(' ');
22998eb8895Sroy 			curx++;
23098eb8895Sroy 		}
23198eb8895Sroy 		curs(cx, cy);
23298eb8895Sroy 	}
23398eb8895Sroy }
23498eb8895Sroy 
23598eb8895Sroy void
clearscreen(void)23698eb8895Sroy clearscreen(void)
23798eb8895Sroy {
23898eb8895Sroy 	xputs(clear_screen);
23998eb8895Sroy 	curx = cury = 1;
24098eb8895Sroy }
24198eb8895Sroy 
24298eb8895Sroy void
home(void)24398eb8895Sroy home(void)
24498eb8895Sroy {
24598eb8895Sroy 	char *out;
24698eb8895Sroy 
24798eb8895Sroy 	if (cursor_home)
24898eb8895Sroy 		xputs(cursor_home);
2494060cbcdSroy 	else if ((cursor_address) && (out = tiparm(cursor_address, 0, 0)))
25098eb8895Sroy 		xputs(out);
25198eb8895Sroy 	else
25298eb8895Sroy 		curs(1, 1);	/* using UP ... */
25398eb8895Sroy 	curx = cury = 1;
25498eb8895Sroy }
25598eb8895Sroy 
25698eb8895Sroy void
standoutbeg(void)25798eb8895Sroy standoutbeg(void)
25898eb8895Sroy {
25998eb8895Sroy 	if (enter_standout_mode && exit_standout_mode && !magic_cookie_glitch)
26098eb8895Sroy 		xputs(enter_standout_mode);
26198eb8895Sroy }
26298eb8895Sroy 
26398eb8895Sroy void
standoutend(void)26498eb8895Sroy standoutend(void)
26598eb8895Sroy {
26698eb8895Sroy 	if (exit_standout_mode && enter_standout_mode && !magic_cookie_glitch)
26798eb8895Sroy 		xputs(exit_standout_mode);
26898eb8895Sroy }
26998eb8895Sroy 
27098eb8895Sroy void
backsp(void)27198eb8895Sroy backsp(void)
27298eb8895Sroy {
27398eb8895Sroy 	if (cursor_left)
27498eb8895Sroy 		xputs(cursor_left);
27598eb8895Sroy 	else
27698eb8895Sroy 		(void) putchar('\b');
27798eb8895Sroy 	curx--;
27898eb8895Sroy }
27998eb8895Sroy 
28098eb8895Sroy void
sound_bell(void)28198eb8895Sroy sound_bell(void)
28298eb8895Sroy {
28398eb8895Sroy 	(void) putchar('\007');	/* curx does not change */
28498eb8895Sroy 	(void) fflush(stdout);
28598eb8895Sroy }
28698eb8895Sroy 
28798eb8895Sroy void
delay_output(void)28898eb8895Sroy delay_output(void)
28998eb8895Sroy {
29098eb8895Sroy 
29198eb8895Sroy 	/* delay 50 ms - could also use a 'nap'-system call */
29298eb8895Sroy 	  /* or the usleep call like this :-) */
29398eb8895Sroy 	usleep(50000);
29498eb8895Sroy }
29598eb8895Sroy 
29698eb8895Sroy void
cl_eos(void)29798eb8895Sroy cl_eos(void)
29898eb8895Sroy {				/* free after Robert Viduya *//* must only be
29998eb8895Sroy 				 * called with curx = 1 */
30098eb8895Sroy 
30198eb8895Sroy 	if (clr_eos)
30298eb8895Sroy 		xputs(clr_eos);
30398eb8895Sroy 	else {
30498eb8895Sroy 		int             cx = curx, cy = cury;
30598eb8895Sroy 		while (cury <= LI - 2) {
30698eb8895Sroy 			cl_end();
30798eb8895Sroy 			xputc('\n');
30898eb8895Sroy 			curx = 1;
30998eb8895Sroy 			cury++;
31098eb8895Sroy 		}
31198eb8895Sroy 		cl_end();
31298eb8895Sroy 		curs(cx, cy);
31398eb8895Sroy 	}
31498eb8895Sroy }
315