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