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