xref: /csrg-svn/games/snake/snake/move.c (revision 63913)
121257Sdist /*
2*63913Sbostic  * Copyright (c) 1980, 1993
3*63913Sbostic  *	The Regents of the University of California.  All rights reserved.
433692Sbostic  *
542594Sbostic  * %sccs.include.redist.c%
621257Sdist  */
721257Sdist 
813775Ssam #ifndef lint
9*63913Sbostic static char sccsid[] = "@(#)move.c	8.1 (Berkeley) 07/19/93";
1033692Sbostic #endif /* not lint */
1113775Ssam 
1213775Ssam /*************************************************************************
1313775Ssam  *
1413775Ssam  *	MOVE LIBRARY
1513775Ssam  *
1613775Ssam  *	This set of subroutines moves a cursor to a predefined
1713775Ssam  *	location, independent of the terminal type.  If the
1813775Ssam  *	terminal has an addressable cursor, it uses it.  If
1913775Ssam  *	not, it optimizes for tabs (currently) even if you don't
2013775Ssam  *      have them.
2113775Ssam  *
2213775Ssam  *	At all times the current address of the cursor must be maintained,
2313775Ssam  *	and that is available as structure cursor.
2413775Ssam  *
2513775Ssam  *	The following calls are allowed:
2613775Ssam  *		move(sp)	move to point sp.
2713775Ssam  *		up()		move up one line.
2813775Ssam  *		down()		move down one line.
2913775Ssam  *		bs()		move left one space (except column 0).
3013775Ssam  *		nd()		move right one space(no write).
3113775Ssam  *		clear()		clear screen.
3213775Ssam  *		home()		home.
3313775Ssam  *		ll()		move to lower left corner of screen.
3413775Ssam  *		cr()		carriage return (no line feed).
3546760Sbostic  *		pr()		just like standard printf, but keeps track
3613775Ssam  *				of cursor position. (Uses pstring).
3746760Sbostic  *		apr()		same as printf, but first argument is &point.
3813775Ssam  *				(Uses pstring).
3913775Ssam  *		pstring(s)	output the string of printing characters.
4013775Ssam  *				However, '\r' is interpreted to mean return
4113775Ssam  *				to column of origination AND do linefeed.
4213775Ssam  *				'\n' causes <cr><lf>.
4313775Ssam  *		putpad(str)	calls tputs to output character with proper
4413775Ssam  *					padding.
4513775Ssam  *		outch()		the output routine for a character used by
4613775Ssam  *					tputs. It just calls putchar.
4713775Ssam  *		pch(ch)		output character to screen and update
4813775Ssam  *					cursor address (must be a standard
4913775Ssam  *					printing character). WILL SCROLL.
5013775Ssam  *		pchar(ps,ch)	prints one character if it is on the
5113775Ssam  *					screen at the specified location;
5213775Ssam  *					otherwise, dumps it.(no wrap-around).
5313775Ssam  *
5413775Ssam  *		getcap()	initializes strings for later calls.
5513775Ssam  *		cap(string)	outputs the string designated in the termcap
5613775Ssam  *					data base. (Should not move the cursor.)
5734027Sbostic  *		done()		returns the terminal to intial state and exits.
5813775Ssam  *
5913775Ssam  *		point(&p,x,y)	return point set to x,y.
6013775Ssam  *
6113775Ssam  *		baudrate(x)	returns the baudrate of the terminal.
6213775Ssam  *		delay(t)	causes an approximately constant delay
6313775Ssam  *					independent of baudrate.
6413775Ssam  *					Duration is ~ t/20 seconds.
6513775Ssam  *
6613775Ssam  ******************************************************************************/
6713775Ssam 
6852541Storek #if __STDC__
6946760Sbostic #include <stdarg.h>
7052541Storek #else
7152541Storek #include <varargs.h>
7252541Storek #endif
7313775Ssam #include "snake.h"
7413775Ssam 
7513775Ssam int CMlength;
7613775Ssam int NDlength;
7713775Ssam int BSlength;
7813775Ssam int delaystr[10];
7913775Ssam short ospeed;
8013775Ssam 
8113775Ssam static char str[80];
8213775Ssam 
8313775Ssam move(sp)
8413775Ssam struct point *sp;
8513775Ssam {
8613775Ssam 	int distance;
8713775Ssam 	int tabcol,ct;
8813775Ssam 	struct point z;
8913775Ssam 
9013775Ssam 	if (sp->line <0 || sp->col <0 || sp->col > COLUMNS){
9146760Sbostic 		pr("move to [%d,%d]?",sp->line,sp->col);
9213775Ssam 		return;
9313775Ssam 	}
9413775Ssam 	if (sp->line >= LINES){
9513775Ssam 		move(point(&z,sp->col,LINES-1));
9613775Ssam 		while(sp->line-- >= LINES)putchar('\n');
9713775Ssam 		return;
9813775Ssam 	}
9913775Ssam 
10013775Ssam 	if (CM != 0) {
10113775Ssam 		char *cmstr = tgoto(CM, sp->col, sp->line);
10213775Ssam 
10313775Ssam 		CMlength = strlen(cmstr);
10413775Ssam 		if(cursor.line == sp->line){
10513775Ssam 			distance = sp->col - cursor.col;
10613775Ssam 			if(distance == 0)return;	/* Already there! */
10713775Ssam 			if(distance > 0){	/* Moving to the right */
10813775Ssam 				if(distance*NDlength < CMlength){
10913775Ssam 					right(sp);
11013775Ssam 					return;
11113775Ssam 				}
11213775Ssam 				if(TA){
11313775Ssam 					ct=sp->col&7;
11413775Ssam 					tabcol=(cursor.col|7)+1;
11513775Ssam 					do{
11613775Ssam 						ct++;
11713775Ssam 						tabcol=(tabcol|7)+1;
11813775Ssam 					}
11913775Ssam 					while(tabcol<sp->col);
12013775Ssam 					if(ct<CMlength){
12113775Ssam 						right(sp);
12213775Ssam 						return;
12313775Ssam 					}
12413775Ssam 				}
12513775Ssam 			} else {		/* Moving to the left */
12613775Ssam 				if (-distance*BSlength < CMlength){
12713775Ssam 					gto(sp);
12813775Ssam 					return;
12913775Ssam 				}
13013775Ssam 			}
13113775Ssam 			if(sp->col < CMlength){
13213775Ssam 				cr();
13313775Ssam 				right(sp);
13413775Ssam 				return;
13513775Ssam 			}
13613775Ssam 				/* No more optimizations on same row. */
13713775Ssam 		}
13813775Ssam 		distance = sp->col - cursor.col;
13913775Ssam 		distance = distance > 0 ?
14013775Ssam 			distance*NDlength : -distance * BSlength;
14146760Sbostic 		if (distance < 0)
14246760Sbostic 			pr("ERROR: distance is negative: %d",distance);
14313775Ssam 		distance += abs(sp->line - cursor.line);
14413775Ssam 		if(distance >= CMlength){
14513775Ssam 			putpad(cmstr);
14613775Ssam 			cursor.line = sp->line;
14713775Ssam 			cursor.col = sp->col;
14813775Ssam 			return;
14913775Ssam 		}
15013775Ssam 	}
15113775Ssam 
15213775Ssam 	/*
15313775Ssam 	 * If we get here we have a terminal that can't cursor
15413775Ssam 	 * address but has local motions or one which can cursor
15513775Ssam 	 * address but can get there quicker with local motions.
15613775Ssam 	 */
15713775Ssam 	 gto(sp);
15813775Ssam }
15913775Ssam gto(sp)
16013775Ssam struct point *sp;
16113775Ssam {
16213775Ssam 
16313775Ssam 	int distance,f,tfield,j;
16413775Ssam 
16513775Ssam 	if (cursor.line > LINES || cursor.line <0 ||
16613775Ssam 	    cursor.col <0 || cursor.col > COLUMNS)
16746760Sbostic 		pr("ERROR: cursor is at %d,%d\n",
16813775Ssam 			cursor.line,cursor.col);
16913775Ssam 	if (sp->line > LINES || sp->line <0 ||
17013775Ssam 	    sp->col <0 || sp->col >  COLUMNS)
17146760Sbostic 		pr("ERROR: target is %d,%d\n",sp->line,sp->col);
17213775Ssam 	tfield = (sp->col) >> 3;
17313775Ssam 	if (sp->line == cursor.line){
17413775Ssam 		if (sp->col > cursor.col)right(sp);
17513775Ssam 		else{
17613775Ssam 			distance = (cursor.col -sp->col)*BSlength;
17713775Ssam 			if (((TA) &&
17813775Ssam 			     (distance > tfield+((sp->col)&7)*NDlength)
17913775Ssam 			    ) ||
18013775Ssam 			    (((cursor.col)*NDlength) < distance)
18113775Ssam 			   ){
18213775Ssam 				cr();
18313775Ssam 				right(sp);
18413775Ssam 			}
18513775Ssam 			else{
18613775Ssam 				while(cursor.col > sp->col) bs();
18713775Ssam 			}
18813775Ssam 		}
18913775Ssam 		return;
19013775Ssam 	}
19113775Ssam 				/*must change row */
19213775Ssam 	if (cursor.col - sp->col > (cursor.col >> 3)){
19313775Ssam 		if (cursor.col == 0)f = 0;
19413775Ssam 		else f = -1;
19513775Ssam 	}
19613775Ssam 	else f = cursor.col >> 3;
19713775Ssam 	if (((sp->line << 1) + 1 < cursor.line - f) && (HO != 0)){
19813775Ssam 			/*
19913775Ssam 			 * home quicker than rlf:
20013775Ssam 			 * (sp->line + f > cursor.line - sp->line)
20113775Ssam 			 */
20213775Ssam 		putpad(HO);
20313775Ssam 		cursor.col = cursor.line = 0;
20413775Ssam 		gto(sp);
20513775Ssam 		return;
20613775Ssam 	}
20713775Ssam 	if (((sp->line << 1) > cursor.line + LINES+1 + f) && (LL != 0)){
20813775Ssam 		/* home,rlf quicker than lf
20913775Ssam 		 * (LINES+1 - sp->line + f < sp->line - cursor.line)
21013775Ssam 		 */
21113775Ssam 		if (cursor.line > f + 1){
21213775Ssam 		/* is home faster than wraparound lf?
21313775Ssam 		 * (cursor.line + 20 - sp->line > 21 - sp->line + f)
21413775Ssam 		 */
21513775Ssam 			ll();
21613775Ssam 			gto(sp);
21713775Ssam 			return;
21813775Ssam 		}
21913775Ssam 	}
22013775Ssam 	if ((LL != 0) && (sp->line > cursor.line + (LINES >> 1) - 1))
22113775Ssam 		cursor.line += LINES;
22213775Ssam 	while(sp->line > cursor.line)down();
22313775Ssam 	while(sp->line < cursor.line)up();
22413775Ssam 	gto(sp);		/*can recurse since cursor.line = sp->line */
22513775Ssam }
22613775Ssam 
22713775Ssam right(sp)
22813775Ssam struct point *sp;
22913775Ssam {
23013775Ssam 	int field,tfield;
23113775Ssam 	int tabcol,strlength;
23213775Ssam 
23313775Ssam 	if (sp->col < cursor.col)
23446760Sbostic 		pr("ERROR:right() can't move left\n");
23513775Ssam 	if(TA){		/* If No Tabs: can't send tabs because ttydrive
23613775Ssam 			 * loses count with control characters.
23713775Ssam 			 */
23813775Ssam 		field = cursor.col >> 3;
23913775Ssam /*
24013775Ssam  *	This code is useful for a terminal which wraps around on backspaces.
24113775Ssam  *	(Mine does.)  Unfortunately, this is not specified in termcap, and
24213775Ssam  *	most terminals don't work that way.  (Of course, most terminals
24313775Ssam  *	have addressible cursors, too).
24413775Ssam  */
24513775Ssam 		if (BW && (CM == 0) &&
24613775Ssam 		    ((sp->col << 1) - field > (COLUMNS - 8) << 1 )
24713775Ssam 		   ){
24813775Ssam 	 		if (cursor.line == 0){
24913775Ssam 	 			outch('\n');
25013775Ssam 	 		}
25113775Ssam 	 		outch('\r');
25213775Ssam 	 		cursor.col = COLUMNS + 1;
25313775Ssam 	 		while(cursor.col > sp->col)bs();
25413775Ssam 	 		if (cursor.line != 0) outch('\n');
25513775Ssam 	 		return;
25613775Ssam 	 	}
25713775Ssam 
25813775Ssam 		tfield = sp->col >> 3;
25913775Ssam 
26013775Ssam 		while (field < tfield){
26113775Ssam 			putpad(TA);
26213775Ssam 			cursor.col = ++field << 3;
26313775Ssam 		}
26413775Ssam 		tabcol = (cursor.col|7) + 1;
26513775Ssam 		strlength = (tabcol - sp->col)*BSlength + 1;
26613775Ssam 		/* length of sequence to overshoot */
26713775Ssam 		if (((sp->col - cursor.col)*NDlength > strlength) &&
26813775Ssam 		    (tabcol < COLUMNS)
26913775Ssam 		   ){
27013775Ssam 			/*
27113775Ssam 			 * Tab past and backup
27213775Ssam 			 */
27313775Ssam 			putpad(TA);
27413775Ssam 			cursor.col = (cursor.col | 7) + 1;
27513775Ssam 			while(cursor.col > sp->col)bs();
27613775Ssam 		}
27713775Ssam 	}
27813775Ssam 	while (sp->col > cursor.col){
27913775Ssam 		nd();
28013775Ssam 	}
28113775Ssam }
28213775Ssam 
cr()28313775Ssam cr(){
28413775Ssam 	outch('\r');
28513775Ssam 	cursor.col = 0;
28613775Ssam }
28713775Ssam 
clear()28813775Ssam clear(){
28913775Ssam 	int i;
29013775Ssam 
29113775Ssam 	if (CL){
29213775Ssam 		putpad(CL);
29313775Ssam 		cursor.col=cursor.line=0;
29413775Ssam 	} else {
29513775Ssam 		for(i=0; i<LINES; i++) {
29613775Ssam 			putchar('\n');
29713775Ssam 		}
29813775Ssam 		cursor.line = LINES - 1;
29913775Ssam 		home();
30013775Ssam 	}
30113775Ssam }
30213775Ssam 
home()30313775Ssam home(){
30413775Ssam 	struct point z;
30513775Ssam 
30613775Ssam 	if(HO != 0){
30713775Ssam 		putpad(HO);
30813775Ssam 		cursor.col = cursor.line = 0;
30913775Ssam 		return;
31013775Ssam 	}
31113775Ssam 	z.col = z.line = 0;
31213775Ssam 	move(&z);
31313775Ssam }
31413775Ssam 
ll()31513775Ssam ll(){
31613775Ssam 	int j,l;
31713775Ssam 	struct point z;
31813775Ssam 
31913775Ssam 	l = lcnt + 2;
32013775Ssam 	if(LL != NULL && LINES==l){
32113775Ssam 		putpad(LL);
32213775Ssam 		cursor.line = LINES-1;
32313775Ssam 		cursor.col = 0;
32413775Ssam 		return;
32513775Ssam 	}
32613775Ssam 	z.col = 0;
32713775Ssam 	z.line = l-1;
32813775Ssam 	move(&z);
32913775Ssam }
33013775Ssam 
up()33113775Ssam up(){
33213775Ssam 	putpad(UP);
33313775Ssam 	cursor.line--;
33413775Ssam }
33513775Ssam 
down()33613775Ssam down(){
33713775Ssam 	putpad(DO);
33813775Ssam 	cursor.line++;
33913775Ssam 	if (cursor.line >= LINES)cursor.line=LINES-1;
34013775Ssam }
bs()34113775Ssam bs(){
34213775Ssam 	if (cursor.col > 0){
34313775Ssam 		putpad(BS);
34413775Ssam 		cursor.col--;
34513775Ssam 	}
34613775Ssam }
34713775Ssam 
nd()34813775Ssam nd(){
34913775Ssam 	putpad(ND);
35013775Ssam 	cursor.col++;
35113775Ssam 	if (cursor.col == COLUMNS+1){
35213775Ssam 		cursor.line++;
35313775Ssam 		cursor.col = 0;
35413775Ssam 		if (cursor.line >= LINES)cursor.line=LINES-1;
35513775Ssam 	}
35613775Ssam }
35713775Ssam 
pch(c)35813775Ssam pch(c)
35913775Ssam {
36013775Ssam 	outch(c);
36113775Ssam 	if(++cursor.col >= COLUMNS && AM) {
36213775Ssam 		cursor.col = 0;
36313775Ssam 		++cursor.line;
36413775Ssam 	}
36513775Ssam }
36613775Ssam 
36757832Storek void
36852541Storek #if __STDC__
apr(struct point * ps,const char * fmt,...)36957832Storek apr(struct point *ps, const char *fmt, ...)
37052541Storek #else
37152541Storek apr(ps, fmt, va_alist)
37246760Sbostic 	struct point *ps;
37346760Sbostic 	char *fmt;
37452541Storek 	va_dcl
37552541Storek #endif
37613775Ssam {
37713775Ssam 	struct point p;
37846760Sbostic 	va_list ap;
37913775Ssam 
38013775Ssam 	p.line = ps->line+1; p.col = ps->col+1;
38113775Ssam 	move(&p);
38252541Storek #if __STDC__
38346760Sbostic 	va_start(ap, fmt);
38452541Storek #else
38552541Storek 	va_start(ap);
38652541Storek #endif
38746760Sbostic 	(void)vsprintf(str, fmt, ap);
38846760Sbostic 	va_end(ap);
38913775Ssam 	pstring(str);
39013775Ssam }
39113775Ssam 
39257832Storek void
39352541Storek #if __STDC__
pr(const char * fmt,...)39457832Storek pr(const char *fmt, ...)
39552541Storek #else
39652541Storek pr(fmt, va_alist)
39746760Sbostic 	char *fmt;
39852541Storek 	va_dcl
39952541Storek #endif
40013775Ssam {
40146760Sbostic 	va_list ap;
40246760Sbostic 
40352541Storek #if __STDC__
40446760Sbostic 	va_start(ap, fmt);
40552541Storek #else
40652541Storek 	va_start(ap);
40752541Storek #endif
40846760Sbostic 	(void)vsprintf(str, fmt, ap);
40946760Sbostic 	va_end(ap);
41013775Ssam 	pstring(str);
41113775Ssam }
41213775Ssam 
pstring(s)41313775Ssam pstring(s)
41413775Ssam char *s;{
41513775Ssam 	struct point z;
41613775Ssam 	int stcol;
41713775Ssam 
41813775Ssam 	stcol = cursor.col;
41913775Ssam 	while (s[0] != '\0'){
42013775Ssam 		switch (s[0]){
42113775Ssam 		case '\n':
42213775Ssam 			move(point(&z,0,cursor.line+1));
42313775Ssam 			break;
42413775Ssam 		case '\r':
42513775Ssam 			move(point(&z,stcol,cursor.line+1));
42613775Ssam 			break;
42713775Ssam 		case '\t':
42813775Ssam 			z.col = (((cursor.col + 8) >> 3) << 3);
42913775Ssam 			z.line = cursor.line;
43013775Ssam 			move(&z);
43113775Ssam 			break;
43213775Ssam 		case '\b':
43313775Ssam 			bs();
43413775Ssam 			break;
43533114Sbostic 		case CTRL('g'):
43633114Sbostic 			outch(CTRL('g'));
43713775Ssam 			break;
43813775Ssam 		default:
43913775Ssam 			if (s[0] < ' ')break;
44013775Ssam 			pch(s[0]);
44113775Ssam 		}
44213775Ssam 		s++;
44313775Ssam 	}
44413775Ssam }
44513775Ssam 
44613775Ssam pchar(ps,ch)
44713775Ssam struct point *ps;
44813775Ssam char ch;{
44913775Ssam 	struct point p;
45013775Ssam 	p.col = ps->col + 1; p.line = ps->line + 1;
45113775Ssam 	if (
45213775Ssam 		(p.col >= 0) &&
45313775Ssam 		(p.line >= 0) &&
45413775Ssam 		(
45513775Ssam 			(
45613775Ssam 				(p.line < LINES) &&
45713775Ssam 				(p.col < COLUMNS)
45813775Ssam 			) ||
45913775Ssam 			(
46013775Ssam 	    			(p.col == COLUMNS) &&
46113775Ssam 				(p.line < LINES-1)
46213775Ssam 			)
46313775Ssam 	  	)
46413775Ssam 	){
46513775Ssam 		move(&p);
46613775Ssam 		pch(ch);
46713775Ssam 	}
46813775Ssam }
46913775Ssam 
47013775Ssam 
outch(c)47113775Ssam outch(c)
47213775Ssam {
47313775Ssam 	putchar(c);
47413775Ssam }
47513775Ssam 
putpad(str)47613775Ssam putpad(str)
47713775Ssam char *str;
47813775Ssam {
47913775Ssam 	if (str)
48013775Ssam 		tputs(str, 1, outch);
48113775Ssam }
baudrate()48213775Ssam baudrate()
48313775Ssam {
48413775Ssam 
48513775Ssam 	switch (orig.sg_ospeed){
48613775Ssam 	case B300:
48713775Ssam 		return(300);
48813775Ssam 	case B1200:
48913775Ssam 		return(1200);
49013775Ssam 	case B4800:
49113775Ssam 		return(4800);
49213775Ssam 	case B9600:
49313775Ssam 		return(9600);
49413775Ssam 	default:
49513775Ssam 		return(0);
49613775Ssam 	}
49713775Ssam }
delay(t)49813775Ssam delay(t)
49913775Ssam int t;
50013775Ssam {
50113775Ssam 	int k,j;
50213775Ssam 
50313775Ssam 	k = baudrate() * t / 300;
50413775Ssam 	for(j=0;j<k;j++){
50513775Ssam 		putchar(PC);
50613775Ssam 	}
50713775Ssam }
50813775Ssam 
done()50913775Ssam done()
51013775Ssam {
51113775Ssam 	cook();
51213775Ssam 	exit(0);
51313775Ssam }
51413775Ssam 
cook()51513775Ssam cook()
51613775Ssam {
51713775Ssam 	delay(1);
51813775Ssam 	putpad(TE);
51913775Ssam 	putpad(KE);
52013775Ssam 	fflush(stdout);
52113775Ssam 	stty(0, &orig);
52213775Ssam #ifdef TIOCSLTC
52313775Ssam 	ioctl(0, TIOCSLTC, &olttyc);
52413775Ssam #endif
52513775Ssam }
52613775Ssam 
raw()52713775Ssam raw()
52813775Ssam {
52913775Ssam 	stty(0, &new);
53013775Ssam #ifdef TIOCSLTC
53113775Ssam 	ioctl(0, TIOCSLTC, &nlttyc);
53213775Ssam #endif
53313775Ssam }
53413775Ssam 
point(ps,x,y)53513775Ssam struct point *point(ps,x,y)
53613775Ssam struct point *ps;
53713775Ssam int x,y;
53813775Ssam {
53913775Ssam 	ps->col=x;
54013775Ssam 	ps->line=y;
54113775Ssam 	return(ps);
54213775Ssam }
54313775Ssam 
54413775Ssam char *ap;
54513775Ssam 
getcap()54613775Ssam getcap()
54713775Ssam {
54813775Ssam 	char *getenv();
54913775Ssam 	char *term;
55013775Ssam 	char *xPC;
55113775Ssam 	struct point z;
55246760Sbostic 	void stop();
55363912Sbostic #ifdef TIOCGWINSZ
55463912Sbostic 	struct winsize win;
55563912Sbostic #endif
55613775Ssam 
55713775Ssam 	term = getenv("TERM");
55813775Ssam 	if (term==0) {
55913775Ssam 		fprintf(stderr, "No TERM in environment\n");
56013775Ssam 		exit(1);
56113775Ssam 	}
56213775Ssam 
56313775Ssam 	switch (tgetent(tbuf, term)) {
56413775Ssam 	case -1:
56513775Ssam 		fprintf(stderr, "Cannot open termcap file\n");
56613775Ssam 		exit(2);
56713775Ssam 	case 0:
56813775Ssam 		fprintf(stderr, "%s: unknown terminal", term);
56913775Ssam 		exit(3);
57013775Ssam 	}
57113775Ssam 
57213775Ssam 	ap = tcapbuf;
57313775Ssam 
57463912Sbostic #ifdef TIOCGWINSZ
57563912Sbostic 	if (ioctl(0, TIOCGWINSZ, (char *) &win) < 0 ||
57663912Sbostic 	    (LINES = win.ws_row) == 0 || (COLUMNS = win.ws_col) == 0) {
57763912Sbostic #endif
57863912Sbostic 		LINES = tgetnum("li");
57963912Sbostic 		COLUMNS = tgetnum("co");
58063912Sbostic #ifdef TIOCGWINSZ
58163912Sbostic 	}
58263912Sbostic #endif
58334027Sbostic 	if (!lcnt)
58434027Sbostic 		lcnt = LINES - 2;
58534027Sbostic 	if (!ccnt)
58634027Sbostic 		ccnt = COLUMNS - 3;
58713775Ssam 
58813775Ssam 	AM = tgetflag("am");
58913775Ssam 	BW = tgetflag("bw");
59013775Ssam 
59113775Ssam 	ND = tgetstr("nd", &ap);
59213775Ssam 	UP = tgetstr("up", &ap);
59313775Ssam 
59413775Ssam 	DO = tgetstr("do", &ap);
59513775Ssam 	if (DO == 0)
59613775Ssam 		DO = "\n";
59713775Ssam 
59813775Ssam 	BS = tgetstr("bc", &ap);
59913775Ssam 	if (BS == 0 && tgetflag("bs"))
60013775Ssam 		BS = "\b";
60113775Ssam 	if (BS)
60213775Ssam 		xBC = *BS;
60313775Ssam 
60413775Ssam 	TA = tgetstr("ta", &ap);
60513775Ssam 	if (TA == 0 && tgetflag("pt"))
60613775Ssam 		TA = "\t";
60713775Ssam 
60813775Ssam 	HO = tgetstr("ho", &ap);
60913775Ssam 	CL = tgetstr("cl", &ap);
61013775Ssam 	CM = tgetstr("cm", &ap);
61113775Ssam 	LL = tgetstr("ll", &ap);
61213775Ssam 
61313775Ssam 	KL = tgetstr("kl", &ap);
61413775Ssam 	KR = tgetstr("kr", &ap);
61513775Ssam 	KU = tgetstr("ku", &ap);
61613775Ssam 	KD = tgetstr("kd", &ap);
61713775Ssam 	Klength = strlen(KL);
61813775Ssam 		/*	NOTE:   If KL, KR, KU, and KD are not
61913775Ssam 		 *		all the same length, some problems
62013775Ssam 		 *		may arise, since tests are made on
62113775Ssam 		 *		all of them together.
62213775Ssam 		 */
62313775Ssam 
62413775Ssam 	TI = tgetstr("ti", &ap);
62513775Ssam 	TE = tgetstr("te", &ap);
62613775Ssam 	KS = tgetstr("ks", &ap);
62713775Ssam 	KE = tgetstr("ke", &ap);
62813775Ssam 
62913775Ssam 	xPC = tgetstr("pc", &ap);
63013775Ssam 	if (xPC)
63113775Ssam 		PC = *xPC;
63213775Ssam 
63313775Ssam 	NDlength = strlen(ND);
63413775Ssam 	BSlength = strlen(BS);
63513775Ssam 	if ((CM == 0) &&
63613775Ssam 		(HO == 0 | UP==0 || BS==0 || ND==0)) {
63713775Ssam 		fprintf(stderr, "Terminal must have addressible ");
63813775Ssam 		fprintf(stderr, "cursor or home + 4 local motions\n");
63913775Ssam 		exit(5);
64013775Ssam 	}
64113775Ssam 	if (tgetflag("os")) {
64213775Ssam 		fprintf(stderr, "Terminal must not overstrike\n");
64313775Ssam 		exit(5);
64413775Ssam 	}
64513775Ssam 	if (LINES <= 0 || COLUMNS <= 0) {
64613775Ssam 		fprintf(stderr, "Must know the screen size\n");
64713775Ssam 		exit(5);
64813775Ssam 	}
64913775Ssam 
65013775Ssam 	gtty(0, &orig);
65113775Ssam 	new=orig;
65213775Ssam 	new.sg_flags &= ~(ECHO|CRMOD|ALLDELAY|XTABS);
65313775Ssam 	new.sg_flags |= CBREAK;
65413775Ssam 	signal(SIGINT,stop);
65513775Ssam 	ospeed = orig.sg_ospeed;
65613775Ssam #ifdef TIOCGLTC
65713775Ssam 	ioctl(0, TIOCGLTC, &olttyc);
65813775Ssam 	nlttyc = olttyc;
65913775Ssam 	nlttyc.t_suspc = '\377';
66013775Ssam 	nlttyc.t_dsuspc = '\377';
66113775Ssam #endif
66213775Ssam 	raw();
66313775Ssam 
66413775Ssam 	if ((orig.sg_flags & XTABS) == XTABS) TA=0;
66513775Ssam 	putpad(KS);
66613775Ssam 	putpad(TI);
66713775Ssam 	point(&cursor,0,LINES-1);
66813775Ssam }
669