|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.