Annotation of researchv10no/games/rogue/main.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Rogue
                      3:  * Exploring the dungeons of doom
                      4:  * Copyright (C) 1980 by Michael Toy and Glenn Wichman
                      5:  * All rights reserved
                      6:  *
                      7:  * @(#)main.c  3.27 (Berkeley) 6/15/81
                      8:  */
                      9: 
                     10: #include <curses.h>
                     11: #include <signal.h>
                     12: #include <pwd.h>
                     13: #include "mach_dep.h"
                     14: #include "rogue.h"
                     15: 
                     16: #ifdef CHECKTIME
                     17: static int num_checks;         /* times we've gone over in checkout() */
                     18: #endif
                     19: 
                     20: char _sobuf[BUFSIZ];
                     21: 
                     22: main(argc, argv, envp)
                     23: char **argv;
                     24: char **envp;
                     25: {
                     26:     register char *env;
                     27:     register struct passwd *pw;
                     28:     register struct linked_list *item;
                     29:     register struct object *obj;
                     30:     struct passwd *getpwuid();
                     31:     char *getpass(), *crypt();
                     32:     int quit(), lowtime;
                     33:     long now;
                     34: 
                     35:     setbuf (stdout, _sobuf);
                     36: 
                     37:     /*
                     38:      * check for print-score option
                     39:      */
                     40:     if (argc == 2 && strcmp(argv[1], "-s") == 0)
                     41:     {
                     42:        waswizard = TRUE;
                     43:        score(0, -1);
                     44:        exit(0);
                     45:     }
                     46:     /*
                     47:      * Allow nondeterministic cheating
                     48:      */
                     49:     if (argc >= 2 && strcmp(argv[1], "-c") == 0) {
                     50:         cheating = TRUE;
                     51:         argv++;
                     52:         argc--;
                     53:     }
                     54:     /*
                     55:      * Check to see if he is a wizard
                     56:      */
                     57:     if (argc >= 2 && argv[1][0] == '\0')
                     58:        if (strcmp(PASSWD, crypt(getpass("Wizard's password: "), "C4")) == 0)
                     59:        {
                     60:            wizard = TRUE;
                     61:            argv++;
                     62:            argc--;
                     63:        }
                     64: 
                     65:     /*
                     66:      * get home and options from environment
                     67:      */
                     68:     if ((env = getenv("HOME")) != NULL)
                     69:        strcpy(home, env);
                     70:     else if ((pw = getpwuid(getuid())) != NULL)
                     71:        strcpy(home, pw->pw_dir);
                     72:     else
                     73:        home[0] = '\0';
                     74:     strcat(home, "/");
                     75: 
                     76:     strcpy(file_name, home);
                     77:     strcat(file_name, "rogue.save");
                     78: 
                     79:     if ((env = getenv("ROGUEOPTS")) != NULL)
                     80:        parse_opts(env);
                     81:     if (env == NULL || whoami[0] == '\0')
                     82:        if ((pw = getpwuid(getuid())) == NULL)
                     83:        {
                     84:            printf("Say, who the hell are you?\n");
                     85:            exit(1);
                     86:        }
                     87:        else
                     88:            strucpy(whoami, pw->pw_name, strlen(pw->pw_name));
                     89:     if (env == NULL || fruit[0] == '\0')
                     90:        strcpy(fruit, "slime-mold");
                     91: 
                     92: #if MAXLOAD|MAXUSERS
                     93:     if (too_much() && !wizard && !author())
                     94:     {
                     95:        printf("Sorry, %s, but the system is too loaded now.\n", whoami);
                     96:        printf("Try again later.  Meanwhile, why not enjoy a%s %s?\n",
                     97:            vowelstr(fruit), fruit);
                     98:        exit(1);
                     99:     }
                    100: #endif
                    101:     if (argc == 2)
                    102:        if (!restore(argv[1], envp)) /* Note: restore will never return */
                    103:            exit(1);
                    104:     time(&now);
                    105:     lowtime = (int) now;
                    106:     dnum = (wizard && getenv("SEED") != NULL ?
                    107:        atoi(getenv("SEED")) :
                    108:        lowtime + getpid());
                    109:     if (wizard)
                    110:        printf("Hello %s, welcome to dungeon #%d", whoami, dnum);
                    111:     else
                    112:        printf("Hello %s, just a moment while I dig the dungeon...", whoami);
                    113:     fflush(stdout);
                    114:     seed = dnum;
                    115: 
                    116:     init_player();                     /* Roll up the rogue */
                    117:     init_things();                     /* Set up probabilities of things */
                    118:     init_names();                      /* Set up names of scrolls */
                    119:     init_colors();                     /* Set up colors of potions */
                    120:     init_stones();                     /* Set up stone settings of rings */
                    121:     init_materials();                  /* Set up materials of wands */
                    122:     initscr();                         /* Start up cursor package */
                    123:     setup();
                    124:     /*
                    125:      * Set up windows
                    126:      */
                    127:     cw = newwin(LINES, COLS, 0, 0);
                    128:     mw = newwin(LINES, COLS, 0, 0);
                    129:     hw = newwin(LINES, COLS, 0, 0);
                    130:     waswizard = wizard;
                    131:     new_level();                       /* Draw current level */
                    132:     /*
                    133:      * Start up daemons and fuses
                    134:      */
                    135:     daemon(doctor, 0, AFTER);
                    136:     fuse(swander, 0, WANDERTIME, AFTER);
                    137:     daemon(stomach, 0, AFTER);
                    138:     daemon(runners, 0, AFTER);
                    139:     /*
                    140:      * Give the rogue his weaponry.  First a mace.
                    141:      */
                    142:     item = new_item(sizeof *obj);
                    143:     obj = (struct object *) ldata(item);
                    144:     obj->o_type = WEAPON;
                    145:     obj->o_which = MACE;
                    146:     init_weapon(obj, MACE);
                    147:     obj->o_hplus = 1;
                    148:     obj->o_dplus = 1;
                    149:     obj->o_flags |= ISKNOW;
                    150:     add_pack(item, TRUE);
                    151:     cur_weapon = obj;
                    152:     /*
                    153:      * Now a +1 bow
                    154:      */
                    155:     item = new_item(sizeof *obj);
                    156:     obj = (struct object *) ldata(item);
                    157:     obj->o_type = WEAPON;
                    158:     obj->o_which = BOW;
                    159:     init_weapon(obj, BOW);
                    160:     obj->o_hplus = 1;
                    161:     obj->o_dplus = 0;
                    162:     obj->o_flags |= ISKNOW;
                    163:     add_pack(item, TRUE);
                    164:     /*
                    165:      * Now some arrows
                    166:      */
                    167:     item = new_item(sizeof *obj);
                    168:     obj = (struct object *) ldata(item);
                    169:     obj->o_type = WEAPON;
                    170:     obj->o_which = ARROW;
                    171:     init_weapon(obj, ARROW);
                    172:     obj->o_count = 25+rnd(15);
                    173:     obj->o_hplus = obj->o_dplus = 0;
                    174:     obj->o_flags |= ISKNOW;
                    175:     add_pack(item, TRUE);
                    176:     /*
                    177:      * And his suit of armor
                    178:      */
                    179:     item = new_item(sizeof *obj);
                    180:     obj = (struct object *) ldata(item);
                    181:     obj->o_type = ARMOR;
                    182:     obj->o_which = RING_MAIL;
                    183:     obj->o_ac = a_class[RING_MAIL] - 1;
                    184:     obj->o_flags |= ISKNOW;
                    185:     cur_armor = obj;
                    186:     add_pack(item, TRUE);
                    187:     /*
                    188:      * Give him some food too
                    189:      */
                    190:     item = new_item(sizeof *obj);
                    191:     obj = (struct object *) ldata(item);
                    192:     obj->o_type = FOOD;
                    193:     obj->o_count = 1;
                    194:     obj->o_which = 0;
                    195:     add_pack(item, TRUE);
                    196:     playit();
                    197: }
                    198: 
                    199: /*
                    200:  * endit:
                    201:  *     Exit the program abnormally.
                    202:  */
                    203: 
                    204: endit()
                    205: {
                    206:     fatal("Ok, if you want to exit that badly, I'll have to allow it\n");
                    207: }
                    208: 
                    209: /*
                    210:  * fatal:
                    211:  *     Exit the program, printing a message.
                    212:  */
                    213: 
                    214: fatal(s)
                    215: char *s;
                    216: {
                    217:     clear();
                    218:     move(LINES-2, 0);
                    219:     printw("%s", s);
                    220:     draw(stdscr);
                    221:     endwin();
                    222:     exit(0);
                    223: }
                    224: 
                    225: /*
                    226:  * rnd:
                    227:  *     Pick a very random number.
                    228:  */
                    229: 
                    230: rnd(range)
                    231: register int range;
                    232: {
                    233:     return range == 0 ? 0 : abs(RN) % range;
                    234: }
                    235: 
                    236: /*
                    237:  * roll:
                    238:  *     roll a number of dice
                    239:  */
                    240: 
                    241: roll(number, sides)
                    242: register int number, sides;
                    243: {
                    244:     register int dtotal = 0;
                    245: 
                    246:     while(number--)
                    247:        dtotal += rnd(sides)+1;
                    248:     return dtotal;
                    249: }
                    250: # ifdef SIGTSTP
                    251: /*
                    252:  * handle stop and start signals
                    253:  */
                    254: tstp()
                    255: {
                    256:     mvcur(0, COLS - 1, LINES - 1, 0);
                    257:     endwin();
                    258:     fflush(stdout);
                    259:     kill(0, SIGTSTP);
                    260:     signal(SIGTSTP, tstp);
                    261:     crmode();
                    262:     noecho();
                    263:     clearok(curscr, TRUE);
                    264:     touchwin(cw);
                    265:     draw(cw);
                    266:     raw();     /* flush input */
                    267:     noraw();
                    268: }
                    269: # endif
                    270: 
                    271: setup()
                    272: {
                    273: #ifdef CHECKTIME
                    274:     int  checkout();
                    275: #endif
                    276: 
                    277: #ifndef DUMP
                    278:     signal(SIGHUP, auto_save);
                    279:     signal(SIGILL, auto_save);
                    280:     signal(SIGTRAP, auto_save);
                    281:     signal(SIGIOT, auto_save);
                    282:     signal(SIGEMT, auto_save);
                    283:     signal(SIGFPE, auto_save);
                    284:     signal(SIGBUS, auto_save);
                    285:     signal(SIGSEGV, auto_save);
                    286:     signal(SIGSYS, auto_save);
                    287:     signal(SIGPIPE, auto_save);
                    288:     signal(SIGTERM, auto_save);
                    289: #endif
                    290: 
                    291:     signal(SIGINT, quit);
                    292: #ifndef DUMP
                    293:     signal(SIGQUIT, endit);
                    294: #endif
                    295: #ifdef SIGTSTP
                    296:     signal(SIGTSTP, tstp);
                    297: #endif
                    298: #ifdef CHECKTIME
                    299:     if (!author())
                    300:     {
                    301:        signal(SIGALRM, checkout);
                    302:        alarm(CHECKTIME * 60);
                    303:        num_checks = 0;
                    304:     }
                    305: #endif
                    306:     crmode();                          /* Cbreak mode */
                    307:     noecho();                          /* Echo off */
                    308: }
                    309: 
                    310: /*
                    311:  * playit:
                    312:  *     The main loop of the program.  Loop until the game is over,
                    313:  * refreshing things and looking at the proper times.
                    314:  */
                    315: 
                    316: playit()
                    317: {
                    318:     register char *opts;
                    319: 
                    320:     /*
                    321:      * set up defaults for slow terminals
                    322:      */
                    323: 
                    324: #if    USG==1
                    325:     if ((_tty.c_cflag & CBAUD) < B1200)
                    326: #else
                    327:     if (_tty.sg_ospeed < B1200)
                    328: #endif
                    329:     {
                    330:        terse = TRUE;
                    331:        jump = TRUE;
                    332:     }
                    333: 
                    334:     /*
                    335:      * parse environment declaration of options
                    336:      */
                    337:     if ((opts = getenv("ROGUEOPTS")) != NULL)
                    338:        parse_opts(opts);
                    339: 
                    340: 
                    341:     oldpos = hero;
                    342:     oldrp = roomin(&hero);
                    343:     while (playing)
                    344:        command();                      /* Command execution */
                    345:     endit();
                    346: }
                    347: 
                    348: #if MAXLOAD|MAXUSERS
                    349: /*
                    350:  * see if the system is being used too much for this game
                    351:  */
                    352: too_much()
                    353: {
                    354: #ifdef MAXLOAD
                    355:     double avec[3];
                    356: #else
                    357:     register int cnt;
                    358: #endif
                    359: 
                    360: #ifdef MAXLOAD
                    361:     loadav(avec);
                    362:     return (avec[2] > (MAXLOAD / 10.0));
                    363: #else
                    364:     return (ucount() > MAXUSERS);
                    365: #endif
                    366: }
                    367: 
                    368: /*
                    369:  * see if a user is an author of the program
                    370:  */
                    371: author()
                    372: {
                    373:     switch (getuid())
                    374:     {
                    375:        case 24601:
                    376:            return TRUE;
                    377:        default:
                    378:            return FALSE;
                    379:     }
                    380: }
                    381: #endif
                    382: 
                    383: #ifdef CHECKTIME
                    384: checkout()
                    385: {
                    386:     static char *msgs[] = {
                    387:        "The load is too high to be playing.  Please leave in %d minutes",
                    388:        "Please save your game.  You have %d minutes",
                    389:        "Last warning.  You have %d minutes to leave",
                    390:     };
                    391:     int checktime;
                    392: 
                    393:     signal(SIGALRM, checkout);
                    394:     if (too_much())
                    395:     {
                    396:        if (num_checks == 3)
                    397:            fatal("Sorry.  You took to long.  You are dead\n");
                    398:        checktime = CHECKTIME / (num_checks + 1);
                    399:        chmsg(msgs[num_checks++], checktime);
                    400:        alarm(checktime * 60);
                    401:     }
                    402:     else
                    403:     {
                    404:        if (num_checks)
                    405:        {
                    406:            chmsg("The load has dropped back down.  You have a reprieve.");
                    407:            num_checks = 0;
                    408:        }
                    409:        alarm(CHECKTIME * 60);
                    410:     }
                    411: }
                    412: 
                    413: /*
                    414:  * checkout()'s version of msg.  If we are in the middle of a shell, do a
                    415:  * printf instead of a msg to avoid the refresh.
                    416:  */
                    417: chmsg(fmt, arg)
                    418: char *fmt;
                    419: int arg;
                    420: {
                    421:     if (in_shell)
                    422:     {
                    423:        printf(fmt, arg);
                    424:        putchar('\n');
                    425:        fflush(stdout);
                    426:     }
                    427:     else
                    428:        msg(fmt, arg);
                    429: }
                    430: #endif
                    431: 
                    432: #ifdef LOADAV
                    433: 
                    434: #include <nlist.h>
                    435: 
                    436: struct nlist avenrun =
                    437: {
                    438:     "_avenrun"
                    439: };
                    440: 
                    441: loadav(avg)
                    442: register double *avg;
                    443: {
                    444:     register int kmem;
                    445: 
                    446:     if ((kmem = open("/dev/kmem", 0)) < 0)
                    447:        goto bad;
                    448:     nlist(NAMELIST, &avenrun);
                    449:     if (avenrun.n_type == 0)
                    450:     {
                    451: bad:
                    452:        avg[0] = avg[1] = avg[2] = 0.0;
                    453:        return;
                    454:     }
                    455: 
                    456:     lseek(kmem, (long) avenrun.n_value, 0);
                    457:     read(kmem, avg, 3 * sizeof (double));
                    458: }
                    459: #endif
                    460: 
                    461: #ifdef UCOUNT
                    462: 
                    463: #include <utmp.h>
                    464: 
                    465: struct utmp buf;
                    466: 
                    467: ucount()
                    468: {
                    469:     register struct utmp *up;
                    470:     register FILE *utmp;
                    471:     register int count;
                    472: 
                    473:     if ((utmp = fopen(UTMP, "r")) == NULL)
                    474:        return 0;
                    475: 
                    476:     up = &buf;
                    477:     count = 0;
                    478: 
                    479:     while (fread(up, 1, sizeof (*up), utmp) > 0)
                    480:        if (buf.ut_name[0] != '\0')
                    481:            count++;
                    482:     fclose(utmp);
                    483:     return count;
                    484: }
                    485: #endif

unix.superglobalmegacorp.com

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