|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)worms.c 5.8 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: /* ! 31: * ! 32: * @@@ @@@ @@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@ ! 33: * @@@ @@@ @@@@@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@@@ ! 34: * @@@ @@@ @@@@ @@@@ @@@@ @@@@ @@@ @@@@ ! 35: * @@@ @@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ ! 36: * @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@ ! 37: * @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ ! 38: * @@@@@@@@@@@@ @@@@ @@@@ @@@ @@@ @@@ @@@ ! 39: * @@@@ @@@@ @@@@@@@@@@@@ @@@ @@@ @@@ @@@ ! 40: * @@ @@ @@@@@@@@@@ @@@ @@@ @@@ @@@ ! 41: * ! 42: * Eric P. Scott ! 43: * Caltech High Energy Physics ! 44: * October, 1980 ! 45: * ! 46: */ ! 47: #include <sys/types.h> ! 48: #include <stdio.h> ! 49: #ifdef USG ! 50: #include <termio.h> ! 51: #else ! 52: #include <sgtty.h> ! 53: #endif ! 54: #include <signal.h> ! 55: ! 56: static struct options { ! 57: int nopts; ! 58: int opts[3]; ! 59: } ! 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: }, ! 79: left[8] = { ! 80: { 0, { 0, 0, 0 } }, ! 81: { 0, { 0, 0, 0 } }, ! 82: { 0, { 0, 0, 0 } }, ! 83: { 2, { 2, 3, 0 } }, ! 84: { 1, { 3, 0, 0 } }, ! 85: { 2, { 3, 7, 0 } }, ! 86: { 1, { 7, 0, 0 } }, ! 87: { 2, { 7, 0, 0 } } ! 88: }, ! 89: right[8] = { ! 90: { 1, { 7, 0, 0 } }, ! 91: { 2, { 3, 7, 0 } }, ! 92: { 1, { 3, 0, 0 } }, ! 93: { 2, { 3, 4, 0 } }, ! 94: { 0, { 0, 0, 0 } }, ! 95: { 0, { 0, 0, 0 } }, ! 96: { 0, { 0, 0, 0 } }, ! 97: { 2, { 6, 7, 0 } } ! 98: }, ! 99: lower[8] = { ! 100: { 0, { 0, 0, 0 } }, ! 101: { 2, { 0, 1, 0 } }, ! 102: { 1, { 1, 0, 0 } }, ! 103: { 2, { 1, 5, 0 } }, ! 104: { 1, { 5, 0, 0 } }, ! 105: { 2, { 5, 6, 0 } }, ! 106: { 0, { 0, 0, 0 } }, ! 107: { 0, { 0, 0, 0 } } ! 108: }, ! 109: upleft[8] = { ! 110: { 0, { 0, 0, 0 } }, ! 111: { 0, { 0, 0, 0 } }, ! 112: { 0, { 0, 0, 0 } }, ! 113: { 0, { 0, 0, 0 } }, ! 114: { 0, { 0, 0, 0 } }, ! 115: { 1, { 3, 0, 0 } }, ! 116: { 2, { 1, 3, 0 } }, ! 117: { 1, { 1, 0, 0 } } ! 118: }, ! 119: upright[8] = { ! 120: { 2, { 3, 5, 0 } }, ! 121: { 1, { 3, 0, 0 } }, ! 122: { 0, { 0, 0, 0 } }, ! 123: { 0, { 0, 0, 0 } }, ! 124: { 0, { 0, 0, 0 } }, ! 125: { 0, { 0, 0, 0 } }, ! 126: { 0, { 0, 0, 0 } }, ! 127: { 1, { 5, 0, 0 } } ! 128: }, ! 129: lowleft[8] = { ! 130: { 3, { 7, 0, 1 } }, ! 131: { 0, { 0, 0, 0 } }, ! 132: { 0, { 0, 0, 0 } }, ! 133: { 1, { 1, 0, 0 } }, ! 134: { 2, { 1, 7, 0 } }, ! 135: { 1, { 7, 0, 0 } }, ! 136: { 0, { 0, 0, 0 } }, ! 137: { 0, { 0, 0, 0 } } ! 138: }, ! 139: lowright[8] = { ! 140: { 0, { 0, 0, 0 } }, ! 141: { 1, { 7, 0, 0 } }, ! 142: { 2, { 5, 7, 0 } }, ! 143: { 1, { 5, 0, 0 } }, ! 144: { 0, { 0, 0, 0 } }, ! 145: { 0, { 0, 0, 0 } }, ! 146: { 0, { 0, 0, 0 } }, ! 147: { 0, { 0, 0, 0 } } ! 148: }; ! 149: ! 150: #define cursor(c, r) tputs(tgoto(CM, c, r), 1, fputchar) ! 151: ! 152: char *tcp; ! 153: int fputchar(); ! 154: ! 155: static char flavor[] = { ! 156: 'O', '*', '#', '$', '%', '0', '@', '~' ! 157: }; ! 158: static short xinc[] = { ! 159: 1, 1, 1, 0, -1, -1, -1, 0 ! 160: }, yinc[] = { ! 161: -1, 0, 1, 1, 1, 0, -1, -1 ! 162: }; ! 163: static struct worm { ! 164: int orientation, head; ! 165: short *xpos, *ypos; ! 166: } *worm; ! 167: ! 168: main(argc, argv) ! 169: int argc; ! 170: char **argv; ! 171: { ! 172: extern int optind; ! 173: extern short ospeed; ! 174: extern char *optarg, *UP; ! 175: register int x, y, h, n; ! 176: register struct worm *w; ! 177: register struct options *op; ! 178: register short *ip; ! 179: register char *term; ! 180: int CO, IN, LI, last, bottom, ch, length, number, trail, Wrap; ! 181: int onsig(); ! 182: short **ref; ! 183: char *AL, *BC, *CM, *EI, *HO, *IC, *IM, *IP, *SR; ! 184: char *field, tcb[100], *mp, *malloc(), *getenv(), *tgetstr(), *tgoto(); ! 185: long random(); ! 186: #ifdef USG ! 187: struct termio sg; ! 188: #else ! 189: struct sgttyb sg; ! 190: #endif ! 191: ! 192: length = 16; ! 193: number = 3; ! 194: trail = ' '; ! 195: field = NULL; ! 196: while ((ch = getopt(argc, argv, "fl:n:t")) != EOF) ! 197: switch(ch) { ! 198: case 'f': ! 199: field = "WORM"; ! 200: break; ! 201: case 'l': ! 202: if ((length = atoi(optarg)) < 2 || length > 1024) { ! 203: (void)fprintf(stderr, ! 204: "worms: invalid length (%d - %d).\n", ! 205: 2, 1024); ! 206: exit(1); ! 207: } ! 208: break; ! 209: case 'n': ! 210: if ((number = atoi(optarg)) < 1) { ! 211: (void)fprintf(stderr, ! 212: "worms: invalid number of worms.\n"); ! 213: exit(1); ! 214: } ! 215: break; ! 216: case 't': ! 217: trail = '.'; ! 218: break; ! 219: case '?': ! 220: default: ! 221: (void)fprintf(stderr, ! 222: "usage: worms [-ft] [-length #] [-number #]\n"); ! 223: exit(1); ! 224: } ! 225: ! 226: if (!(term = getenv("TERM"))) { ! 227: (void)fprintf(stderr, "worms: no TERM environment variable.\n"); ! 228: exit(1); ! 229: } ! 230: if (!(worm = (struct worm *)malloc((u_int)number * ! 231: sizeof(struct worm))) || !(mp = malloc((u_int)1024))) ! 232: nomem(); ! 233: if (tgetent(mp, term) <= 0) { ! 234: (void)fprintf(stderr, "worms: %s: unknown terminal type.\n", ! 235: term); ! 236: exit(1); ! 237: } ! 238: tcp = tcb; ! 239: if (!(CM = tgetstr("cm", &tcp))) { ! 240: (void)fprintf(stderr, ! 241: "worms: terminal incapable of cursor motion.\n"); ! 242: exit(1); ! 243: } ! 244: AL = tgetstr("al", &tcp); ! 245: BC = tgetflag("bs") ? "\b" : tgetstr("bc", &tcp); ! 246: if ((CO = tgetnum("co")) <= 0) ! 247: CO = 80; ! 248: last = CO - 1; ! 249: EI = tgetstr("ei", &tcp); ! 250: HO = tgetstr("ho", &tcp); ! 251: IC = tgetstr("ic", &tcp); ! 252: IM = tgetstr("im", &tcp); ! 253: IN = tgetflag("in"); ! 254: IP = tgetstr("ip", &tcp); ! 255: if ((LI = tgetnum("li")) <= 0) ! 256: LI = 24; ! 257: bottom = LI - 1; ! 258: SR = tgetstr("sr", &tcp); ! 259: UP = tgetstr("up", &tcp); ! 260: #ifdef USG ! 261: ioctl(1, TCGETA, &sg); ! 262: ospeed = sg.c_cflag&CBAUD; ! 263: #else ! 264: gtty(1, &sg); ! 265: ospeed = sg.sg_ospeed; ! 266: #endif ! 267: Wrap = tgetflag("am"); ! 268: if (!(ip = (short *)malloc((u_int)(LI * CO * sizeof(short))))) ! 269: nomem(); ! 270: if (!(ref = (short **)malloc((u_int)(LI * sizeof(short *))))) ! 271: nomem(); ! 272: for (n = 0; n < LI; ++n) { ! 273: ref[n] = ip; ! 274: ip += CO; ! 275: } ! 276: for (ip = ref[0], n = LI * CO; --n >= 0;) ! 277: *ip++ = 0; ! 278: if (Wrap) ! 279: ref[bottom][last] = 1; ! 280: for (n = number, w = &worm[0]; --n >= 0; w++) { ! 281: w->orientation = w->head = 0; ! 282: if (!(ip = (short *)malloc((u_int)(length * sizeof(short))))) ! 283: nomem(); ! 284: w->xpos = ip; ! 285: for (x = length; --x >= 0;) ! 286: *ip++ = -1; ! 287: if (!(ip = (short *)malloc((u_int)(length * sizeof(short))))) ! 288: nomem(); ! 289: w->ypos = ip; ! 290: for (y = length; --y >= 0;) ! 291: *ip++ = -1; ! 292: } ! 293: ! 294: (void)signal(SIGHUP, onsig); ! 295: (void)signal(SIGINT, onsig); ! 296: (void)signal(SIGQUIT, onsig); ! 297: (void)signal(SIGSTOP, onsig); ! 298: (void)signal(SIGTSTP, onsig); ! 299: (void)signal(SIGTERM, onsig); ! 300: ! 301: tputs(tgetstr("ti", &tcp), 1, fputchar); ! 302: tputs(tgetstr("cl", &tcp), 1, fputchar); ! 303: if (field) { ! 304: register char *p = field; ! 305: ! 306: for (y = bottom; --y >= 0;) { ! 307: for (x = CO; --x >= 0;) { ! 308: fputchar(*p++); ! 309: if (!*p) ! 310: p = field; ! 311: } ! 312: if (!Wrap) ! 313: fputchar('\n'); ! 314: (void)fflush(stdout); ! 315: } ! 316: if (Wrap) { ! 317: if (IM && !IN) { ! 318: for (x = last; --x > 0;) { ! 319: fputchar(*p++); ! 320: if (!*p) ! 321: p = field; ! 322: } ! 323: y = *p++; ! 324: if (!*p) ! 325: p = field; ! 326: fputchar(*p); ! 327: if (BC) ! 328: tputs(BC, 1, fputchar); ! 329: else ! 330: cursor(last - 1, bottom); ! 331: tputs(IM, 1, fputchar); ! 332: if (IC) ! 333: tputs(IC, 1, fputchar); ! 334: fputchar(y); ! 335: if (IP) ! 336: tputs(IP, 1, fputchar); ! 337: tputs(EI, 1, fputchar); ! 338: } ! 339: else if (SR || AL) { ! 340: if (HO) ! 341: tputs(HO, 1, fputchar); ! 342: else ! 343: cursor(0, 0); ! 344: if (SR) ! 345: tputs(SR, 1, fputchar); ! 346: else ! 347: tputs(AL, LI, fputchar); ! 348: for (x = CO; --x >= 0;) { ! 349: fputchar(*p++); ! 350: if (!*p) ! 351: p = field; ! 352: } ! 353: } ! 354: else for (x = last; --x >= 0;) { ! 355: fputchar(*p++); ! 356: if (!*p) ! 357: p = field; ! 358: } ! 359: } ! 360: else for (x = CO; --x >= 0;) { ! 361: fputchar(*p++); ! 362: if (!*p) ! 363: p = field; ! 364: } ! 365: } ! 366: for (;;) { ! 367: (void)fflush(stdout); ! 368: for (n = 0, w = &worm[0]; n < number; n++, w++) { ! 369: if ((x = w->xpos[h = w->head]) < 0) { ! 370: cursor(x = w->xpos[h] = 0, ! 371: y = w->ypos[h] = bottom); ! 372: fputchar(flavor[n % sizeof(flavor)]); ! 373: ref[y][x]++; ! 374: } ! 375: else ! 376: y = w->ypos[h]; ! 377: if (++h == length) ! 378: h = 0; ! 379: if (w->xpos[w->head = h] >= 0) { ! 380: register int x1, y1; ! 381: ! 382: x1 = w->xpos[h]; ! 383: y1 = w->ypos[h]; ! 384: if (--ref[y1][x1] == 0) { ! 385: cursor(x1, y1); ! 386: if (trail) ! 387: fputchar(trail); ! 388: } ! 389: } ! 390: op = &(!x ? (!y ? upleft : (y == bottom ? lowleft : left)) : (x == last ? (!y ? upright : (y == bottom ? lowright : right)) : (!y ? upper : (y == bottom ? lower : normal))))[w->orientation]; ! 391: switch (op->nopts) { ! 392: case 0: ! 393: (void)fflush(stdout); ! 394: abort(); ! 395: return; ! 396: case 1: ! 397: w->orientation = op->opts[0]; ! 398: break; ! 399: default: ! 400: w->orientation = ! 401: op->opts[(int)random() % op->nopts]; ! 402: } ! 403: cursor(x += xinc[w->orientation], ! 404: y += yinc[w->orientation]); ! 405: if (!Wrap || x != last || y != bottom) ! 406: fputchar(flavor[n % sizeof(flavor)]); ! 407: ref[w->ypos[h] = y][w->xpos[h] = x]++; ! 408: } ! 409: } ! 410: } ! 411: ! 412: onsig() ! 413: { ! 414: tputs(tgetstr("cl", &tcp), 1, fputchar); ! 415: tputs(tgetstr("te", &tcp), 1, fputchar); ! 416: exit(0); ! 417: } ! 418: ! 419: fputchar(c) ! 420: char c; ! 421: { ! 422: putchar(c); ! 423: } ! 424: ! 425: nomem() ! 426: { ! 427: (void)fprintf(stderr, "worms: not enough memory.\n"); ! 428: exit(1); ! 429: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.