Mercurial > hg > early-roguelike
diff srogue/main.c @ 36:2128c7dc8a40
Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 25 Nov 2010 12:21:41 +0000 |
parents | |
children | 34d7a614855e |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srogue/main.c Thu Nov 25 12:21:41 2010 +0000 @@ -0,0 +1,472 @@ +/* + * 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 <time.h> +#include <termios.h> +#include <fcntl.h> +#include <stdio.h> +#include <signal.h> +#include <pwd.h> +#include <limits.h> +#include <sys/stat.h> +#include "rogue.h" + +#ifdef ATT +#include <time.h> +#endif + +#ifdef BSD +#define srand48(seed) srandom(seed) +#define lrand48() random() +#include <sys/time.h> +#endif + +#include "rogue.ext" + +struct termios terminal; + +main(argc, argv, envp) +char **argv; +char **envp; +{ + register char *env; + register struct linked_list *item; + register struct object *obj; + struct passwd *pw; + struct passwd *getpwuid(); + char alldone, wpt; + char *getpass(), *xcrypt(), *strrchr(); + int lowtime; + time_t now; + char *roguehome(); + char *homedir = roguehome(); + +#ifdef __DJGPP__ + _fmode = O_BINARY; +#endif + + if (homedir == NULL) + homedir = ""; + + playuid = getuid(); + + if (setuid(playuid) < 0) { + printf("Cannot change to effective uid: %d\n", playuid); + exit(1); + } + playgid = getgid(); + + /* check for print-score option */ + + strcpy(scorefile, homedir); + + if (*scorefile) + strcat(scorefile,"/"); + strcat(scorefile, "srogue.scr"); + + if(argc >= 2 && strcmp(argv[1], "-s") == 0) + { + showtop(0); + exit(0); + } + + 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--; + } + } + time(&now); + lowtime = (int) now; + + /* get home and options from environment */ + + if ((env = getenv("HOME")) != NULL) + strcpy(home, env); + else if ((pw = getpwuid(playuid)) != NULL) + strcpy(home, pw->pw_dir); + else + home[0] = '\0'; + + if (strcmp(home,"/") == 0) + home[0] = '\0'; + + if ((strlen(home) > 0) && (home[strlen(home)-1] != '/')) + strcat(home, "/"); + + strcpy(file_name, home); + strcat(file_name, "srogue.sav"); + + if ((env = getenv("ROGUEOPTS")) != NULL) + parse_opts(env); + + if (env == NULL || whoami[0] == '\0') + { + if((pw = getpwuid(playuid)) == NULL) + { + printf("Say, who are you?\n"); + exit(1); + } + else + strucpy(whoami, pw->pw_name, strlen(pw->pw_name)); + } + + if (env == NULL || fruit[0] == '\0') + strcpy(fruit, "juicy-fruit"); + + if (argc == 2) + if(!restore(argv[1], envp)) /* NOTE: NEVER RETURNS */ + exit(1); + + dnum = (wizard && getenv("SEED") != NULL ? + atoi(getenv("SEED")) : lowtime + getpid()); + + 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; + srand48(seed); /* init rnd number gen */ + + signal(SIGINT, byebye); /* just in case */ + signal(SIGQUIT ,byebye); + + 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 == NULL) || (*whoami == '\0') || (strcmp(whoami,"dosuser")==0)) + { + echo(); + mvaddstr(23,2,"Rogue's Name? "); + wgetnstr(stdscr,whoami,MAXSTR); + noecho(); + } + + if ((whoami == NULL) || (*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); + waswizard = wizard; + + /* Draw current level */ + + new_level(NORMLEV); + + /* Start up daemons and fuses */ + + daemon(status, TRUE, BEFORE); + daemon(doctor, TRUE, BEFORE); + daemon(stomach, TRUE, BEFORE); + daemon(runners, 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. + */ + +fatal(s) +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(how) +int how; +{ + if (!isendwin()) + endwin(); + + exit(how); /* exit like flag says */ +} + + +/* + * rnd: + * Pick a very random number. + */ +rnd(range) +int range; +{ + reg int wh; + + if (range == 0) + wh = 0; + else { + wh = lrand48() % range; + wh &= 0x7FFFFFFF; + } + return wh; +} + +/* + * roll: + * roll a number of dice + */ +roll(number, sides) +int number, sides; +{ + reg int dtotal = 0; + + while(number-- > 0) + dtotal += rnd(sides)+1; + return dtotal; +} + + +/* +** setup: Setup signal catching functions +*/ +setup() +{ + signal(SIGHUP, auto_save); + signal(SIGINT, auto_save); + signal(SIGQUIT, byebye); + signal(SIGILL, game_err); + signal(SIGTRAP, game_err); +#ifdef SIGIOT + signal(SIGIOT, game_err); +#endif +#ifdef SIGEMT + signal(SIGEMT, game_err); +#endif + signal(SIGFPE, game_err); +#ifdef SIGBUS + signal(SIGBUS, game_err); +#endif + signal(SIGSEGV, game_err); +#ifdef SIGSYS + signal(SIGSYS, game_err); +#endif + signal(SIGPIPE, game_err); + signal(SIGTERM, game_err); + + cbreak(); + noecho(); +} + +/* +** playit: The main loop of the program. Loop until the game is over, +** refreshing things and looking at the proper times. +*/ + +playit() +{ + reg char *opts; + + tcgetattr(0,&terminal); + + + /* 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 +*/ +author() +{ + 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 (S_ISDIR (sb.st_mode)); + + return(0); +} + +char * +roguehome() +{ + static char path[1024]; + char *end,*home; + + if ( (home = getenv("ROGUEHOME")) != NULL) + { + if (*home) + { + strncpy(path, home, PATH_MAX - 20); + + end = &path[strlen(path)-1]; + + + while( (end >= path) && ((*end == '/') || (*end == '\\'))) + *end-- = '\0'; + + if (directory_exists(path)) + return(path); + } + } + + 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); +} +