/* * Rogue * Exploring the dungeons of doom * * @(#)main.c 9.0 (rdk) 7/17/84 * * Super-Rogue * Copyright (C) 1984 Robert D. Kindelberger * All rights reserved. * * Based on "Rogue: Exploring the Dungeons of Doom" * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. */ #include #include #include #include #include #include #include #include #include "rogue.h" #ifdef ATT #include #endif #ifdef BSD #include #endif #include "rogue.ext" char *roguehome(void); void open_records(void); extern FILE *scoreboard; extern FILE *logfile; int main(int argc, char *argv[], char *envp[]) { register char *env; register struct linked_list *item; register struct object *obj; char alldone; int wpt; char *getpass(), *xcrypt(), *strrchr(); char *homedir = roguehome(); md_init(); if (homedir == NULL) homedir = ""; playuid = md_getuid(); playgid = md_getgid(); /* check for print-score option */ #ifdef SCOREFILE strncpy(scorefile, SCOREFILE, LINLEN); scorefile[LINLEN - 1] = '\0'; #else strncpy(scorefile, homedir, LINLEN-11); if (scorefile[LINLEN-12] != '\0') scorefile[0] = '\0'; if (*scorefile) strcat(scorefile,"/"); strcat(scorefile, "srogue.scr"); #endif open_records(); if(argc >= 2 && strcmp(argv[1], "-s") == 0) { showtop(0); exit(0); } #ifdef WIZARD if (argc >= 2 && author() && strcmp(argv[1],"-a") == 0) { wizard = TRUE; argv++; argc--; } /* Check to see if he is a wizard */ if (argc >= 2 && strcmp(argv[1],"-w") == 0) { if (strcmp(PASSWD, xcrypt(getpass(wizstr),"mT")) == 0) { wizard = TRUE; argv++; argc--; } } #endif #ifdef SAVEDIR if (argc >= 3 && !strcmp(argv[1], "-n")) { strncpy(whoami, argv[2], LINLEN); whoami[LINLEN - 1] = '\0'; use_savedir = TRUE; if (snprintf(file_name, 256, "%s/%d-%s.srsav", SAVEDIR, playuid, whoami) >= 256) { /* Just in case it doesn't fit */ strcpy(file_name, "srogue.save"); use_savedir = FALSE; } } #endif if (!use_savedir) md_normaluser(); /* get home and options from environment */ if ((env = getenv("HOME")) != NULL) strcpy(home, env); else { strncpy(home, md_gethomedir(), LINLEN); if (home[LINLEN-1] != '\0') home[0] = '\0'; } if (strcmp(home,"/") == 0) home[0] = '\0'; if ((strlen(home) > 0) && (home[strlen(home)-1] != '/')) strcat(home, "/"); if (!use_savedir) { strcpy(file_name, home); strcat(file_name, "srogue.sav"); } if ((env = getenv("ROGUEOPTS")) != NULL) parse_opts(env); if (!use_savedir && (env == NULL || whoami[0] == '\0')) { strucpy(whoami, md_getusername(), strlen(md_getusername())); } if (env == NULL || fruit[0] == '\0') strcpy(fruit, "juicy-fruit"); if (use_savedir) { /* restore() won't return if the restore succeeded. If * file_name doesn't exist, it will return TRUE. In that * case, start a new game. */ if (!restore(file_name, envp)) exit(1); } else if (argc == 2) if(!restore(argv[1], envp)) /* NOTE: NEVER RETURNS */ exit(1); /* START NEW GAME */ dnum = (wizard && getenv("SEED") != NULL ? atoi(getenv("SEED")) : md_random_seed()); if(wizard) printf("Hello %s, welcome to dungeon #%d\n", whoami, dnum); else printf("Hello %s, One moment while I open the door to the dungeon...\n", whoami); fflush(stdout); seed = dnum; md_srandom(seed); /* init rnd number gen */ md_onsignal_exit(); /* just in case */ init_everything(); #ifdef __INTERIX setenv("TERM","interix"); #endif initscr(); /* Start up cursor package */ if (strcmp(termname(),"dumb") == 0) { endwin(); printf("ERROR in terminal parameters.\n"); printf("Check TERM in environment.\n"); byebye(1); } if (LINES < 24 || COLS < 80) { endwin(); printf("ERROR: screen size too small\n"); byebye(1); } if ((*whoami == '\0') || (strcmp(whoami,"dosuser")==0)) { echo(); mvaddstr(23,2,"Rogue's Name? "); wgetnstr(stdscr,whoami,MAXSTR); noecho(); } if (*whoami == '\0') strcpy(whoami,"Rodney"); setup(); /* Set up windows */ cw = newwin(0, 0, 0, 0); mw = newwin(0, 0, 0, 0); hw = newwin(0, 0, 0, 0); keypad(cw, 1); waswizard = wizard; /* Draw current level */ new_level(NORMLEV); /* Start up daemons and fuses */ start_daemon(status, TRUE, BEFORE); start_daemon(runners, TRUE, AFTER); /* * These daemons have been moved to AFTER because BEFORE daemons * get called every command, even invalid ones. Hopefully this * won't break anything. */ start_daemon(doctor, TRUE, AFTER); start_daemon(stomach, TRUE, AFTER); fuse(swander, TRUE, WANDERTIME); /* Give the rogue his weaponry */ do { wpt = pick_one(w_magic); switch (wpt) { case MACE: case SWORD: case TWOSWORD: case SPEAR: case TRIDENT: case SPETUM: case BARDICHE: case PIKE: case BASWORD: case HALBERD: alldone = TRUE; otherwise: alldone = FALSE; } } while(!alldone); item = new_thing(FALSE, WEAPON, wpt); obj = OBJPTR(item); obj->o_hplus = rnd(3); obj->o_dplus = rnd(3); obj->o_flags = ISKNOW; add_pack(item, TRUE); cur_weapon = obj; /* Now a bow */ item = new_thing(FALSE, WEAPON, BOW); obj = OBJPTR(item); obj->o_hplus = rnd(3); obj->o_dplus = rnd(3); obj->o_flags = ISKNOW; add_pack(item, TRUE); /* Now some arrows */ item = new_thing(FALSE, WEAPON, ARROW); obj = OBJPTR(item); obj->o_count = 25 + rnd(15); obj->o_hplus = rnd(2); obj->o_dplus = rnd(2); obj->o_flags = ISKNOW; add_pack(item, TRUE); /* And his suit of armor */ wpt = pick_one(a_magic); item = new_thing(FALSE, ARMOR, wpt); obj = OBJPTR(item); obj->o_flags = ISKNOW; obj->o_ac = armors[wpt].a_class - rnd(4); cur_armor = obj; add_pack(item, TRUE); /* Give him some food */ item = new_thing(FALSE, FOOD, 0); add_pack(item, TRUE); playit(); } /* * endit: * Exit the program abnormally. */ void endit(int a) { fatal("Ok, if you want to exit that badly, I'll have to allow it"); } /* * fatal: * Exit the program, printing a message. */ void fatal(char *s) { clear(); refresh(); endwin(); fprintf(stderr,"%s\n\r",s); fflush(stderr); byebye(2); } /* * byebye: * Exit here and reset the users terminal parameters * to the way they were when he started */ void byebye(int how) { if (!isendwin()) endwin(); exit(how); /* exit like flag says */ } /* * rnd: * Pick a very random number. */ int rnd(int range) { reg int wh; if (range == 0) wh = 0; else { wh = md_random() % range; wh &= 0x7FFFFFFF; } return wh; } /* * roll: * roll a number of dice */ int roll(int number, int sides) { reg int dtotal = 0; while(number-- > 0) dtotal += rnd(sides)+1; return dtotal; } /* ** setup: Setup signal catching functions */ void setup(void) { md_onsignal_autosave(); nonl(); cbreak(); noecho(); } /* ** playit: The main loop of the program. Loop until the game is over, ** refreshing things and looking at the proper times. */ void playit(void) { reg char *opts; /* parse environment declaration of options */ if ((opts = getenv("ROGUEOPTS")) != NULL) parse_opts(opts); player.t_oldpos = hero; oldrp = roomin(&hero); nochange = FALSE; while (playing) command(); /* Command execution */ endit(0); } /* ** author: See if a user is an author of the program */ bool author(void) { switch (playuid) { case 100: case 0: return TRUE; default: return FALSE; } } int directory_exists(char *dirname) { struct stat sb; if (stat(dirname, &sb) == 0) /* path exists */ return ((sb.st_mode & S_IFMT) == S_IFDIR); return(0); } char * roguehome(void) { static char path[LINLEN+16]; char *end,*home; if ( (home = getenv("ROGUEHOME")) != NULL) { if (*home) { /* LINLEN - 11 is all that will fit into scorefile */ strncpy(path, home, LINLEN - 11); if (path[LINLEN - 12] == '\0') { end = &path[strlen(path)-1]; while( (end >= path) && ((*end == '/') || (*end == '\\'))) *end-- = '\0'; if (directory_exists(path)) return(path); } /* Otherwise home was truncated and should be ignored */ } } if (directory_exists("/var/games/roguelike")) return("/var/games/roguelike"); if (directory_exists("/var/lib/roguelike")) return("/var/lib/roguelike"); if (directory_exists("/var/roguelike")) return("/var/roguelike"); if (directory_exists("/usr/games/lib")) return("/usr/games/lib"); if (directory_exists("/games/roguelik")) return("/games/roguelik"); return(NULL); } void open_records(void) { if (scoreboard == NULL) scoreboard = fopen(scorefile, "r+"); if (scoreboard == NULL && errno == ENOENT) { scoreboard = fopen(scorefile, "w+"); } #ifdef LOGFILE if (logfile == NULL) logfile = fopen(LOGFILE, "a"); #endif }