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