1: #ifndef lint 2: char copyright[] = 3: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 4: All rights reserved.\n"; 5: #endif not lint 6: 7: #ifndef lint 8: static char sccsid[] = "@(#)worms.c 5.3 (Berkeley) 7/15/85"; 9: #endif not lint 10: 11: #define BSD 12: 13: /* 14: 15: @@@ @@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@ 16: @@@ @@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@ 17: @@@ @@@ @@@@ @@@@ @@@@ @@@@ @@@ @@@@ 18: @@@ @@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ 19: @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ 20: @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ 21: @@@@@@@@@@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ 22: @@@@ @@@@ @@@@@@@@@@@@ @@@ @@@ @@@ @@@ 23: @@ @@ @@@@@@@@@@ @@@ @@@ @@@ @@@ 24: 25: Eric P. Scott 26: Caltech High Energy Physics 27: October, 1980 28: 29: */ 30: #include <stdio.h> 31: #ifdef USG 32: #include <termio.h> 33: #else 34: #include <sgtty.h> 35: #endif 36: #include <signal.h> 37: int fputchar(); 38: #define cursor(col,row) tputs(tgoto(CM,col,row),1,fputchar) 39: extern char *UP; 40: extern short ospeed; 41: int Wrap; 42: short *ref[24]; 43: static char flavor[]={ 44: 'O', '*', '#', '$', '%', '0' 45: }; 46: static short xinc[]={ 47: 1, 1, 1, 0, -1, -1, -1, 0 48: }, yinc[]={ 49: -1, 0, 1, 1, 1, 0, -1, -1 50: }; 51: static struct worm { 52: int orientation, head; 53: short *xpos, *ypos; 54: } worm[40]; 55: static char *field; 56: static int length=16, number=3, trail=' '; 57: static struct options { 58: int nopts; 59: int opts[3]; 60: } normal[8]={ 61: { 3, { 7, 0, 1 } }, 62: { 3, { 0, 1, 2 } }, 63: { 3, { 1, 2, 3 } }, 64: { 3, { 2, 3, 4 } }, 65: { 3, { 3, 4, 5 } }, 66: { 3, { 4, 5, 6 } }, 67: { 3, { 5, 6, 7 } }, 68: { 3, { 6, 7, 0 } } 69: }, upper[8]={ 70: { 1, { 1, 0, 0 } }, 71: { 2, { 1, 2, 0 } }, 72: { 0, { 0, 0, 0 } }, 73: { 0, { 0, 0, 0 } }, 74: { 0, { 0, 0, 0 } }, 75: { 2, { 4, 5, 0 } }, 76: { 1, { 5, 0, 0 } }, 77: { 2, { 1, 5, 0 } } 78: }, left[8]={ 79: { 0, { 0, 0, 0 } }, 80: { 0, { 0, 0, 0 } }, 81: { 0, { 0, 0, 0 } }, 82: { 2, { 2, 3, 0 } }, 83: { 1, { 3, 0, 0 } }, 84: { 2, { 3, 7, 0 } }, 85: { 1, { 7, 0, 0 } }, 86: { 2, { 7, 0, 0 } } 87: }, right[8]={ 88: { 1, { 7, 0, 0 } }, 89: { 2, { 3, 7, 0 } }, 90: { 1, { 3, 0, 0 } }, 91: { 2, { 3, 4, 0 } }, 92: { 0, { 0, 0, 0 } }, 93: { 0, { 0, 0, 0 } }, 94: { 0, { 0, 0, 0 } }, 95: { 2, { 6, 7, 0 } } 96: }, lower[8]={ 97: { 0, { 0, 0, 0 } }, 98: { 2, { 0, 1, 0 } }, 99: { 1, { 1, 0, 0 } }, 100: { 2, { 1, 5, 0 } }, 101: { 1, { 5, 0, 0 } }, 102: { 2, { 5, 6, 0 } }, 103: { 0, { 0, 0, 0 } }, 104: { 0, { 0, 0, 0 } } 105: }, upleft[8]={ 106: { 0, { 0, 0, 0 } }, 107: { 0, { 0, 0, 0 } }, 108: { 0, { 0, 0, 0 } }, 109: { 0, { 0, 0, 0 } }, 110: { 0, { 0, 0, 0 } }, 111: { 1, { 3, 0, 0 } }, 112: { 2, { 1, 3, 0 } }, 113: { 1, { 1, 0, 0 } } 114: }, upright[8]={ 115: { 2, { 3, 5, 0 } }, 116: { 1, { 3, 0, 0 } }, 117: { 0, { 0, 0, 0 } }, 118: { 0, { 0, 0, 0 } }, 119: { 0, { 0, 0, 0 } }, 120: { 0, { 0, 0, 0 } }, 121: { 0, { 0, 0, 0 } }, 122: { 1, { 5, 0, 0 } } 123: }, lowleft[8]={ 124: { 3, { 7, 0, 1 } }, 125: { 0, { 0, 0, 0 } }, 126: { 0, { 0, 0, 0 } }, 127: { 1, { 1, 0, 0 } }, 128: { 2, { 1, 7, 0 } }, 129: { 1, { 7, 0, 0 } }, 130: { 0, { 0, 0, 0 } }, 131: { 0, { 0, 0, 0 } } 132: }, lowright[8]={ 133: { 0, { 0, 0, 0 } }, 134: { 1, { 7, 0, 0 } }, 135: { 2, { 5, 7, 0 } }, 136: { 1, { 5, 0, 0 } }, 137: { 0, { 0, 0, 0 } }, 138: { 0, { 0, 0, 0 } }, 139: { 0, { 0, 0, 0 } }, 140: { 0, { 0, 0, 0 } } 141: }; 142: char *TE; 143: main(argc,argv) 144: int argc; 145: char *argv[]; 146: { 147: char *malloc(); 148: char *getenv(); 149: char *tgetstr(), *tgoto(); 150: int quit(); 151: float ranf(); 152: register int x, y; 153: register int n; 154: register struct worm *w; 155: register struct options *op; 156: register int h; 157: register short *ip; 158: char *AL, *BC, *CM, *EI, *HO, *IC, *IM, *IP, *SR; 159: int CO, IN, LI, last, bottom; 160: char *tcp; 161: register char *term; 162: char tcb[100]; 163: #ifdef USG 164: struct termio sg; 165: #else 166: struct sgttyb sg; 167: #endif 168: setbuf(stdout,malloc(BUFSIZ)); 169: for (x=1;x<argc;x++) { 170: register char *p; 171: p=argv[x]; 172: if (*p=='-') p++; 173: switch (*p) { 174: case 'f': 175: field="WORM"; 176: break; 177: case 'l': 178: if (++x==argc) goto usage; 179: if ((length=atoi(argv[x]))<2||length>1024) { 180: fprintf(stderr,"%s: Invalid length\n",*argv); 181: exit(1); 182: } 183: break; 184: case 'n': 185: if (++x==argc) goto usage; 186: if ((number=atoi(argv[x]))<1||number>40) { 187: fprintf(stderr,"%s: Invalid number of worms\n",*argv); 188: exit(1); 189: } 190: break; 191: case 't': 192: trail='.'; 193: break; 194: default: 195: usage: 196: fprintf(stderr, 197: "usage: %s [-field] [-length #] [-number #] [-trail]\n",*argv); 198: exit(1); 199: break; 200: } 201: } 202: if (!(term=getenv("TERM"))) { 203: fprintf(stderr,"%s: TERM: parameter not set\n",*argv); 204: exit(1); 205: } 206: if (tgetent(malloc(1024),term)<=0) { 207: fprintf(stderr,"%s: %s: unknown terminal type\n",*argv,term); 208: exit(1); 209: } 210: tcp=tcb; 211: if (!(CM=tgetstr("cm",&tcp))) { 212: fprintf(stderr,"%s: terminal not capable of cursor motion\n",*argv); 213: exit(1); 214: } 215: AL=tgetstr("al",&tcp); 216: BC=tgetflag("bs") ? "\b" : tgetstr("bc",&tcp); 217: if ((CO=tgetnum("co"))<=0) CO=80; 218: last=CO-1; 219: EI=tgetstr("ei",&tcp); 220: HO=tgetstr("ho",&tcp); 221: IC=tgetstr("ic",&tcp); 222: IM=tgetstr("im",&tcp); 223: IN=tgetflag("in"); 224: IP=tgetstr("ip",&tcp); 225: if ((LI=tgetnum("li"))<=0) LI=24; 226: bottom=LI-1; 227: SR=tgetstr("sr",&tcp); 228: TE=tgetstr("te",&tcp); 229: UP=tgetstr("up",&tcp); 230: #ifdef USG 231: ioctl(fileno(stdout),TCGETA,&sg); 232: ospeed=sg.c_cflag&CBAUD; 233: #else 234: gtty(fileno(stdout),&sg); 235: ospeed=sg.sg_ospeed; 236: #endif 237: Wrap=tgetflag("am"); 238: ip=(short *)malloc(LI*CO*sizeof (short)); 239: for (n=0;n<LI;) { 240: ref[n++]=ip; ip+=CO; 241: } 242: for (ip=ref[0],n=LI*CO;--n>=0;) *ip++=0; 243: if (Wrap) ref[bottom][last]=1; 244: for (n=number, w= &worm[0];--n>=0;w++) { 245: w->orientation=w->head=0; 246: if (!(ip=(short *)malloc(length*sizeof (short)))) { 247: fprintf(stderr,"%s: out of memory\n",*argv); 248: exit(1); 249: } 250: w->xpos=ip; 251: for (x=length;--x>=0;) *ip++ = -1; 252: if (!(ip=(short *)malloc(length*sizeof (short)))) { 253: fprintf(stderr,"%s: out of memory\n",*argv); 254: exit(1); 255: } 256: w->ypos=ip; 257: for (y=length;--y>=0;) *ip++ = -1; 258: } 259: signal(SIGINT, quit); 260: tputs(tgetstr("ti",&tcp),1,fputchar); 261: tputs(tgetstr("cl",&tcp),1,fputchar); 262: if (field) { 263: register char *p; 264: p=field; 265: for (y=bottom;--y>=0;) { 266: for (x=CO;--x>=0;) { 267: putchar(*p++); 268: if (!*p) p=field; 269: } 270: if (!Wrap) putchar('\n'); 271: fflush(stdout); 272: } 273: if (Wrap) { 274: if (IM&&!IN) { 275: for (x=last;--x>0;) { 276: putchar(*p++); 277: if (!*p) p=field; 278: } 279: y= *p++; if (!*p) p=field; 280: putchar(*p); 281: if (BC) tputs(BC,1,fputchar); 282: else cursor(last-1,bottom); 283: tputs(IM,1,fputchar); 284: if (IC) tputs(IC,1,fputchar); 285: putchar(y); 286: if (IP) tputs(IP,1,fputchar); 287: tputs(EI,1,fputchar); 288: } 289: else if (SR||AL) { 290: if (HO) tputs(HO,1,fputchar); 291: else cursor(0,0); 292: if (SR) tputs(SR,1,fputchar); 293: else tputs(AL,LI,fputchar); 294: for (x=CO;--x>=0;) { 295: putchar(*p++); 296: if (!*p) p=field; 297: } 298: } 299: else for (x=last;--x>=0;) { 300: putchar(*p++); 301: if (!*p) p=field; 302: } 303: } 304: else for (x=CO;--x>=0;) { 305: putchar(*p++); 306: if (!*p) p=field; 307: } 308: } 309: fflush(stdout); 310: for (;;) { 311: for (n=0,w= &worm[0];n<number;n++,w++) { 312: if ((x=w->xpos[h=w->head])<0) { 313: cursor(x=w->xpos[h]=0,y=w->ypos[h]=bottom); 314: putchar(flavor[n%6]); 315: ref[y][x]++; 316: } 317: else y=w->ypos[h]; 318: if (++h==length) h=0; 319: if (w->xpos[w->head=h]>=0) { 320: register int x1, y1; 321: x1=w->xpos[h]; y1=w->ypos[h]; 322: if (--ref[y1][x1]==0) { 323: cursor(x1,y1); putchar(trail); 324: } 325: } 326: op= &(x==0 ? (y==0 ? upleft : (y==bottom ? lowleft : left)) : 327: (x==last ? (y==0 ? upright : (y==bottom ? lowright : right)) : 328: (y==0 ? upper : (y==bottom ? lower : normal))))[w->orientation]; 329: switch (op->nopts) { 330: case 0: 331: fflush(stdout); 332: abort(); 333: return; 334: case 1: 335: w->orientation=op->opts[0]; 336: break; 337: default: 338: w->orientation=op->opts[(int)(ranf()*(float)op->nopts)]; 339: } 340: cursor(x+=xinc[w->orientation], y+=yinc[w->orientation]); 341: if (!Wrap||x!=last||y!=bottom) putchar(flavor[n%6]); 342: ref[w->ypos[h]=y][w->xpos[h]=x]++; 343: } 344: fflush(stdout); 345: } 346: } 347: quit() 348: { 349: signal(SIGINT, SIG_IGN); 350: tputs(TE,1,fputchar); 351: exit(0); 352: } 353: fputchar(c) 354: char c; 355: { 356: putchar(c); 357: } 358: float ranf() { 359: #if defined(BSD) && !defined(pdp11) 360: return((float)rand()/2147483647.); 361: #else 362: return((float)rand()/32767.); 363: #endif 364: }