121210Sdist /*
2*60746Sbostic  * Copyright (c) 1980, 1993
3*60746Sbostic  *	The Regents of the University of California.  All rights reserved.
433485Sbostic  *
542563Sbostic  * %sccs.include.redist.c%
621210Sdist  */
76758Srrh 
821210Sdist #ifndef lint
9*60746Sbostic static char sccsid[] = "@(#)fancy.c	8.1 (Berkeley) 05/31/93";
1033485Sbostic #endif /* not lint */
1121210Sdist 
126758Srrh #include "back.h"
136758Srrh 
146758Srrh char	PC;			/* padding character */
156758Srrh char	*BC;			/* backspace sequence */
166758Srrh char	*CD;			/* clear to end of screen sequence */
176758Srrh char	*CE;			/* clear to end of line sequence */
186758Srrh char	*CL;			/* clear screen sequence */
196758Srrh char	*CM;			/* cursor movement instructions */
206758Srrh char	*HO;			/* home cursor sequence */
216758Srrh char	*MC;			/* column cursor movement map */
226758Srrh char	*ML;			/* row cursor movement map */
236758Srrh char	*ND;			/* forward cursor sequence */
246758Srrh char	*UP;			/* up cursor sequence */
256758Srrh 
266758Srrh int	lHO;			/* length of HO */
276758Srrh int	lBC;			/* length of BC */
286758Srrh int	lND;			/* length of ND */
296758Srrh int	lUP;			/* length of UP */
306758Srrh int	CO;			/* number of columns */
316758Srrh int	LI;			/* number of lines */
326758Srrh int	*linect;		/* array of lengths of lines on screen
336758Srrh 				   (the actual screen is not stored) */
346758Srrh 
356758Srrh 				/* two letter codes */
366758Srrh char	tcap[] = "bccdceclcmhomcmlndup";
376758Srrh 				/* corresponding strings */
386758Srrh char	**tstr[] = { &BC, &CD, &CE, &CL, &CM, &HO, &MC, &ML, &ND, &UP };
396758Srrh 
406758Srrh int	buffnum;		/* pointer to output buffer */
416758Srrh 
426758Srrh char	tbuf[1024];		/* buffer for decoded termcap entries */
436758Srrh 
446758Srrh int	oldb[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
456758Srrh 
466758Srrh int	oldr;
476758Srrh int	oldw;
486758Srrh 						/* "real" cursor positions, so
496758Srrh 						 * it knows when to reposition.
506758Srrh 						 * These are -1 if curr and curc
516758Srrh 						 * are accurate */
526758Srrh int	realr;
536758Srrh int	realc;
546758Srrh 
5533145Sbostic void	addbuf();
5633145Sbostic 
fboard()576758Srrh fboard ()  {
586758Srrh 	register int	i, j, l;
596758Srrh 
606758Srrh 	curmove (0,0);				/* do top line */
616758Srrh 	for (i = 0; i < 53; i++)
626758Srrh 		fancyc ('_');
636758Srrh 
646758Srrh 	curmove (15,0);				/* do botttom line */
656758Srrh 	for (i = 0; i < 53; i++)
666758Srrh 		fancyc ('_');
676758Srrh 
686758Srrh 	l = 1;					/* do vertical lines */
696758Srrh 	for (i = 52; i > -1; i -= 28)  {
706758Srrh 		curmove ( (l == 1? 1: 15) ,i);
716758Srrh 		fancyc ('|');
726758Srrh 		for (j = 0; j < 14; j++)  {
736758Srrh 			curmove (curr+l,curc-1);
746758Srrh 			fancyc ('|');
756758Srrh 		}
766758Srrh 		if (i == 24)
776758Srrh 			i += 32;
786758Srrh 		l = -l;				/* alternate directions */
796758Srrh 	}
806758Srrh 
816758Srrh 	curmove (2,1);				/* label positions 13-18 */
826758Srrh 	for (i = 13; i < 18; i++)  {
836758Srrh 		fancyc ('1');
846758Srrh 		fancyc ((i % 10)+'0');
856758Srrh 		curmove (curr,curc+2);
866758Srrh 	}
876758Srrh 	fancyc ('1');
886758Srrh 	fancyc ('8');
896758Srrh 
906758Srrh 	curmove (2,29);				/* label positions 19-24 */
916758Srrh 	fancyc ('1');
926758Srrh 	fancyc ('9');
936758Srrh 	for (i = 20; i < 25; i++)  {
946758Srrh 		curmove (curr,curc+2);
956758Srrh 		fancyc ('2');
966758Srrh 		fancyc ((i % 10)+'0');
976758Srrh 	}
986758Srrh 
996758Srrh 	curmove (14,1);				/* label positions 12-7 */
1006758Srrh 	fancyc ('1');
1016758Srrh 	fancyc ('2');
1026758Srrh 	for (i = 11; i > 6; i--)  {
1036758Srrh 		curmove (curr,curc+2);
1046758Srrh 		fancyc (i > 9? '1': ' ');
1056758Srrh 		fancyc ((i % 10)+'0');
1066758Srrh 	}
1076758Srrh 
1086758Srrh 	curmove (14,30);			/* label positions 6-1 */
1096758Srrh 	fancyc ('6');
1106758Srrh 	for (i = 5; i > 0; i--) {
1116758Srrh 		curmove (curr,curc+3);
1126758Srrh 		fancyc (i+'0');
1136758Srrh 	}
1146758Srrh 
1156758Srrh 	for (i = 12; i > 6; i--)		/* print positions 12-7 */
1166758Srrh 		if (board[i])
1176758Srrh 			bsect (board[i],13,1+4*(12-i),-1);
1186758Srrh 
1196758Srrh 	if (board[0])				/* print red men on bar */
1206758Srrh 		bsect (board[0],13,25,-1);
1216758Srrh 
1226758Srrh 	for (i = 6; i > 0; i--)			/* print positions 6-1 */
1236758Srrh 		if (board[i])
1246758Srrh 			bsect (board[i],13,29+4*(6-i),-1);
1256758Srrh 
1266758Srrh 	l = (off[1] < 0? off[1]+15: off[1]);	/* print white's home */
1276758Srrh 	bsect (l,3,54,1);
1286758Srrh 
1296758Srrh 	curmove (8,25);				/* print the word BAR */
1306758Srrh 	fancyc ('B');
1316758Srrh 	fancyc ('A');
1326758Srrh 	fancyc ('R');
1336758Srrh 
1346758Srrh 	for (i = 13; i < 19; i++)		/* print positions 13-18 */
1356758Srrh 		if (board[i])
1366758Srrh 			bsect (board[i],3,1+4*(i-13),1);
1376758Srrh 
1386758Srrh 	if (board[25])				/* print white's men on bar */
1396758Srrh 		bsect (board[25],3,25,1);
1406758Srrh 
1416758Srrh 	for (i = 19; i < 25; i++)		/* print positions 19-24 */
1426758Srrh 		if (board[i])
1436758Srrh 			bsect (board[i],3,29+4*(i-19),1);
1446758Srrh 
1456758Srrh 	l = (off[0] < 0? off[0]+15: off[0]);	/* print red's home */
1466758Srrh 	bsect (-l,13,54,-1);
1476758Srrh 
1486758Srrh 	for (i = 0; i < 26; i++)		/* save board position
1496758Srrh 						 * for refresh later */
1506758Srrh 		oldb[i] = board[i];
1516758Srrh 	oldr = (off[1] < 0? off[1]+15: off[1]);
1526758Srrh 	oldw = -(off[0] < 0? off[0]+15: off[0]);
1536758Srrh }
1546758Srrh 
1556758Srrh /*
1566758Srrh  * bsect (b,rpos,cpos,cnext)
1576758Srrh  *	Print the contents of a board position.  "b" has the value of the
1586758Srrh  * position, "rpos" is the row to start printing, "cpos" is the column to
1596758Srrh  * start printing, and "cnext" is positive if the position starts at the top
1606758Srrh  * and negative if it starts at the bottom.  The value of "cpos" is checked
1616758Srrh  * to see if the position is a player's home, since those are printed
1626758Srrh  * differently.
1636758Srrh  */
1646758Srrh 
bsect(b,rpos,cpos,cnext)1656758Srrh bsect (b,rpos,cpos,cnext)
1666758Srrh int	b;					/* contents of position */
1676758Srrh int	rpos;					/* row of position */
1686758Srrh int	cpos;					/* column of position */
1696758Srrh int	cnext;					/* direction of position */
1706758Srrh 
1716758Srrh {
1726758Srrh 	register int	j;			/* index */
1736758Srrh 	register int	n;			/* number of men on position */
1746758Srrh 	register int	bct;			/* counter */
1756758Srrh 	int		k;			/* index */
1766758Srrh 	char		pc;			/* color of men on position */
1776758Srrh 
1786758Srrh 	n = abs(b);				/* initialize n and pc */
1796758Srrh 	pc = (b > 0? 'r': 'w');
1806758Srrh 
1816758Srrh 	if (n < 6 && cpos < 54)			/* position cursor at start */
1826758Srrh 		curmove (rpos,cpos+1);
1836758Srrh 	else
1846758Srrh 		curmove (rpos,cpos);
1856758Srrh 
1866758Srrh 	for (j = 0; j < 5; j++)  {		/* print position row by row */
1876758Srrh 
1886758Srrh 		for (k = 0; k < 15; k += 5)		/* print men */
1896758Srrh 			if (n > j+k)
1906758Srrh 				fancyc (pc);
1916758Srrh 
1926758Srrh 		if (j < 4)  {				/* figure how far to
1936758Srrh 							 * back up for next
1946758Srrh 							 * row */
1956758Srrh 			if (n < 6)  {			/* stop if none left */
1966758Srrh 				if (j+1 == n)
1976758Srrh 					break;
1986758Srrh 				bct = 1;		/* single column */
1996758Srrh 			} else  {
2006758Srrh 				if (n < 11)  {		/* two columns */
2016758Srrh 					if (cpos == 54)  {	/* home pos */
2026758Srrh 						if (j+5 >= n)
2036758Srrh 							bct = 1;
2046758Srrh 						else
2056758Srrh 							bct = 2;
2066758Srrh 					}
2076758Srrh 					if (cpos < 54)  {	/* not home */
2086758Srrh 						if (j+6 >= n)
2096758Srrh 							bct = 1;
2106758Srrh 						else
2116758Srrh 							bct = 2;
2126758Srrh 					}
2136758Srrh 				} else  {		/* three columns */
2146758Srrh 					if (j+10 >= n)
2156758Srrh 						bct = 2;
2166758Srrh 					else
2176758Srrh 						bct = 3;
2186758Srrh 				}
2196758Srrh 			}
2206758Srrh 			curmove (curr+cnext,curc-bct);	/* reposition cursor */
2216758Srrh 		}
2226758Srrh 	}
2236758Srrh }
2246758Srrh 
refresh()2256758Srrh refresh()  {
2266758Srrh 	register int	i, r, c;
2276758Srrh 
2286758Srrh 	r = curr;				/* save current position */
2296758Srrh 	c = curc;
2306758Srrh 
2316758Srrh 	for (i = 12; i > 6; i--)		/* fix positions 12-7 */
2326758Srrh 		if (board[i] != oldb[i])  {
2336758Srrh 			fixpos (oldb[i],board[i],13,1+(12-i)*4,-1);
2346758Srrh 			oldb[i] = board[i];
2356758Srrh 		}
2366758Srrh 
2376758Srrh 	if (board[0] != oldb[0])  {		/* fix red men on bar */
2386758Srrh 		fixpos (oldb[0],board[0],13,25,-1);
2396758Srrh 		oldb[0] = board[0];
2406758Srrh 	}
2416758Srrh 
2426758Srrh 	for (i = 6; i > 0; i--)			/* fix positions 6-1 */
2436758Srrh 		if (board[i] != oldb[i])  {
2446758Srrh 			fixpos (oldb[i],board[i],13,29+(6-i)*4,-1);
2456758Srrh 			oldb[i] = board[i];
2466758Srrh 		}
2476758Srrh 
2486758Srrh 	i = -(off[0] < 0? off[0]+15: off[0]);	/* fix white's home */
2496758Srrh 	if (oldw != i)  {
2506758Srrh 		fixpos (oldw,i,13,54,-1);
2516758Srrh 		oldw = i;
2526758Srrh 	}
2536758Srrh 
2546758Srrh 	for (i = 13; i < 19; i++)		/* fix positions 13-18 */
2556758Srrh 		if (board[i] != oldb[i])  {
2566758Srrh 			fixpos (oldb[i],board[i],3,1+(i-13)*4,1);
2576758Srrh 			oldb[i] = board[i];
2586758Srrh 		}
2596758Srrh 
2606758Srrh 	if (board[25] != oldb[25])  {		/* fix white men on bar */
2616758Srrh 		fixpos (oldb[25],board[25],3,25,1);
2626758Srrh 		oldb[25] = board[25];
2636758Srrh 	}
2646758Srrh 
2656758Srrh 	for (i = 19; i < 25; i++)		/* fix positions 19-24 */
2666758Srrh 		if (board[i] != oldb[i])  {
2676758Srrh 			fixpos (oldb[i],board[i],3,29+(i-19)*4,1);
2686758Srrh 			oldb[i] = board[i];
2696758Srrh 		}
2706758Srrh 
2716758Srrh 	i = (off[1] < 0? off[1]+15: off[1]);	/* fix red's home */
2726758Srrh 	if (oldr != i)  {
2736758Srrh 		fixpos (oldr,i,3,54,1);
2746758Srrh 		oldr = i;
2756758Srrh 	}
2766758Srrh 
2776758Srrh 	curmove (r,c);				/* return to saved position */
2786758Srrh 	newpos();
2796758Srrh 	buflush();
2806758Srrh }
2816758Srrh 
fixpos(old,new,r,c,inc)2826758Srrh fixpos (old,new,r,c,inc)
2836758Srrh int	old, new, r, c, inc;
2846758Srrh 
2856758Srrh {
2866758Srrh 	register int	o, n, nv;
2876758Srrh 	int		ov, nc;
2886758Srrh 	char		col;
2896758Srrh 
2906758Srrh 	if (old*new >= 0)  {
2916758Srrh 		ov = abs(old);
2926758Srrh 		nv = abs(new);
2936758Srrh 		col = (old+new > 0? 'r': 'w');
2946758Srrh 		o = (ov-1)/5;
2956758Srrh 		n = (nv-1)/5;
2966758Srrh 		if (o == n)  {
2976758Srrh 			if (o == 2)
2986758Srrh 				nc = c+2;
2996758Srrh 			if (o == 1)
3006758Srrh 				nc = c < 54? c: c+1;
3016758Srrh 			if (o == 0)
3026758Srrh 				nc = c < 54? c+1: c;
3036758Srrh 			if (ov > nv)
3046758Srrh 				fixcol (r+inc*(nv-n*5),nc,abs(ov-nv),' ',inc);
3056758Srrh 			else
3066758Srrh 				fixcol (r+inc*(ov-o*5),nc,abs(ov-nv),col,inc);
3076758Srrh 			return;
3086758Srrh 		} else  {
3096758Srrh 			if (c < 54)  {
3106758Srrh 				if (o+n == 1)  {
3116758Srrh 					if (n)  {
3126758Srrh 						fixcol (r,c,abs(nv-5),col,inc);
3136758Srrh 						if (ov != 5)
3146758Srrh 							fixcol (r+inc*ov,c+1,abs(ov-5),col,inc);
3156758Srrh 					} else  {
3166758Srrh 						fixcol (r,c,abs(ov-5),' ',inc);
3176758Srrh 						if (nv != 5)
3186758Srrh 							fixcol (r+inc*nv,c+1,abs(nv-5),' ',inc);
3196758Srrh 					}
3206758Srrh 					return;
3216758Srrh 				}
3226758Srrh 				if (n == 2)  {
3236758Srrh 					if (ov != 10)
3246758Srrh 						fixcol (r+inc*(ov-5),c,abs(ov-10),col,inc);
3256758Srrh 					fixcol (r,c+2,abs(nv-10),col,inc);
3266758Srrh 				} else  {
3276758Srrh 					if (nv != 10)
3286758Srrh 						fixcol (r+inc*(nv-5),c,abs(nv-10),' ',inc);
3296758Srrh 					fixcol (r,c+2,abs(ov-10),' ',inc);
3306758Srrh 				}
3316758Srrh 				return;
3326758Srrh 			}
3336758Srrh 			if (n > o)  {
3346758Srrh 				fixcol (r+inc*(ov%5),c+o,abs(5*n-ov),col,inc);
3356758Srrh 				if (nv != 5*n)
3366758Srrh 					fixcol (r,c+n,abs(5*n-nv),col,inc);
3376758Srrh 			} else  {
3386758Srrh 				fixcol (r+inc*(nv%5),c+n,abs(5*n-nv),' ',inc);
3396758Srrh 				if (ov != 5*o)
3406758Srrh 					fixcol (r,c+o,abs(5*o-ov),' ',inc);
3416758Srrh 			}
3426758Srrh 			return;
3436758Srrh 		}
3446758Srrh 	}
3456758Srrh 	nv = abs(new);
3466758Srrh 	fixcol (r,c+1,nv,new > 0? 'r': 'w',inc);
3476758Srrh 	if (abs(old) <= abs(new))
3486758Srrh 		return;
3496758Srrh 	fixcol (r+inc*new,c+1,abs(old+new),' ',inc);
3506758Srrh }
3516758Srrh 
fixcol(r,c,l,ch,inc)3526758Srrh fixcol (r,c,l,ch,inc)
3536758Srrh register int	l, ch;
3546758Srrh int		r, c, inc;
3556758Srrh 
3566758Srrh {
3576758Srrh 	register int	i;
3586758Srrh 
3596758Srrh 	curmove (r,c);
3606758Srrh 	fancyc (ch);
3616758Srrh 	for (i = 1; i < l; i++)  {
3626758Srrh 		curmove (curr+inc,curc-1);
3636758Srrh 		fancyc (ch);
3646758Srrh 	}
3656758Srrh }
3666758Srrh 
curmove(r,c)3676758Srrh curmove (r,c)
3686758Srrh register int	r, c;
3696758Srrh 
3706758Srrh {
3716758Srrh 	if (curr == r && curc == c)
3726758Srrh 		return;
3736758Srrh 	if (realr == -1)  {
3746758Srrh 		realr = curr;
3756758Srrh 		realc = curc;
3766758Srrh 	}
3776758Srrh 	curr = r;
3786758Srrh 	curc = c;
3796758Srrh }
3806758Srrh 
newpos()3816758Srrh newpos ()  {
3826758Srrh 	register int	r;		/* destination row */
3836758Srrh 	register int	c;		/* destination column */
3846758Srrh 	register int	mode = -1;	/* mode of movement */
3856758Srrh 
3866758Srrh 	int	count = 1000;		/* character count */
3876758Srrh 	int	i;			/* index */
3886758Srrh 	int	j;			/* index */
3896758Srrh 	int	n;			/* temporary variable */
3906758Srrh 	char	*m;			/* string containing CM movement */
3916758Srrh 
3926758Srrh 
3936758Srrh 	if (realr == -1)		/* see if already there */
3946758Srrh 		return;
3956758Srrh 
3966758Srrh 	r = curr;			/* set current and dest. positions */
3976758Srrh 	c = curc;
3986758Srrh 	curr = realr;
3996758Srrh 	curc = realc;
4006758Srrh 
4016758Srrh 					/* double check position */
4026758Srrh 	if (curr == r && curc == c)  {
4036758Srrh 		realr = realc = -1;
4046758Srrh 		return;
4056758Srrh 	}
4066758Srrh 
4076758Srrh 	if (CM)  {			/* try CM to get there */
4086758Srrh 		mode = 0;
40933485Sbostic 		m = (char *)tgoto (CM,c,r);
4106758Srrh 		count = strlen (m);
4116758Srrh 	}
4126758Srrh 
4136758Srrh 					/* try HO and local movement */
4146758Srrh 	if (HO && (n = r+c*lND+lHO) < count)  {
4156758Srrh 		mode = 1;
4166758Srrh 		count = n;
4176758Srrh 	}
4186758Srrh 
4196758Srrh 					/* try various LF combinations */
4206758Srrh 	if (r >= curr)  {
4216758Srrh 						/* CR, LF, and ND */
4226758Srrh 		if ((n = (r-curr)+c*lND+1) < count)  {
4236758Srrh 			mode = 2;
4246758Srrh 			count = n;
4256758Srrh 		}
4266758Srrh 						/* LF, ND */
4276758Srrh 		if (c >= curc && (n = (r-curr)+(c-curc)*lND) < count)  {
4286758Srrh 			mode = 3;
4296758Srrh 			count = n;
4306758Srrh 		}
4316758Srrh 						/* LF, BS */
4326758Srrh 		if (c < curc && (n = (r-curr)+(curc-c)*lBC) < count)  {
4336758Srrh 			mode = 4;
4346758Srrh 			count = n;
4356758Srrh 		}
4366758Srrh 	}
4376758Srrh 
4386758Srrh 					/* try corresponding UP combinations */
4396758Srrh 	if (r < curr)  {
4406758Srrh 						/* CR, UP, and ND */
4416758Srrh 		if ((n = (curr-r)*lUP+c*lND+1) < count)  {
4426758Srrh 			mode = 5;
4436758Srrh 			count = n;
4446758Srrh 		}
4456758Srrh 						/* UP and ND */
4466758Srrh 		if (c >= curc && (n = (curr-r)*lUP+(c-curc)*lND) < count)  {
4476758Srrh 			mode = 6;
4486758Srrh 			count = n;
4496758Srrh 		}
4506758Srrh 						/* UP and BS */
4516758Srrh 		if (c < curc && (n = (curr-r)*lUP+(curc-c)*lBC) < count)  {
4526758Srrh 			mode = 7;
4536758Srrh 			count = n;
4546758Srrh 		}
4556758Srrh 	}
4566758Srrh 
4576758Srrh 						/* space over */
4586758Srrh 	if (curr == r && c > curc && linect[r] < curc && c-curc < count)
4596758Srrh 		mode = 8;
4606758Srrh 
4616758Srrh 	switch (mode)  {
4626758Srrh 
4636758Srrh 	case -1:				/* error! */
4646758Srrh 		write (2,"\r\nInternal cursor error.\r\n",26);
4656758Srrh 		getout();
4666758Srrh 
4676758Srrh 						/* direct cursor motion */
4686758Srrh 	case  0:
4696758Srrh 		tputs (m,abs(curr-r),addbuf);
4706758Srrh 		break;
4716758Srrh 
4726758Srrh 						/* relative to "home" */
4736758Srrh 	case  1:
4746758Srrh 		tputs (HO,r,addbuf);
4756758Srrh 		for (i = 0; i < r; i++)
4766758Srrh 			addbuf ('\012');
4776758Srrh 		for (i = 0; i < c; i++)
4786758Srrh 			tputs (ND,1,addbuf);
4796758Srrh 		break;
4806758Srrh 
4816758Srrh 						/* CR and down and over */
4826758Srrh 	case  2:
4836758Srrh 		addbuf ('\015');
4846758Srrh 		for (i = 0; i < r-curr; i++)
4856758Srrh 			addbuf ('\012');
4866758Srrh 		for (i = 0; i < c; i++)
4876758Srrh 			tputs (ND,1,addbuf);
4886758Srrh 		break;
4896758Srrh 
4906758Srrh 						/* down and over */
4916758Srrh 	case  3:
4926758Srrh 		for (i = 0; i < r-curr; i++)
4936758Srrh 			addbuf ('\012');
4946758Srrh 		for (i = 0; i < c-curc; i++)
4956758Srrh 			tputs (ND,1,addbuf);
4966758Srrh 		break;
4976758Srrh 
4986758Srrh 						/* down and back */
4996758Srrh 	case  4:
5006758Srrh 		for (i = 0; i < r-curr; i++)
5016758Srrh 			addbuf ('\012');
5026758Srrh 		for (i = 0; i < curc-c; i++)
5036758Srrh 			addbuf ('\010');
5046758Srrh 		break;
5056758Srrh 
5066758Srrh 						/* CR and up and over */
5076758Srrh 	case  5:
5086758Srrh 		addbuf ('\015');
5096758Srrh 		for (i = 0; i < curr-r; i++)
5106758Srrh 			tputs (UP,1,addbuf);
5116758Srrh 		for (i = 0; i < c; i++)
5126758Srrh 			tputs (ND,1,addbuf);
5136758Srrh 		break;
5146758Srrh 
5156758Srrh 						/* up and over */
5166758Srrh 	case  6:
5176758Srrh 		for (i = 0; i < curr-r; i++)
5186758Srrh 			tputs (UP,1,addbuf);
5196758Srrh 		for (i = 0; i < c-curc; i++)
5206758Srrh 			tputs (ND,1,addbuf);
5216758Srrh 		break;
5226758Srrh 
5236758Srrh 						/* up and back */
5246758Srrh 	case  7:
5256758Srrh 		for (i = 0; i < curr-r; i++)
5266758Srrh 			tputs (UP,1,addbuf);
5276758Srrh 		for (i = 0; i < curc-c; i++)  {
5286758Srrh 			if (BC)
5296758Srrh 				tputs (BC,1,addbuf);
5306758Srrh 			else
5316758Srrh 				addbuf ('\010');
5326758Srrh 		}
5336758Srrh 		break;
5346758Srrh 
5356758Srrh 						/* safe space */
5366758Srrh 	case  8:
5376758Srrh 		for (i = 0; i < c-curc; i++)
5386758Srrh 			addbuf (' ');
5396758Srrh 	}
5406758Srrh 
5416758Srrh 						/* fix positions */
5426758Srrh 	curr = r;
5436758Srrh 	curc = c;
5446758Srrh 	realr = -1;
5456758Srrh 	realc = -1;
5466758Srrh }
5476758Srrh 
clear()5486758Srrh clear ()  {
5496758Srrh 	register int	i;
5506758Srrh 
5516758Srrh 					/* double space if can't clear */
5526758Srrh 	if (CL == 0)  {
5536758Srrh 		writel ("\n\n");
5546758Srrh 		return;
5556758Srrh 	}
5566758Srrh 
5576758Srrh 	curr = curc = 0;		/* fix position markers */
5586758Srrh 	realr = realc = -1;
5596758Srrh 	for (i = 0; i < 24; i++)	/* clear line counts */
5606758Srrh 		linect[i] = -1;
5616758Srrh 	buffnum = -1;			/* ignore leftover buffer contents */
5626758Srrh 	tputs (CL,CO,addbuf);		/* put CL in buffer */
5636758Srrh }
5646758Srrh 
tos()5656758Srrh tos ()  {				/* home cursor */
5666758Srrh 	curmove (0,0);
5676758Srrh }
5686758Srrh 
fancyc(c)5696758Srrh fancyc (c)
5706758Srrh register char	c;			/* character to output */
5716758Srrh {
5726758Srrh 	register int	sp;		/* counts spaces in a tab */
5736758Srrh 
5746758Srrh 	if (c == '\007')  {		/* bells go in blindly */
5756758Srrh 		addbuf (c);
5766758Srrh 		return;
5776758Srrh 	}
5786758Srrh 
5796758Srrh 					/* process tabs, use spaces if the
5806758Srrh 					 * the tab should be erasing things,
5816758Srrh 					 * otherwise use cursor movement
5826758Srrh 					 * routines.  Note this does not use
5836758Srrh 					 * hardware tabs at all. */
5846758Srrh 	if (c == '\t')  {
5856758Srrh 		sp = (curc+8) & (~ 7);		/* compute spaces */
5866758Srrh 						/* check line length */
5876758Srrh 		if (linect[curr] >= curc || sp < 4)  {
5886758Srrh 			for (; sp > curc; sp--)
5896758Srrh 				addbuf (' ');
5906758Srrh 			curc = sp;		/* fix curc */
5916758Srrh 		} else
5926758Srrh 			curmove (curr,sp);
5936758Srrh 		return;
5946758Srrh 	}
5956758Srrh 
5966758Srrh 					/* do newline be calling newline */
5976758Srrh 	if (c == '\n')  {
5986758Srrh 		newline();
5996758Srrh 		return;
6006758Srrh 	}
6016758Srrh 
6026758Srrh 					/* ignore any other control chars */
6036758Srrh 	if (c < ' ')
6046758Srrh 		return;
6056758Srrh 
6066758Srrh 					/* if an erasing space or non-space,
6076758Srrh 					 * just add it to buffer.  Otherwise
6086758Srrh 					 * use cursor movement routine, so that
6096758Srrh 					 * multiple spaces will be grouped
6106758Srrh 					 * together */
6116758Srrh 	if (c > ' ' || linect[curr] >= curc)  {
6126758Srrh 		newpos ();			/* make sure position correct */
6136758Srrh 		addbuf (c);			/* add character to buffer */
6146758Srrh 						/* fix line length */
6156758Srrh 		if (c == ' ' && linect[curr] == curc)
6166758Srrh 			linect[curr]--;
6176758Srrh 		else if (linect[curr] < curc)
6186758Srrh 			linect[curr] = curc;
6196758Srrh 		curc++;				/* fix curc */
6206758Srrh 	} else
6216758Srrh 					/* use cursor movement routine */
6226758Srrh 		curmove (curr,curc+1);
6236758Srrh }
6246758Srrh 
clend()6256758Srrh clend()  {
6266758Srrh 	register int	i;
6276758Srrh 	register char	*s;
6286758Srrh 
6296758Srrh 
6306758Srrh 	if (CD)  {
6316758Srrh 		tputs (CD,CO-curr,addbuf);
6326758Srrh 		for (i = curr; i < LI; i++)
6336758Srrh 			linect[i] = -1;
6346758Srrh 		return;
6356758Srrh 	}
6366758Srrh 
6376758Srrh 	curmove (i = curr,0);
6386758Srrh 	cline();
6396758Srrh 	while (curr < LI-1)  {
6406758Srrh 		curmove (curr+1,0);
6416758Srrh 		if (linect[curr] > -1)
6426758Srrh 			cline ();
6436758Srrh 	}
6446758Srrh 	curmove (i,0);
6456758Srrh }
6466758Srrh 
cline()6476758Srrh cline ()  {
6486758Srrh 	register int	i;
6496758Srrh 	register int	c;
6506758Srrh 	register char	*s;
6516758Srrh 
6526758Srrh 	if (curc > linect[curr])
6536758Srrh 		return;
6546758Srrh 	newpos ();
6556758Srrh 	if (CE)  {
6566758Srrh 		tputs (CE,1,addbuf);
6576758Srrh 		linect[curr] = curc-1;
6586758Srrh 	} else  {
6596758Srrh 		c = curc-1;
6606758Srrh 		while (linect[curr] > c)  {
6616758Srrh 			addbuf (' ');
6626758Srrh 			curc++;
6636758Srrh 			linect[curr]--;
6646758Srrh 		}
6656758Srrh 		curmove (curr,c+1);
6666758Srrh 	}
6676758Srrh }
6686758Srrh 
newline()6696758Srrh newline ()  {
6706758Srrh 	cline();
6716758Srrh 	if (curr == LI-1)
6726758Srrh 		curmove (begscr,0);
6736758Srrh 	else
6746758Srrh 		curmove (curr+1,0);
6756758Srrh }
6766758Srrh 
getcaps(s)6776758Srrh getcaps (s)
6786758Srrh register char	*s;
6796758Srrh 
6806758Srrh {
6816758Srrh 	register char	*code;		/* two letter code */
6826758Srrh 	register char	***cap;		/* pointer to cap string */
6836758Srrh 	char		*bufp;		/* pointer to cap buffer */
6846758Srrh 	char		tentry[1024];	/* temporary uncoded caps buffer */
6856758Srrh 
6866758Srrh 	tgetent (tentry,s);		/* get uncoded termcap entry */
6876758Srrh 
6886758Srrh 	LI = tgetnum ("li");		/* get number of lines */
6896758Srrh 	if (LI == -1)
6906758Srrh 		LI = 12;
6916758Srrh 	CO = tgetnum ("co");		/* get number of columns */
6926758Srrh 	if (CO == -1)
6936758Srrh 		CO = 65;
6946758Srrh 
6956758Srrh 	bufp = tbuf;			/* get padding character */
6966758Srrh 	tgetstr ("pc",&bufp);
6976758Srrh 	if (bufp != tbuf)
6986758Srrh 		PC = *tbuf;
6996758Srrh 	else
7006758Srrh 		PC = 0;
7016758Srrh 
7026758Srrh 	bufp = tbuf;			/* get string entries */
7036758Srrh 	cap = tstr;
7046758Srrh 	for (code = tcap; *code; code += 2)
70533485Sbostic 		**cap++ = (char *)tgetstr (code,&bufp);
7066758Srrh 
7076758Srrh 					/* get pertinent lengths */
7086758Srrh 	if (HO)
7096758Srrh 		lHO = strlen (HO);
7106758Srrh 	if (BC)
7116758Srrh 		lBC = strlen (BC);
7126758Srrh 	else
7136758Srrh 		lBC = 1;
7146758Srrh 	if (UP)
7156758Srrh 		lUP = strlen (UP);
7166758Srrh 	if (ND)
7176758Srrh 		lND = strlen (ND);
7186758Srrh 	if (LI < 24 || CO < 72 || !(CL && UP && ND))
7196758Srrh 		return (0);
72033485Sbostic 	linect = (int *)calloc (LI+1,sizeof(int));
7216758Srrh 	return (1);
7226758Srrh }
723