Annotation of early-roguelike/srogue/main.c, Revision 1.1
1.1 ! rubenllo 1: /*
! 2: * Rogue
! 3: * Exploring the dungeons of doom
! 4: *
! 5: * @(#)main.c 9.0 (rdk) 7/17/84
! 6: *
! 7: * Super-Rogue
! 8: * Copyright (C) 1984 Robert D. Kindelberger
! 9: * All rights reserved.
! 10: *
! 11: * Based on "Rogue: Exploring the Dungeons of Doom"
! 12: * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
! 13: * All rights reserved.
! 14: *
! 15: * See the file LICENSE.TXT for full copyright and licensing information.
! 16: */
! 17:
! 18: #include <stdlib.h>
! 19: #include <string.h>
! 20: #include <time.h>
! 21: #include <fcntl.h>
! 22: #include <stdio.h>
! 23: #include <limits.h>
! 24: #include <errno.h>
! 25: #include <sys/stat.h>
! 26: #include "rogue.h"
! 27:
! 28: #ifdef ATT
! 29: #include <time.h>
! 30: #endif
! 31:
! 32: #ifdef BSD
! 33: #include <sys/time.h>
! 34: #endif
! 35:
! 36: #include "rogue.ext"
! 37:
! 38: char *roguehome(void);
! 39: void open_records(void);
! 40:
! 41: extern FILE *scoreboard;
! 42: extern FILE *logfile;
! 43:
! 44: int
! 45: main(int argc, char *argv[], char *envp[])
! 46: {
! 47: register char *env;
! 48: register struct linked_list *item;
! 49: register struct object *obj;
! 50: char alldone;
! 51: int wpt;
! 52: char *getpass(), *xcrypt(), *strrchr();
! 53: char *homedir = roguehome();
! 54:
! 55: md_init();
! 56:
! 57: if (homedir == NULL)
! 58: homedir = "";
! 59:
! 60: playuid = md_getuid();
! 61: playgid = md_getgid();
! 62:
! 63: /* check for print-score option */
! 64: #ifdef SCOREFILE
! 65: strncpy(scorefile, SCOREFILE, LINLEN);
! 66: scorefile[LINLEN - 1] = '\0';
! 67: #else
! 68:
! 69: strncpy(scorefile, homedir, LINLEN-11);
! 70: if (scorefile[LINLEN-12] != '\0')
! 71: scorefile[0] = '\0';
! 72:
! 73: if (*scorefile)
! 74: strcat(scorefile,"/");
! 75: strcat(scorefile, "srogue.scr");
! 76: #endif
! 77: open_records();
! 78:
! 79: if(argc >= 2 && strcmp(argv[1], "-s") == 0)
! 80: {
! 81: showtop(0);
! 82: exit(0);
! 83: }
! 84:
! 85: #ifdef WIZARD
! 86: if (argc >= 2 && author() && strcmp(argv[1],"-a") == 0)
! 87: {
! 88: wizard = TRUE;
! 89: argv++;
! 90: argc--;
! 91: }
! 92:
! 93: /* Check to see if he is a wizard */
! 94:
! 95: if (argc >= 2 && strcmp(argv[1],"-w") == 0)
! 96: {
! 97: if (strcmp(PASSWD, xcrypt(getpass(wizstr),"mT")) == 0)
! 98: {
! 99: wizard = TRUE;
! 100: argv++;
! 101: argc--;
! 102: }
! 103: }
! 104: #endif
! 105:
! 106: #ifdef SAVEDIR
! 107: if (argc >= 3 && !strcmp(argv[1], "-n")) {
! 108: strncpy(whoami, argv[2], LINLEN);
! 109: whoami[LINLEN - 1] = '\0';
! 110: use_savedir = TRUE;
! 111: if (snprintf(file_name, 256, "%s/%d-%s.srsav", SAVEDIR,
! 112: playuid, whoami) >= 256) {
! 113: /* Just in case it doesn't fit */
! 114: strcpy(file_name, "srogue.save");
! 115: use_savedir = FALSE;
! 116: }
! 117: }
! 118: #endif
! 119:
! 120: if (!use_savedir)
! 121: md_normaluser();
! 122:
! 123: /* get home and options from environment */
! 124:
! 125: if ((env = getenv("HOME")) != NULL)
! 126: strcpy(home, env);
! 127: else {
! 128: strncpy(home, md_gethomedir(), LINLEN);
! 129: if (home[LINLEN-1] != '\0')
! 130: home[0] = '\0';
! 131: }
! 132:
! 133: if (strcmp(home,"/") == 0)
! 134: home[0] = '\0';
! 135:
! 136: if ((strlen(home) > 0) && (home[strlen(home)-1] != '/'))
! 137: strcat(home, "/");
! 138:
! 139: if (!use_savedir) {
! 140: strcpy(file_name, home);
! 141: strcat(file_name, "srogue.sav");
! 142: }
! 143:
! 144: if ((env = getenv("ROGUEOPTS")) != NULL)
! 145: parse_opts(env);
! 146:
! 147: if (!use_savedir && (env == NULL || whoami[0] == '\0'))
! 148: {
! 149: strucpy(whoami, md_getusername(), strlen(md_getusername()));
! 150: }
! 151:
! 152: if (env == NULL || fruit[0] == '\0')
! 153: strcpy(fruit, "juicy-fruit");
! 154:
! 155: if (use_savedir)
! 156: {
! 157: /* restore() won't return if the restore succeeded. If
! 158: * file_name doesn't exist, it will return TRUE. In that
! 159: * case, start a new game. */
! 160: if (!restore(file_name, envp))
! 161: exit(1);
! 162: }
! 163: else if (argc == 2)
! 164: if(!restore(argv[1], envp)) /* NOTE: NEVER RETURNS */
! 165: exit(1);
! 166:
! 167: /* START NEW GAME */
! 168:
! 169: dnum = (wizard && getenv("SEED") != NULL ?
! 170: atoi(getenv("SEED")) : md_random_seed());
! 171:
! 172: if(wizard)
! 173: printf("Hello %s, welcome to dungeon #%d\n", whoami, dnum);
! 174: else
! 175: printf("Hello %s, One moment while I open the door to the dungeon...\n", whoami);
! 176:
! 177: fflush(stdout);
! 178: seed = dnum;
! 179: md_srandom(seed); /* init rnd number gen */
! 180:
! 181: md_onsignal_exit(); /* just in case */
! 182:
! 183: init_everything();
! 184:
! 185: #ifdef __INTERIX
! 186: setenv("TERM","interix");
! 187: #endif
! 188:
! 189: initscr(); /* Start up cursor package */
! 190:
! 191: if (strcmp(termname(),"dumb") == 0)
! 192: {
! 193: endwin();
! 194: printf("ERROR in terminal parameters.\n");
! 195: printf("Check TERM in environment.\n");
! 196: byebye(1);
! 197: }
! 198:
! 199: if (LINES < 24 || COLS < 80) {
! 200: endwin();
! 201: printf("ERROR: screen size too small\n");
! 202: byebye(1);
! 203: }
! 204:
! 205: if ((*whoami == '\0') || (strcmp(whoami,"dosuser")==0))
! 206: {
! 207: echo();
! 208: mvaddstr(23,2,"Rogue's Name? ");
! 209: wgetnstr(stdscr,whoami,MAXSTR);
! 210: noecho();
! 211: }
! 212:
! 213: if (*whoami == '\0')
! 214: strcpy(whoami,"Rodney");
! 215:
! 216: setup();
! 217:
! 218: /* Set up windows */
! 219:
! 220: cw = newwin(0, 0, 0, 0);
! 221: mw = newwin(0, 0, 0, 0);
! 222: hw = newwin(0, 0, 0, 0);
! 223: keypad(cw, 1);
! 224: waswizard = wizard;
! 225:
! 226: /* Draw current level */
! 227:
! 228: new_level(NORMLEV);
! 229:
! 230: /* Start up daemons and fuses */
! 231:
! 232: start_daemon(status, TRUE, BEFORE);
! 233: start_daemon(runners, TRUE, AFTER);
! 234: /*
! 235: * These daemons have been moved to AFTER because BEFORE daemons
! 236: * get called every command, even invalid ones. Hopefully this
! 237: * won't break anything.
! 238: */
! 239: start_daemon(doctor, TRUE, AFTER);
! 240: start_daemon(stomach, TRUE, AFTER);
! 241: fuse(swander, TRUE, WANDERTIME);
! 242:
! 243: /* Give the rogue his weaponry */
! 244:
! 245: do {
! 246: wpt = pick_one(w_magic);
! 247: switch (wpt)
! 248: {
! 249: case MACE: case SWORD: case TWOSWORD:
! 250: case SPEAR: case TRIDENT: case SPETUM:
! 251: case BARDICHE: case PIKE: case BASWORD:
! 252: case HALBERD:
! 253: alldone = TRUE;
! 254: otherwise:
! 255: alldone = FALSE;
! 256: }
! 257: } while(!alldone);
! 258:
! 259: item = new_thing(FALSE, WEAPON, wpt);
! 260: obj = OBJPTR(item);
! 261: obj->o_hplus = rnd(3);
! 262: obj->o_dplus = rnd(3);
! 263: obj->o_flags = ISKNOW;
! 264: add_pack(item, TRUE);
! 265: cur_weapon = obj;
! 266:
! 267: /* Now a bow */
! 268:
! 269: item = new_thing(FALSE, WEAPON, BOW);
! 270: obj = OBJPTR(item);
! 271: obj->o_hplus = rnd(3);
! 272: obj->o_dplus = rnd(3);
! 273: obj->o_flags = ISKNOW;
! 274: add_pack(item, TRUE);
! 275:
! 276: /* Now some arrows */
! 277:
! 278: item = new_thing(FALSE, WEAPON, ARROW);
! 279: obj = OBJPTR(item);
! 280: obj->o_count = 25 + rnd(15);
! 281: obj->o_hplus = rnd(2);
! 282: obj->o_dplus = rnd(2);
! 283: obj->o_flags = ISKNOW;
! 284: add_pack(item, TRUE);
! 285:
! 286: /* And his suit of armor */
! 287:
! 288: wpt = pick_one(a_magic);
! 289: item = new_thing(FALSE, ARMOR, wpt);
! 290: obj = OBJPTR(item);
! 291: obj->o_flags = ISKNOW;
! 292: obj->o_ac = armors[wpt].a_class - rnd(4);
! 293: cur_armor = obj;
! 294: add_pack(item, TRUE);
! 295:
! 296: /* Give him some food */
! 297:
! 298: item = new_thing(FALSE, FOOD, 0);
! 299: add_pack(item, TRUE);
! 300:
! 301: playit();
! 302: }
! 303:
! 304:
! 305: /*
! 306: * endit:
! 307: * Exit the program abnormally.
! 308: */
! 309: void
! 310: endit(int a)
! 311: {
! 312: fatal("Ok, if you want to exit that badly, I'll have to allow it");
! 313: }
! 314:
! 315: /*
! 316: * fatal:
! 317: * Exit the program, printing a message.
! 318: */
! 319:
! 320: void
! 321: fatal(char *s)
! 322: {
! 323: clear();
! 324: refresh();
! 325: endwin();
! 326: fprintf(stderr,"%s\n\r",s);
! 327: fflush(stderr);
! 328: byebye(2);
! 329: }
! 330:
! 331: /*
! 332: * byebye:
! 333: * Exit here and reset the users terminal parameters
! 334: * to the way they were when he started
! 335: */
! 336:
! 337: void
! 338: byebye(int how)
! 339: {
! 340: if (!isendwin())
! 341: endwin();
! 342:
! 343: exit(how); /* exit like flag says */
! 344: }
! 345:
! 346:
! 347: /*
! 348: * rnd:
! 349: * Pick a very random number.
! 350: */
! 351: int
! 352: rnd(int range)
! 353: {
! 354: reg int wh;
! 355:
! 356: if (range == 0)
! 357: wh = 0;
! 358: else {
! 359: wh = md_random() % range;
! 360: wh &= 0x7FFFFFFF;
! 361: }
! 362: return wh;
! 363: }
! 364:
! 365: /*
! 366: * roll:
! 367: * roll a number of dice
! 368: */
! 369: int
! 370: roll(int number, int sides)
! 371: {
! 372: reg int dtotal = 0;
! 373:
! 374: while(number-- > 0)
! 375: dtotal += rnd(sides)+1;
! 376: return dtotal;
! 377: }
! 378:
! 379:
! 380: /*
! 381: ** setup: Setup signal catching functions
! 382: */
! 383: void
! 384: setup(void)
! 385: {
! 386: md_onsignal_autosave();
! 387:
! 388: nonl();
! 389: cbreak();
! 390: noecho();
! 391: }
! 392:
! 393: /*
! 394: ** playit: The main loop of the program. Loop until the game is over,
! 395: ** refreshing things and looking at the proper times.
! 396: */
! 397:
! 398: void
! 399: playit(void)
! 400: {
! 401: reg char *opts;
! 402:
! 403: /* parse environment declaration of options */
! 404:
! 405: if ((opts = getenv("ROGUEOPTS")) != NULL)
! 406: parse_opts(opts);
! 407:
! 408: player.t_oldpos = hero;
! 409: oldrp = roomin(&hero);
! 410: nochange = FALSE;
! 411: while (playing)
! 412: command(); /* Command execution */
! 413: endit(0);
! 414: }
! 415:
! 416:
! 417: /*
! 418: ** author: See if a user is an author of the program
! 419: */
! 420: bool
! 421: author(void)
! 422: {
! 423: switch (playuid) {
! 424: case 100:
! 425: case 0:
! 426: return TRUE;
! 427: default:
! 428: return FALSE;
! 429: }
! 430: }
! 431:
! 432: int
! 433: directory_exists(char *dirname)
! 434: {
! 435: struct stat sb;
! 436:
! 437: if (stat(dirname, &sb) == 0) /* path exists */
! 438: return ((sb.st_mode & S_IFMT) == S_IFDIR);
! 439:
! 440: return(0);
! 441: }
! 442:
! 443: char *
! 444: roguehome(void)
! 445: {
! 446: static char path[LINLEN+16];
! 447: char *end,*home;
! 448:
! 449: if ( (home = getenv("ROGUEHOME")) != NULL)
! 450: {
! 451: if (*home)
! 452: {
! 453: /* LINLEN - 11 is all that will fit into scorefile */
! 454: strncpy(path, home, LINLEN - 11);
! 455: if (path[LINLEN - 12] == '\0')
! 456: {
! 457: end = &path[strlen(path)-1];
! 458: while( (end >= path) && ((*end == '/') || (*end == '\\')))
! 459: *end-- = '\0';
! 460:
! 461: if (directory_exists(path))
! 462: return(path);
! 463: }
! 464: /* Otherwise home was truncated and should be ignored */
! 465: }
! 466: }
! 467:
! 468: if (directory_exists("/var/games/roguelike"))
! 469: return("/var/games/roguelike");
! 470: if (directory_exists("/var/lib/roguelike"))
! 471: return("/var/lib/roguelike");
! 472: if (directory_exists("/var/roguelike"))
! 473: return("/var/roguelike");
! 474: if (directory_exists("/usr/games/lib"))
! 475: return("/usr/games/lib");
! 476: if (directory_exists("/games/roguelik"))
! 477: return("/games/roguelik");
! 478:
! 479: return(NULL);
! 480: }
! 481:
! 482: void
! 483: open_records(void)
! 484: {
! 485: if (scoreboard == NULL)
! 486: scoreboard = fopen(scorefile, "r+");
! 487: if (scoreboard == NULL && errno == ENOENT) {
! 488: scoreboard = fopen(scorefile, "w+");
! 489: }
! 490: #ifdef LOGFILE
! 491: if (logfile == NULL)
! 492: logfile = fopen(LOGFILE, "a");
! 493: #endif
! 494: }
! 495:
CVSweb