Annotation of 43BSDReno/games/worms/worms.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.