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