xref: /csrg-svn/games/snake/snake/move.c (revision 46760)
121257Sdist /*
221257Sdist  * Copyright (c) 1980 Regents of the University of California.
333692Sbostic  * All rights reserved.
433692Sbostic  *
542594Sbostic  * %sccs.include.redist.c%
621257Sdist  */
721257Sdist 
813775Ssam #ifndef lint
9*46760Sbostic static char sccsid[] = "@(#)move.c	5.8 (Berkeley) 02/28/91";
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).
35*46760Sbostic  *		pr()		just like standard printf, but keeps track
3613775Ssam  *				of cursor position. (Uses pstring).
37*46760Sbostic  *		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 
68*46760Sbostic #include <stdarg.h>
6913775Ssam #include "snake.h"
7013775Ssam 
7113775Ssam int CMlength;
7213775Ssam int NDlength;
7313775Ssam int BSlength;
7413775Ssam int delaystr[10];
7513775Ssam short ospeed;
7613775Ssam 
7713775Ssam static char str[80];
7813775Ssam 
7913775Ssam move(sp)
8013775Ssam struct point *sp;
8113775Ssam {
8213775Ssam 	int distance;
8313775Ssam 	int tabcol,ct;
8413775Ssam 	struct point z;
8513775Ssam 
8613775Ssam 	if (sp->line <0 || sp->col <0 || sp->col > COLUMNS){
87*46760Sbostic 		pr("move to [%d,%d]?",sp->line,sp->col);
8813775Ssam 		return;
8913775Ssam 	}
9013775Ssam 	if (sp->line >= LINES){
9113775Ssam 		move(point(&z,sp->col,LINES-1));
9213775Ssam 		while(sp->line-- >= LINES)putchar('\n');
9313775Ssam 		return;
9413775Ssam 	}
9513775Ssam 
9613775Ssam 	if (CM != 0) {
9713775Ssam 		char *cmstr = tgoto(CM, sp->col, sp->line);
9813775Ssam 
9913775Ssam 		CMlength = strlen(cmstr);
10013775Ssam 		if(cursor.line == sp->line){
10113775Ssam 			distance = sp->col - cursor.col;
10213775Ssam 			if(distance == 0)return;	/* Already there! */
10313775Ssam 			if(distance > 0){	/* Moving to the right */
10413775Ssam 				if(distance*NDlength < CMlength){
10513775Ssam 					right(sp);
10613775Ssam 					return;
10713775Ssam 				}
10813775Ssam 				if(TA){
10913775Ssam 					ct=sp->col&7;
11013775Ssam 					tabcol=(cursor.col|7)+1;
11113775Ssam 					do{
11213775Ssam 						ct++;
11313775Ssam 						tabcol=(tabcol|7)+1;
11413775Ssam 					}
11513775Ssam 					while(tabcol<sp->col);
11613775Ssam 					if(ct<CMlength){
11713775Ssam 						right(sp);
11813775Ssam 						return;
11913775Ssam 					}
12013775Ssam 				}
12113775Ssam 			} else {		/* Moving to the left */
12213775Ssam 				if (-distance*BSlength < CMlength){
12313775Ssam 					gto(sp);
12413775Ssam 					return;
12513775Ssam 				}
12613775Ssam 			}
12713775Ssam 			if(sp->col < CMlength){
12813775Ssam 				cr();
12913775Ssam 				right(sp);
13013775Ssam 				return;
13113775Ssam 			}
13213775Ssam 				/* No more optimizations on same row. */
13313775Ssam 		}
13413775Ssam 		distance = sp->col - cursor.col;
13513775Ssam 		distance = distance > 0 ?
13613775Ssam 			distance*NDlength : -distance * BSlength;
137*46760Sbostic 		if (distance < 0)
138*46760Sbostic 			pr("ERROR: distance is negative: %d",distance);
13913775Ssam 		distance += abs(sp->line - cursor.line);
14013775Ssam 		if(distance >= CMlength){
14113775Ssam 			putpad(cmstr);
14213775Ssam 			cursor.line = sp->line;
14313775Ssam 			cursor.col = sp->col;
14413775Ssam 			return;
14513775Ssam 		}
14613775Ssam 	}
14713775Ssam 
14813775Ssam 	/*
14913775Ssam 	 * If we get here we have a terminal that can't cursor
15013775Ssam 	 * address but has local motions or one which can cursor
15113775Ssam 	 * address but can get there quicker with local motions.
15213775Ssam 	 */
15313775Ssam 	 gto(sp);
15413775Ssam }
15513775Ssam gto(sp)
15613775Ssam struct point *sp;
15713775Ssam {
15813775Ssam 
15913775Ssam 	int distance,f,tfield,j;
16013775Ssam 
16113775Ssam 	if (cursor.line > LINES || cursor.line <0 ||
16213775Ssam 	    cursor.col <0 || cursor.col > COLUMNS)
163*46760Sbostic 		pr("ERROR: cursor is at %d,%d\n",
16413775Ssam 			cursor.line,cursor.col);
16513775Ssam 	if (sp->line > LINES || sp->line <0 ||
16613775Ssam 	    sp->col <0 || sp->col >  COLUMNS)
167*46760Sbostic 		pr("ERROR: target is %d,%d\n",sp->line,sp->col);
16813775Ssam 	tfield = (sp->col) >> 3;
16913775Ssam 	if (sp->line == cursor.line){
17013775Ssam 		if (sp->col > cursor.col)right(sp);
17113775Ssam 		else{
17213775Ssam 			distance = (cursor.col -sp->col)*BSlength;
17313775Ssam 			if (((TA) &&
17413775Ssam 			     (distance > tfield+((sp->col)&7)*NDlength)
17513775Ssam 			    ) ||
17613775Ssam 			    (((cursor.col)*NDlength) < distance)
17713775Ssam 			   ){
17813775Ssam 				cr();
17913775Ssam 				right(sp);
18013775Ssam 			}
18113775Ssam 			else{
18213775Ssam 				while(cursor.col > sp->col) bs();
18313775Ssam 			}
18413775Ssam 		}
18513775Ssam 		return;
18613775Ssam 	}
18713775Ssam 				/*must change row */
18813775Ssam 	if (cursor.col - sp->col > (cursor.col >> 3)){
18913775Ssam 		if (cursor.col == 0)f = 0;
19013775Ssam 		else f = -1;
19113775Ssam 	}
19213775Ssam 	else f = cursor.col >> 3;
19313775Ssam 	if (((sp->line << 1) + 1 < cursor.line - f) && (HO != 0)){
19413775Ssam 			/*
19513775Ssam 			 * home quicker than rlf:
19613775Ssam 			 * (sp->line + f > cursor.line - sp->line)
19713775Ssam 			 */
19813775Ssam 		putpad(HO);
19913775Ssam 		cursor.col = cursor.line = 0;
20013775Ssam 		gto(sp);
20113775Ssam 		return;
20213775Ssam 	}
20313775Ssam 	if (((sp->line << 1) > cursor.line + LINES+1 + f) && (LL != 0)){
20413775Ssam 		/* home,rlf quicker than lf
20513775Ssam 		 * (LINES+1 - sp->line + f < sp->line - cursor.line)
20613775Ssam 		 */
20713775Ssam 		if (cursor.line > f + 1){
20813775Ssam 		/* is home faster than wraparound lf?
20913775Ssam 		 * (cursor.line + 20 - sp->line > 21 - sp->line + f)
21013775Ssam 		 */
21113775Ssam 			ll();
21213775Ssam 			gto(sp);
21313775Ssam 			return;
21413775Ssam 		}
21513775Ssam 	}
21613775Ssam 	if ((LL != 0) && (sp->line > cursor.line + (LINES >> 1) - 1))
21713775Ssam 		cursor.line += LINES;
21813775Ssam 	while(sp->line > cursor.line)down();
21913775Ssam 	while(sp->line < cursor.line)up();
22013775Ssam 	gto(sp);		/*can recurse since cursor.line = sp->line */
22113775Ssam }
22213775Ssam 
22313775Ssam right(sp)
22413775Ssam struct point *sp;
22513775Ssam {
22613775Ssam 	int field,tfield;
22713775Ssam 	int tabcol,strlength;
22813775Ssam 
22913775Ssam 	if (sp->col < cursor.col)
230*46760Sbostic 		pr("ERROR:right() can't move left\n");
23113775Ssam 	if(TA){		/* If No Tabs: can't send tabs because ttydrive
23213775Ssam 			 * loses count with control characters.
23313775Ssam 			 */
23413775Ssam 		field = cursor.col >> 3;
23513775Ssam /*
23613775Ssam  *	This code is useful for a terminal which wraps around on backspaces.
23713775Ssam  *	(Mine does.)  Unfortunately, this is not specified in termcap, and
23813775Ssam  *	most terminals don't work that way.  (Of course, most terminals
23913775Ssam  *	have addressible cursors, too).
24013775Ssam  */
24113775Ssam 		if (BW && (CM == 0) &&
24213775Ssam 		    ((sp->col << 1) - field > (COLUMNS - 8) << 1 )
24313775Ssam 		   ){
24413775Ssam 	 		if (cursor.line == 0){
24513775Ssam 	 			outch('\n');
24613775Ssam 	 		}
24713775Ssam 	 		outch('\r');
24813775Ssam 	 		cursor.col = COLUMNS + 1;
24913775Ssam 	 		while(cursor.col > sp->col)bs();
25013775Ssam 	 		if (cursor.line != 0) outch('\n');
25113775Ssam 	 		return;
25213775Ssam 	 	}
25313775Ssam 
25413775Ssam 		tfield = sp->col >> 3;
25513775Ssam 
25613775Ssam 		while (field < tfield){
25713775Ssam 			putpad(TA);
25813775Ssam 			cursor.col = ++field << 3;
25913775Ssam 		}
26013775Ssam 		tabcol = (cursor.col|7) + 1;
26113775Ssam 		strlength = (tabcol - sp->col)*BSlength + 1;
26213775Ssam 		/* length of sequence to overshoot */
26313775Ssam 		if (((sp->col - cursor.col)*NDlength > strlength) &&
26413775Ssam 		    (tabcol < COLUMNS)
26513775Ssam 		   ){
26613775Ssam 			/*
26713775Ssam 			 * Tab past and backup
26813775Ssam 			 */
26913775Ssam 			putpad(TA);
27013775Ssam 			cursor.col = (cursor.col | 7) + 1;
27113775Ssam 			while(cursor.col > sp->col)bs();
27213775Ssam 		}
27313775Ssam 	}
27413775Ssam 	while (sp->col > cursor.col){
27513775Ssam 		nd();
27613775Ssam 	}
27713775Ssam }
27813775Ssam 
27913775Ssam cr(){
28013775Ssam 	outch('\r');
28113775Ssam 	cursor.col = 0;
28213775Ssam }
28313775Ssam 
28413775Ssam clear(){
28513775Ssam 	int i;
28613775Ssam 
28713775Ssam 	if (CL){
28813775Ssam 		putpad(CL);
28913775Ssam 		cursor.col=cursor.line=0;
29013775Ssam 	} else {
29113775Ssam 		for(i=0; i<LINES; i++) {
29213775Ssam 			putchar('\n');
29313775Ssam 		}
29413775Ssam 		cursor.line = LINES - 1;
29513775Ssam 		home();
29613775Ssam 	}
29713775Ssam }
29813775Ssam 
29913775Ssam home(){
30013775Ssam 	struct point z;
30113775Ssam 
30213775Ssam 	if(HO != 0){
30313775Ssam 		putpad(HO);
30413775Ssam 		cursor.col = cursor.line = 0;
30513775Ssam 		return;
30613775Ssam 	}
30713775Ssam 	z.col = z.line = 0;
30813775Ssam 	move(&z);
30913775Ssam }
31013775Ssam 
31113775Ssam ll(){
31213775Ssam 	int j,l;
31313775Ssam 	struct point z;
31413775Ssam 
31513775Ssam 	l = lcnt + 2;
31613775Ssam 	if(LL != NULL && LINES==l){
31713775Ssam 		putpad(LL);
31813775Ssam 		cursor.line = LINES-1;
31913775Ssam 		cursor.col = 0;
32013775Ssam 		return;
32113775Ssam 	}
32213775Ssam 	z.col = 0;
32313775Ssam 	z.line = l-1;
32413775Ssam 	move(&z);
32513775Ssam }
32613775Ssam 
32713775Ssam up(){
32813775Ssam 	putpad(UP);
32913775Ssam 	cursor.line--;
33013775Ssam }
33113775Ssam 
33213775Ssam down(){
33313775Ssam 	putpad(DO);
33413775Ssam 	cursor.line++;
33513775Ssam 	if (cursor.line >= LINES)cursor.line=LINES-1;
33613775Ssam }
33713775Ssam bs(){
33813775Ssam 	if (cursor.col > 0){
33913775Ssam 		putpad(BS);
34013775Ssam 		cursor.col--;
34113775Ssam 	}
34213775Ssam }
34313775Ssam 
34413775Ssam nd(){
34513775Ssam 	putpad(ND);
34613775Ssam 	cursor.col++;
34713775Ssam 	if (cursor.col == COLUMNS+1){
34813775Ssam 		cursor.line++;
34913775Ssam 		cursor.col = 0;
35013775Ssam 		if (cursor.line >= LINES)cursor.line=LINES-1;
35113775Ssam 	}
35213775Ssam }
35313775Ssam 
35413775Ssam pch(c)
35513775Ssam {
35613775Ssam 	outch(c);
35713775Ssam 	if(++cursor.col >= COLUMNS && AM) {
35813775Ssam 		cursor.col = 0;
35913775Ssam 		++cursor.line;
36013775Ssam 	}
36113775Ssam }
36213775Ssam 
363*46760Sbostic apr(ps, fmt)
364*46760Sbostic 	struct point *ps;
365*46760Sbostic 	char *fmt;
36613775Ssam {
36713775Ssam 	struct point p;
368*46760Sbostic 	va_list ap;
36913775Ssam 
37013775Ssam 	p.line = ps->line+1; p.col = ps->col+1;
37113775Ssam 	move(&p);
372*46760Sbostic 	va_start(ap, fmt);
373*46760Sbostic 	(void)vsprintf(str, fmt, ap);
374*46760Sbostic 	va_end(ap);
37513775Ssam 	pstring(str);
37613775Ssam }
37713775Ssam 
378*46760Sbostic pr(fmt)
379*46760Sbostic 	char *fmt;
38013775Ssam {
381*46760Sbostic 	va_list ap;
382*46760Sbostic 
383*46760Sbostic 	va_start(ap, fmt);
384*46760Sbostic 	(void)vsprintf(str, fmt, ap);
385*46760Sbostic 	va_end(ap);
38613775Ssam 	pstring(str);
38713775Ssam }
38813775Ssam 
38913775Ssam pstring(s)
39013775Ssam char *s;{
39113775Ssam 	struct point z;
39213775Ssam 	int stcol;
39313775Ssam 
39413775Ssam 	stcol = cursor.col;
39513775Ssam 	while (s[0] != '\0'){
39613775Ssam 		switch (s[0]){
39713775Ssam 		case '\n':
39813775Ssam 			move(point(&z,0,cursor.line+1));
39913775Ssam 			break;
40013775Ssam 		case '\r':
40113775Ssam 			move(point(&z,stcol,cursor.line+1));
40213775Ssam 			break;
40313775Ssam 		case '\t':
40413775Ssam 			z.col = (((cursor.col + 8) >> 3) << 3);
40513775Ssam 			z.line = cursor.line;
40613775Ssam 			move(&z);
40713775Ssam 			break;
40813775Ssam 		case '\b':
40913775Ssam 			bs();
41013775Ssam 			break;
41133114Sbostic 		case CTRL('g'):
41233114Sbostic 			outch(CTRL('g'));
41313775Ssam 			break;
41413775Ssam 		default:
41513775Ssam 			if (s[0] < ' ')break;
41613775Ssam 			pch(s[0]);
41713775Ssam 		}
41813775Ssam 		s++;
41913775Ssam 	}
42013775Ssam }
42113775Ssam 
42213775Ssam pchar(ps,ch)
42313775Ssam struct point *ps;
42413775Ssam char ch;{
42513775Ssam 	struct point p;
42613775Ssam 	p.col = ps->col + 1; p.line = ps->line + 1;
42713775Ssam 	if (
42813775Ssam 		(p.col >= 0) &&
42913775Ssam 		(p.line >= 0) &&
43013775Ssam 		(
43113775Ssam 			(
43213775Ssam 				(p.line < LINES) &&
43313775Ssam 				(p.col < COLUMNS)
43413775Ssam 			) ||
43513775Ssam 			(
43613775Ssam 	    			(p.col == COLUMNS) &&
43713775Ssam 				(p.line < LINES-1)
43813775Ssam 			)
43913775Ssam 	  	)
44013775Ssam 	){
44113775Ssam 		move(&p);
44213775Ssam 		pch(ch);
44313775Ssam 	}
44413775Ssam }
44513775Ssam 
44613775Ssam 
44713775Ssam outch(c)
44813775Ssam {
44913775Ssam 	putchar(c);
45013775Ssam }
45113775Ssam 
45213775Ssam putpad(str)
45313775Ssam char *str;
45413775Ssam {
45513775Ssam 	if (str)
45613775Ssam 		tputs(str, 1, outch);
45713775Ssam }
45813775Ssam baudrate()
45913775Ssam {
46013775Ssam 
46113775Ssam 	switch (orig.sg_ospeed){
46213775Ssam 	case B300:
46313775Ssam 		return(300);
46413775Ssam 	case B1200:
46513775Ssam 		return(1200);
46613775Ssam 	case B4800:
46713775Ssam 		return(4800);
46813775Ssam 	case B9600:
46913775Ssam 		return(9600);
47013775Ssam 	default:
47113775Ssam 		return(0);
47213775Ssam 	}
47313775Ssam }
47413775Ssam delay(t)
47513775Ssam int t;
47613775Ssam {
47713775Ssam 	int k,j;
47813775Ssam 
47913775Ssam 	k = baudrate() * t / 300;
48013775Ssam 	for(j=0;j<k;j++){
48113775Ssam 		putchar(PC);
48213775Ssam 	}
48313775Ssam }
48413775Ssam 
48513775Ssam done()
48613775Ssam {
48713775Ssam 	cook();
48813775Ssam 	exit(0);
48913775Ssam }
49013775Ssam 
49113775Ssam cook()
49213775Ssam {
49313775Ssam 	delay(1);
49413775Ssam 	putpad(TE);
49513775Ssam 	putpad(KE);
49613775Ssam 	fflush(stdout);
49713775Ssam 	stty(0, &orig);
49813775Ssam #ifdef TIOCSLTC
49913775Ssam 	ioctl(0, TIOCSLTC, &olttyc);
50013775Ssam #endif
50113775Ssam }
50213775Ssam 
50313775Ssam raw()
50413775Ssam {
50513775Ssam 	stty(0, &new);
50613775Ssam #ifdef TIOCSLTC
50713775Ssam 	ioctl(0, TIOCSLTC, &nlttyc);
50813775Ssam #endif
50913775Ssam }
51013775Ssam 
51113775Ssam struct point *point(ps,x,y)
51213775Ssam struct point *ps;
51313775Ssam int x,y;
51413775Ssam {
51513775Ssam 	ps->col=x;
51613775Ssam 	ps->line=y;
51713775Ssam 	return(ps);
51813775Ssam }
51913775Ssam 
52013775Ssam char *ap;
52113775Ssam 
52213775Ssam getcap()
52313775Ssam {
52413775Ssam 	char *getenv();
52513775Ssam 	char *term;
52613775Ssam 	char *xPC;
52713775Ssam 	struct point z;
528*46760Sbostic 	void stop();
52913775Ssam 
53013775Ssam 	term = getenv("TERM");
53113775Ssam 	if (term==0) {
53213775Ssam 		fprintf(stderr, "No TERM in environment\n");
53313775Ssam 		exit(1);
53413775Ssam 	}
53513775Ssam 
53613775Ssam 	switch (tgetent(tbuf, term)) {
53713775Ssam 	case -1:
53813775Ssam 		fprintf(stderr, "Cannot open termcap file\n");
53913775Ssam 		exit(2);
54013775Ssam 	case 0:
54113775Ssam 		fprintf(stderr, "%s: unknown terminal", term);
54213775Ssam 		exit(3);
54313775Ssam 	}
54413775Ssam 
54513775Ssam 	ap = tcapbuf;
54613775Ssam 
54713775Ssam 	LINES = tgetnum("li");
54813775Ssam 	COLUMNS = tgetnum("co");
54934027Sbostic 	if (!lcnt)
55034027Sbostic 		lcnt = LINES - 2;
55134027Sbostic 	if (!ccnt)
55234027Sbostic 		ccnt = COLUMNS - 3;
55313775Ssam 
55413775Ssam 	AM = tgetflag("am");
55513775Ssam 	BW = tgetflag("bw");
55613775Ssam 
55713775Ssam 	ND = tgetstr("nd", &ap);
55813775Ssam 	UP = tgetstr("up", &ap);
55913775Ssam 
56013775Ssam 	DO = tgetstr("do", &ap);
56113775Ssam 	if (DO == 0)
56213775Ssam 		DO = "\n";
56313775Ssam 
56413775Ssam 	BS = tgetstr("bc", &ap);
56513775Ssam 	if (BS == 0 && tgetflag("bs"))
56613775Ssam 		BS = "\b";
56713775Ssam 	if (BS)
56813775Ssam 		xBC = *BS;
56913775Ssam 
57013775Ssam 	TA = tgetstr("ta", &ap);
57113775Ssam 	if (TA == 0 && tgetflag("pt"))
57213775Ssam 		TA = "\t";
57313775Ssam 
57413775Ssam 	HO = tgetstr("ho", &ap);
57513775Ssam 	CL = tgetstr("cl", &ap);
57613775Ssam 	CM = tgetstr("cm", &ap);
57713775Ssam 	LL = tgetstr("ll", &ap);
57813775Ssam 
57913775Ssam 	KL = tgetstr("kl", &ap);
58013775Ssam 	KR = tgetstr("kr", &ap);
58113775Ssam 	KU = tgetstr("ku", &ap);
58213775Ssam 	KD = tgetstr("kd", &ap);
58313775Ssam 	Klength = strlen(KL);
58413775Ssam 		/*	NOTE:   If KL, KR, KU, and KD are not
58513775Ssam 		 *		all the same length, some problems
58613775Ssam 		 *		may arise, since tests are made on
58713775Ssam 		 *		all of them together.
58813775Ssam 		 */
58913775Ssam 
59013775Ssam 	TI = tgetstr("ti", &ap);
59113775Ssam 	TE = tgetstr("te", &ap);
59213775Ssam 	KS = tgetstr("ks", &ap);
59313775Ssam 	KE = tgetstr("ke", &ap);
59413775Ssam 
59513775Ssam 	xPC = tgetstr("pc", &ap);
59613775Ssam 	if (xPC)
59713775Ssam 		PC = *xPC;
59813775Ssam 
59913775Ssam 	NDlength = strlen(ND);
60013775Ssam 	BSlength = strlen(BS);
60113775Ssam 	if ((CM == 0) &&
60213775Ssam 		(HO == 0 | UP==0 || BS==0 || ND==0)) {
60313775Ssam 		fprintf(stderr, "Terminal must have addressible ");
60413775Ssam 		fprintf(stderr, "cursor or home + 4 local motions\n");
60513775Ssam 		exit(5);
60613775Ssam 	}
60713775Ssam 	if (tgetflag("os")) {
60813775Ssam 		fprintf(stderr, "Terminal must not overstrike\n");
60913775Ssam 		exit(5);
61013775Ssam 	}
61113775Ssam 	if (LINES <= 0 || COLUMNS <= 0) {
61213775Ssam 		fprintf(stderr, "Must know the screen size\n");
61313775Ssam 		exit(5);
61413775Ssam 	}
61513775Ssam 
61613775Ssam 	gtty(0, &orig);
61713775Ssam 	new=orig;
61813775Ssam 	new.sg_flags &= ~(ECHO|CRMOD|ALLDELAY|XTABS);
61913775Ssam 	new.sg_flags |= CBREAK;
62013775Ssam 	signal(SIGINT,stop);
62113775Ssam 	ospeed = orig.sg_ospeed;
62213775Ssam #ifdef TIOCGLTC
62313775Ssam 	ioctl(0, TIOCGLTC, &olttyc);
62413775Ssam 	nlttyc = olttyc;
62513775Ssam 	nlttyc.t_suspc = '\377';
62613775Ssam 	nlttyc.t_dsuspc = '\377';
62713775Ssam #endif
62813775Ssam 	raw();
62913775Ssam 
63013775Ssam 	if ((orig.sg_flags & XTABS) == XTABS) TA=0;
63113775Ssam 	putpad(KS);
63213775Ssam 	putpad(TI);
63313775Ssam 	point(&cursor,0,LINES-1);
63413775Ssam }
635