xref: /netbsd-src/games/backgammon/common_source/fancy.c (revision d710132b4b8ce7f7cccaaf660cb16aa16b4077a0)
1 /*	$NetBSD: fancy.c,v 1.10 1999/07/26 18:39:06 hubertf Exp $	*/
2 
3 /*
4  * Copyright (c) 1980, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  */
35 
36 #include <sys/cdefs.h>
37 #ifndef lint
38 #if 0
39 static char sccsid[] = "@(#)fancy.c	8.1 (Berkeley) 5/31/93";
40 #else
41 __RCSID("$NetBSD: fancy.c,v 1.10 1999/07/26 18:39:06 hubertf Exp $");
42 #endif
43 #endif /* not lint */
44 
45 #include "back.h"
46 
47 char    PC;			/* padding character */
48 char   *BC;			/* backspace sequence */
49 char   *CD;			/* clear to end of screen sequence */
50 char   *CE;			/* clear to end of line sequence */
51 char   *CL;			/* clear screen sequence */
52 char   *CM;			/* cursor movement instructions */
53 char   *HO;			/* home cursor sequence */
54 char   *MC;			/* column cursor movement map */
55 char   *ML;			/* row cursor movement map */
56 char   *ND;			/* forward cursor sequence */
57 char   *UP;			/* up cursor sequence */
58 
59 int     lHO;			/* length of HO */
60 int     lBC;			/* length of BC */
61 int     lND;			/* length of ND */
62 int     lUP;			/* length of UP */
63 int     CO;			/* number of columns */
64 int     LI;			/* number of lines */
65 int    *linect;			/* array of lengths of lines on screen (the
66 				 * actual screen is not stored) */
67 
68  /* two letter codes */
69 char    tcap[] = "bccdceclcmhomcmlndup";
70  /* corresponding strings */
71 char  **tstr[] = {&BC, &CD, &CE, &CL, &CM, &HO, &MC, &ML, &ND, &UP};
72 
73 int     buffnum;		/* pointer to output buffer */
74 
75 char    tbuf[1024];		/* buffer for decoded termcap entries */
76 
77 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};
78 
79 int     oldr;
80 int     oldw;
81  /* "real" cursor positions, so it knows when to reposition. These are -1 if
82   * curr and curc are accurate */
83 int     realr;
84 int     realc;
85 
86 void
87 fboard()
88 {
89 	int     i, j, l;
90 
91 	curmove(0, 0);		/* do top line */
92 	for (i = 0; i < 53; i++)
93 		fancyc('_');
94 
95 	curmove(15, 0);		/* do botttom line */
96 	for (i = 0; i < 53; i++)
97 		fancyc('_');
98 
99 	l = 1;			/* do vertical lines */
100 	for (i = 52; i > -1; i -= 28) {
101 		curmove((l == 1 ? 1 : 15), i);
102 		fancyc('|');
103 		for (j = 0; j < 14; j++) {
104 			curmove(curr + l, curc - 1);
105 			fancyc('|');
106 		}
107 		if (i == 24)
108 			i += 32;
109 		l = -l;		/* alternate directions */
110 	}
111 
112 	curmove(2, 1);		/* label positions 13-18 */
113 	for (i = 13; i < 18; i++) {
114 		fancyc('1');
115 		fancyc((i % 10) + '0');
116 		curmove(curr, curc + 2);
117 	}
118 	fancyc('1');
119 	fancyc('8');
120 
121 	curmove(2, 29);		/* label positions 19-24 */
122 	fancyc('1');
123 	fancyc('9');
124 	for (i = 20; i < 25; i++) {
125 		curmove(curr, curc + 2);
126 		fancyc('2');
127 		fancyc((i % 10) + '0');
128 	}
129 
130 	curmove(14, 1);		/* label positions 12-7 */
131 	fancyc('1');
132 	fancyc('2');
133 	for (i = 11; i > 6; i--) {
134 		curmove(curr, curc + 2);
135 		fancyc(i > 9 ? '1' : ' ');
136 		fancyc((i % 10) + '0');
137 	}
138 
139 	curmove(14, 30);	/* label positions 6-1 */
140 	fancyc('6');
141 	for (i = 5; i > 0; i--) {
142 		curmove(curr, curc + 3);
143 		fancyc(i + '0');
144 	}
145 
146 	for (i = 12; i > 6; i--)/* print positions 12-7 */
147 		if (board[i])
148 			bsect(board[i], 13, 1 + 4 * (12 - i), -1);
149 
150 	if (board[0])		/* print red men on bar */
151 		bsect(board[0], 13, 25, -1);
152 
153 	for (i = 6; i > 0; i--)	/* print positions 6-1 */
154 		if (board[i])
155 			bsect(board[i], 13, 29 + 4 * (6 - i), -1);
156 
157 	l = (off[1] < 0 ? off[1] + 15 : off[1]);	/* print white's home */
158 	bsect(l, 3, 54, 1);
159 
160 	curmove(8, 25);		/* print the word BAR */
161 	fancyc('B');
162 	fancyc('A');
163 	fancyc('R');
164 
165 	for (i = 13; i < 19; i++)	/* print positions 13-18 */
166 		if (board[i])
167 			bsect(board[i], 3, 1 + 4 * (i - 13), 1);
168 
169 	if (board[25])		/* print white's men on bar */
170 		bsect(board[25], 3, 25, 1);
171 
172 	for (i = 19; i < 25; i++)	/* print positions 19-24 */
173 		if (board[i])
174 			bsect(board[i], 3, 29 + 4 * (i - 19), 1);
175 
176 	l = (off[0] < 0 ? off[0] + 15 : off[0]);	/* print red's home */
177 	bsect(-l, 13, 54, -1);
178 
179 	for (i = 0; i < 26; i++)/* save board position for refresh later */
180 		oldb[i] = board[i];
181 	oldr = (off[1] < 0 ? off[1] + 15 : off[1]);
182 	oldw = -(off[0] < 0 ? off[0] + 15 : off[0]);
183 }
184 /*
185  * bsect (b,rpos,cpos,cnext)
186  *	Print the contents of a board position.  "b" has the value of the
187  * position, "rpos" is the row to start printing, "cpos" is the column to
188  * start printing, and "cnext" is positive if the position starts at the top
189  * and negative if it starts at the bottom.  The value of "cpos" is checked
190  * to see if the position is a player's home, since those are printed
191  * differently.
192  */
193 void
194 bsect(b, rpos, cpos, cnext)
195 	int     b;		/* contents of position */
196 	int     rpos;		/* row of position */
197 	int     cpos;		/* column of position */
198 	int     cnext;		/* direction of position */
199 {
200 	int     j;		/* index */
201 	int     n;		/* number of men on position */
202 	int     bct;		/* counter */
203 	int     k;		/* index */
204 	char    pc;		/* color of men on position */
205 
206 	bct = 0;
207 	n = abs(b);		/* initialize n and pc */
208 	pc = (b > 0 ? 'r' : 'w');
209 
210 	if (n < 6 && cpos < 54)	/* position cursor at start */
211 		curmove(rpos, cpos + 1);
212 	else
213 		curmove(rpos, cpos);
214 
215 	for (j = 0; j < 5; j++) {	/* print position row by row */
216 
217 		for (k = 0; k < 15; k += 5)	/* print men */
218 			if (n > j + k)
219 				fancyc(pc);
220 
221 		if (j < 4) {	/* figure how far to back up for next row */
222 			if (n < 6) {	/* stop if none left */
223 				if (j + 1 == n)
224 					break;
225 				bct = 1;	/* single column */
226 			} else {
227 				if (n < 11) {	/* two columns */
228 					if (cpos == 54) {	/* home pos */
229 						if (j + 5 >= n)
230 							bct = 1;
231 						else
232 							bct = 2;
233 					}
234 					if (cpos < 54) {	/* not home */
235 						if (j + 6 >= n)
236 							bct = 1;
237 						else
238 							bct = 2;
239 					}
240 				} else {	/* three columns */
241 					if (j + 10 >= n)
242 						bct = 2;
243 					else
244 						bct = 3;
245 				}
246 			}
247 			curmove(curr + cnext, curc - bct);	/* reposition cursor */
248 		}
249 	}
250 }
251 
252 void
253 refresh()
254 {
255 	int     i, r, c;
256 
257 	r = curr;		/* save current position */
258 	c = curc;
259 
260 	for (i = 12; i > 6; i--)/* fix positions 12-7 */
261 		if (board[i] != oldb[i]) {
262 			fixpos(oldb[i], board[i], 13, 1 + (12 - i) * 4, -1);
263 			oldb[i] = board[i];
264 		}
265 	if (board[0] != oldb[0]) {	/* fix red men on bar */
266 		fixpos(oldb[0], board[0], 13, 25, -1);
267 		oldb[0] = board[0];
268 	}
269 	for (i = 6; i > 0; i--)	/* fix positions 6-1 */
270 		if (board[i] != oldb[i]) {
271 			fixpos(oldb[i], board[i], 13, 29 + (6 - i) * 4, -1);
272 			oldb[i] = board[i];
273 		}
274 	i = -(off[0] < 0 ? off[0] + 15 : off[0]);	/* fix white's home */
275 	if (oldw != i) {
276 		fixpos(oldw, i, 13, 54, -1);
277 		oldw = i;
278 	}
279 	for (i = 13; i < 19; i++)	/* fix positions 13-18 */
280 		if (board[i] != oldb[i]) {
281 			fixpos(oldb[i], board[i], 3, 1 + (i - 13) * 4, 1);
282 			oldb[i] = board[i];
283 		}
284 	if (board[25] != oldb[25]) {	/* fix white men on bar */
285 		fixpos(oldb[25], board[25], 3, 25, 1);
286 		oldb[25] = board[25];
287 	}
288 	for (i = 19; i < 25; i++)	/* fix positions 19-24 */
289 		if (board[i] != oldb[i]) {
290 			fixpos(oldb[i], board[i], 3, 29 + (i - 19) * 4, 1);
291 			oldb[i] = board[i];
292 		}
293 	i = (off[1] < 0 ? off[1] + 15 : off[1]);	/* fix red's home */
294 	if (oldr != i) {
295 		fixpos(oldr, i, 3, 54, 1);
296 		oldr = i;
297 	}
298 	curmove(r, c);		/* return to saved position */
299 	newpos();
300 	buflush();
301 }
302 
303 void
304 fixpos(old, new, r, c, inc)
305 	int     old, new, r, c, inc;
306 {
307 	int     o, n, nv;
308 	int     ov, nc;
309 	char    col;
310 
311 	nc = 0;
312 	if (old * new >= 0) {
313 		ov = abs(old);
314 		nv = abs(new);
315 		col = (old + new > 0 ? 'r' : 'w');
316 		o = (ov - 1) / 5;
317 		n = (nv - 1) / 5;
318 		if (o == n) {
319 			if (o == 2)
320 				nc = c + 2;
321 			if (o == 1)
322 				nc = c < 54 ? c : c + 1;
323 			if (o == 0)
324 				nc = c < 54 ? c + 1 : c;
325 			if (ov > nv)
326 				fixcol(r + inc * (nv - n * 5), nc, abs(ov - nv), ' ', inc);
327 			else
328 				fixcol(r + inc * (ov - o * 5), nc, abs(ov - nv), col, inc);
329 			return;
330 		} else {
331 			if (c < 54) {
332 				if (o + n == 1) {
333 					if (n) {
334 						fixcol(r, c, abs(nv - 5), col, inc);
335 						if (ov != 5)
336 							fixcol(r + inc * ov, c + 1,
337 							    abs(ov - 5), col, inc);
338 					} else {
339 						fixcol(r, c, abs(ov - 5), ' ', inc);
340 						if (nv != 5)
341 							fixcol(r + inc * nv, c + 1,
342 							    abs(nv - 5), ' ', inc);
343 					}
344 					return;
345 				}
346 				if (n == 2) {
347 					if (ov != 10)
348 						fixcol(r + inc * (ov - 5), c,
349 						    abs(ov - 10), col, inc);
350 					fixcol(r, c + 2, abs(nv - 10), col, inc);
351 				} else {
352 					if (nv != 10)
353 						fixcol(r + inc * (nv - 5), c,
354 						    abs(nv - 10), ' ', inc);
355 					fixcol(r, c + 2, abs(ov - 10), ' ', inc);
356 				}
357 				return;
358 			}
359 			if (n > o) {
360 				fixcol(r + inc * (ov % 5), c + o, abs(5 * n - ov), col, inc);
361 				if (nv != 5 * n)
362 					fixcol(r, c + n, abs(5 * n - nv), col, inc);
363 			} else {
364 				fixcol(r + inc * (nv % 5), c + n, abs(5 * n - nv), ' ', inc);
365 				if (ov != 5 * o)
366 					fixcol(r, c + o, abs(5 * o - ov), ' ', inc);
367 			}
368 			return;
369 		}
370 	}
371 	nv = abs(new);
372 	fixcol(r, c + 1, nv, new > 0 ? 'r' : 'w', inc);
373 	if (abs(old) <= abs(new))
374 		return;
375 	fixcol(r + inc * new, c + 1, abs(old + new), ' ', inc);
376 }
377 
378 void
379 fixcol(r, c, l, ch, inc)
380 	int     l, ch, r, c, inc;
381 {
382 	int     i;
383 
384 	curmove(r, c);
385 	fancyc(ch);
386 	for (i = 1; i < l; i++) {
387 		curmove(curr + inc, curc - 1);
388 		fancyc(ch);
389 	}
390 }
391 
392 void
393 curmove(r, c)
394 	int     r, c;
395 {
396 	if (curr == r && curc == c)
397 		return;
398 	if (realr == -1) {
399 		realr = curr;
400 		realc = curc;
401 	}
402 	curr = r;
403 	curc = c;
404 }
405 
406 void
407 newpos()
408 {
409 	int     r;		/* destination row */
410 	int     c;		/* destination column */
411 	int     mode = -1;	/* mode of movement */
412 
413 	int     count = 1000;	/* character count */
414 	int     i;		/* index */
415 	int     n;		/* temporary variable */
416 	char   *m;		/* string containing CM movement */
417 
418 
419 	m = NULL;
420 	if (realr == -1)	/* see if already there */
421 		return;
422 
423 	r = curr;		/* set current and dest. positions */
424 	c = curc;
425 	curr = realr;
426 	curc = realc;
427 
428 	/* double check position */
429 	if (curr == r && curc == c) {
430 		realr = realc = -1;
431 		return;
432 	}
433 	if (CM) {		/* try CM to get there */
434 		mode = 0;
435 		m = (char *) tgoto(CM, c, r);
436 		count = strlen(m);
437 	}
438 	/* try HO and local movement */
439 	if (HO && (n = r + c * lND + lHO) < count) {
440 		mode = 1;
441 		count = n;
442 	}
443 	/* try various LF combinations */
444 	if (r >= curr) {
445 		/* CR, LF, and ND */
446 		if ((n = (r - curr) + c * lND + 1) < count) {
447 			mode = 2;
448 			count = n;
449 		}
450 		/* LF, ND */
451 		if (c >= curc && (n = (r - curr) + (c - curc) * lND) < count) {
452 			mode = 3;
453 			count = n;
454 		}
455 		/* LF, BS */
456 		if (c < curc && (n = (r - curr) + (curc - c) * lBC) < count) {
457 			mode = 4;
458 			count = n;
459 		}
460 	}
461 	/* try corresponding UP combinations */
462 	if (r < curr) {
463 		/* CR, UP, and ND */
464 		if ((n = (curr - r) * lUP + c * lND + 1) < count) {
465 			mode = 5;
466 			count = n;
467 		}
468 		/* UP and ND */
469 		if (c >= curc && (n = (curr - r) * lUP + (c - curc) * lND) < count) {
470 			mode = 6;
471 			count = n;
472 		}
473 		/* UP and BS */
474 		if (c < curc && (n = (curr - r) * lUP + (curc - c) * lBC) < count) {
475 			mode = 7;
476 			count = n;
477 		}
478 	}
479 	/* space over */
480 	if (curr == r && c > curc && linect[r] < curc && c - curc < count)
481 		mode = 8;
482 
483 	switch (mode) {
484 
485 	case -1:		/* error! */
486 		write(2, "\r\nInternal cursor error.\r\n", 26);
487 		getout(0);
488 
489 		/* direct cursor motion */
490 	case 0:
491 		tputs(m, abs(curr - r), addbuf);
492 		break;
493 
494 		/* relative to "home" */
495 	case 1:
496 		tputs(HO, r, addbuf);
497 		for (i = 0; i < r; i++)
498 			addbuf('\012');
499 		for (i = 0; i < c; i++)
500 			tputs(ND, 1, addbuf);
501 		break;
502 
503 		/* CR and down and over */
504 	case 2:
505 		addbuf('\015');
506 		for (i = 0; i < r - curr; i++)
507 			addbuf('\012');
508 		for (i = 0; i < c; i++)
509 			tputs(ND, 1, addbuf);
510 		break;
511 
512 		/* down and over */
513 	case 3:
514 		for (i = 0; i < r - curr; i++)
515 			addbuf('\012');
516 		for (i = 0; i < c - curc; i++)
517 			tputs(ND, 1, addbuf);
518 		break;
519 
520 		/* down and back */
521 	case 4:
522 		for (i = 0; i < r - curr; i++)
523 			addbuf('\012');
524 		for (i = 0; i < curc - c; i++)
525 			addbuf('\010');
526 		break;
527 
528 		/* CR and up and over */
529 	case 5:
530 		addbuf('\015');
531 		for (i = 0; i < curr - r; i++)
532 			tputs(UP, 1, addbuf);
533 		for (i = 0; i < c; i++)
534 			tputs(ND, 1, addbuf);
535 		break;
536 
537 		/* up and over */
538 	case 6:
539 		for (i = 0; i < curr - r; i++)
540 			tputs(UP, 1, addbuf);
541 		for (i = 0; i < c - curc; i++)
542 			tputs(ND, 1, addbuf);
543 		break;
544 
545 		/* up and back */
546 	case 7:
547 		for (i = 0; i < curr - r; i++)
548 			tputs(UP, 1, addbuf);
549 		for (i = 0; i < curc - c; i++) {
550 			if (BC)
551 				tputs(BC, 1, addbuf);
552 			else
553 				addbuf('\010');
554 		}
555 		break;
556 
557 		/* safe space */
558 	case 8:
559 		for (i = 0; i < c - curc; i++)
560 			addbuf(' ');
561 	}
562 
563 	/* fix positions */
564 	curr = r;
565 	curc = c;
566 	realr = -1;
567 	realc = -1;
568 }
569 
570 void
571 clear()
572 {
573 	int     i;
574 
575 	/* double space if can't clear */
576 	if (CL == 0) {
577 		writel("\n\n");
578 		return;
579 	}
580 	curr = curc = 0;	/* fix position markers */
581 	realr = realc = -1;
582 	for (i = 0; i < 24; i++)/* clear line counts */
583 		linect[i] = -1;
584 	buffnum = -1;		/* ignore leftover buffer contents */
585 	tputs(CL, CO, addbuf);	/* put CL in buffer */
586 }
587 
588 void
589 fancyc(c)
590 	char    c;		/* character to output */
591 {
592 	int     sp;		/* counts spaces in a tab */
593 
594 	if (c == '\007') {	/* bells go in blindly */
595 		addbuf(c);
596 		return;
597 	}
598 	/* process tabs, use spaces if the the tab should be erasing things,
599 	 * otherwise use cursor movement routines.  Note this does not use
600 	 * hardware tabs at all. */
601 	if (c == '\t') {
602 		sp = (curc + 8) & (~7);	/* compute spaces */
603 		/* check line length */
604 		if (linect[curr] >= curc || sp < 4) {
605 			for (; sp > curc; sp--)
606 				addbuf(' ');
607 			curc = sp;	/* fix curc */
608 		} else
609 			curmove(curr, sp);
610 		return;
611 	}
612 	/* do newline be calling newline */
613 	if (c == '\n') {
614 		newline();
615 		return;
616 	}
617 	/* ignore any other control chars */
618 	if (c < ' ')
619 		return;
620 
621 	/* if an erasing space or non-space, just add it to buffer.  Otherwise
622 	 * use cursor movement routine, so that multiple spaces will be
623 	 * grouped together */
624 	if (c > ' ' || linect[curr] >= curc) {
625 		newpos();	/* make sure position correct */
626 		addbuf(c);	/* add character to buffer */
627 		/* fix line length */
628 		if (c == ' ' && linect[curr] == curc)
629 			linect[curr]--;
630 		else
631 			if (linect[curr] < curc)
632 				linect[curr] = curc;
633 		curc++;		/* fix curc */
634 	} else
635 		/* use cursor movement routine */
636 		curmove(curr, curc + 1);
637 }
638 
639 void
640 clend()
641 {
642 	int     i;
643 
644 	if (CD) {
645 		tputs(CD, CO - curr, addbuf);
646 		for (i = curr; i < LI; i++)
647 			linect[i] = -1;
648 		return;
649 	}
650 	curmove(i = curr, 0);
651 	cline();
652 	while (curr < LI - 1) {
653 		curmove(curr + 1, 0);
654 		if (linect[curr] > -1)
655 			cline();
656 	}
657 	curmove(i, 0);
658 }
659 
660 void
661 cline()
662 {
663 	int     c;
664 
665 	if (curc > linect[curr])
666 		return;
667 	newpos();
668 	if (CE) {
669 		tputs(CE, 1, addbuf);
670 		linect[curr] = curc - 1;
671 	} else {
672 		c = curc - 1;
673 		while (linect[curr] > c) {
674 			addbuf(' ');
675 			curc++;
676 			linect[curr]--;
677 		}
678 		curmove(curr, c + 1);
679 	}
680 }
681 
682 void
683 newline()
684 {
685 	cline();
686 	if (curr == LI - 1)
687 		curmove(begscr, 0);
688 	else
689 		curmove(curr + 1, 0);
690 }
691 
692 int
693 getcaps(s)
694 	const char   *s;
695 {
696 	char   *code;		/* two letter code */
697 	char ***cap;		/* pointer to cap string */
698 	char   *bufp;		/* pointer to cap buffer */
699 	char    tentry[1024];	/* temporary uncoded caps buffer */
700 
701 	tgetent(tentry, s);	/* get uncoded termcap entry */
702 
703 	LI = tgetnum("li");	/* get number of lines */
704 	if (LI == -1)
705 		LI = 12;
706 	CO = tgetnum("co");	/* get number of columns */
707 	if (CO == -1)
708 		CO = 65;
709 
710 	bufp = tbuf;		/* get padding character */
711 	tgetstr("pc", &bufp);
712 	if (bufp != tbuf)
713 		PC = *tbuf;
714 	else
715 		PC = 0;
716 
717 	bufp = tbuf;		/* get string entries */
718 	cap = tstr;
719 	for (code = tcap; *code; code += 2)
720 		**cap++ = (char *) tgetstr(code, &bufp);
721 
722 	/* get pertinent lengths */
723 	if (HO)
724 		lHO = strlen(HO);
725 	if (BC)
726 		lBC = strlen(BC);
727 	else
728 		lBC = 1;
729 	if (UP)
730 		lUP = strlen(UP);
731 	if (ND)
732 		lND = strlen(ND);
733 	if (LI < 24 || CO < 72 || !(CL && UP && ND))
734 		return (0);
735 	linect = (int *) calloc(LI + 1, sizeof(int));
736 	if (linect == NULL) {
737 		write(2, "\r\nOut of memory!\r\n", 18);
738 		getout(0);
739 	}
740 	return (1);
741 }
742