Mercurial > hg > early-roguelike
view rogue5/main.c @ 120:d6b7c3fb37ea
srogue: add and use more md_* portable functions.
Privileges and memory usage checks are now more portable.
author | John "Elwin" Edwards |
---|---|
date | Fri, 02 May 2014 15:06:23 -0700 |
parents | ee250e3646fd |
children | 3d4252fa2ed3 |
line wrap: on
line source
/* * Rogue: Exploring the Dungeons of Doom * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman * All rights reserved. * * See the file LICENSE.TXT for full copyright and licensing information. * * @(#)main.c 4.22 (Berkeley) 02/05/99 */ #include <stdlib.h> #include <string.h> #include <signal.h> #include <time.h> #include <curses.h> #include "rogue.h" /* * main: * The main program, of course */ int main(int argc, char **argv) { char *env; time_t lowtime; md_init(); #ifdef MASTER /* * Check to see if he is a wizard */ if (argc >= 2 && argv[1][0] == '\0') if (strcmp(PASSWD, md_crypt(md_getpass("wizard's password: "), "mT")) == 0) { wizard = TRUE; player.t_flags |= SEEMONST; argv++; argc--; } #endif /* Check to see if savefiles should be stored in the system location */ #ifdef SAVEDIR if (argc >= 3 && !strcmp(argv[1], "-n")) { use_savedir = TRUE; strncpy(whoami, argv[2], MAXSTR); whoami[MAXSTR-1] = '\0'; snprintf(file_name, MAXSTR, "%s/%d-%.80s.r5sav", SAVEDIR, md_getuid(), whoami); } #endif open_score(); open_log(); /* * get home and options from environment */ strcpy(home, md_gethomedir()); if (strlen(home) > MAXSTR - strlen("rogue5.save") - 1) *home = 0; if (!use_savedir) { md_normaluser(); strcpy(file_name, home); strcat(file_name, "rogue5.save"); } if ((env = getenv("ROGUEOPTS")) != NULL) parse_opts(env); if (!use_savedir && (env == NULL || whoami[0] == '\0')) strucpy(whoami, md_getusername(), strlen(md_getusername())); lowtime = time(NULL); if (getenv("SEED") != NULL) { dnum = atoi(getenv("SEED")); noscore = 1; } else dnum = (unsigned int) lowtime + md_getpid(); seed = dnum; /* * check for print-score option */ if (argc == 2) { if (strcmp(argv[1], "-s") == 0) { noscore = TRUE; score(0, -1, 0); exit(0); } else if (strcmp(argv[1], "-d") == 0) { dnum = rnd(100); /* throw away some rnd()s to break patterns */ while (--dnum) rnd(100); purse = rnd(100) + 1; level = rnd(100) + 1; initscr(); getltchars(); death(death_monst()); exit(0); } } init_check(); /* check for legal startup */ if (use_savedir) { /* If there is a saved game, restore() will not return. If it * returns 1, there isn't a game, so start one. If 0, there was * an error. */ if (!restore(file_name)) my_exit(1); } else if (argc == 2) if (!restore(argv[1])) /* Note: restore will never return */ my_exit(1); #ifdef MASTER if (wizard) printf("Hello %s, welcome to dungeon #%d\n", whoami, dnum); else #endif printf("Hello %s, just a moment while I dig the dungeon...\n", whoami); fflush(stdout); initscr(); /* Start up cursor package */ init_probs(); /* Set up prob tables for objects */ init_player(); /* Set up initial player stats */ init_names(); /* Set up names of scrolls */ init_colors(); /* Set up colors of potions */ init_stones(); /* Set up stone settings of rings */ init_materials(); /* Set up materials of wands */ setup(); /* * The screen must be at least NUMLINES x NUMCOLS */ if (LINES < NUMLINES || COLS < NUMCOLS) { printf("\nSorry, the screen must be at least %dx%d\n", NUMLINES, NUMCOLS); endwin(); my_exit(1); } /* * Set up windows */ hw = newwin(LINES, COLS, 0, 0); idlok(stdscr, TRUE); idlok(hw, TRUE); #ifdef MASTER noscore = wizard; #endif new_level(); /* Draw current level */ /* * Start up daemons and fuses */ start_daemon(runners, 0, AFTER); start_daemon(doctor, 0, AFTER); fuse(swander, 0, WANDERTIME, AFTER); start_daemon(stomach, 0, AFTER); playit(); return(0); } /* * endit: * Exit the program abnormally. */ void endit(int sig) { NOOP(sig); fatal("Okay, bye bye!\n"); } /* * fatal: * Exit the program, printing a message. */ void fatal(const char *s) { mvaddstr(LINES - 2, 0, s); refresh(); endwin(); my_exit(0); } /* * rnd: * Pick a very random number. */ int rnd(int range) { return range == 0 ? 0 : abs((int) RN) % range; } /* * roll: * Roll a number of dice */ int roll(int number, int sides) { int dtotal = 0; while (number--) dtotal += rnd(sides)+1; return dtotal; } /* * tstp: * Handle stop and start signals */ void tstp(int ignored) { int y, x; int oy, ox; NOOP(ignored); /* * leave nicely */ getyx(curscr, oy, ox); mvcur(0, COLS - 1, LINES - 1, 0); endwin(); resetltchars(); fflush(stdout); md_tstpsignal(); /* * start back up again */ md_tstpresume(); raw(); noecho(); nonl(); keypad(stdscr,1); playltchars(); clearok(curscr, TRUE); wrefresh(curscr); getyx(curscr, y, x); mvcur(y, x, oy, ox); fflush(stdout); curscr->_cury = oy; curscr->_curx = ox; } /* * playit: * The main loop of the program. Loop until the game is over, * refreshing things and looking at the proper times. */ void playit(void) { char *opts; /* * set up defaults for slow terminals */ if (baudrate() <= 1200) { terse = TRUE; jump = TRUE; see_floor = FALSE; } if (md_hasclreol()) inv_type = INV_CLEAR; /* * parse environment declaration of options */ if ((opts = getenv("ROGUEOPTS")) != NULL) parse_opts(opts); oldpos = hero; oldrp = roomin(&hero); while (playing) command(); /* Command execution */ endit(0); } /* * quit: * Have player make certain, then exit. */ void quit(int sig) { int oy, ox; NOOP(sig); /* * Reset the signal in case we got here via an interrupt */ if (!q_comm) mpos = 0; getyx(curscr, oy, ox); msg("really quit?"); if (readchar() == 'y') { signal(SIGINT, leave); clear(); mvprintw(LINES - 2, 0, "You quit with %d gold pieces", purse); move(LINES - 1, 0); refresh(); writelog(purse, 1, 0); score(purse, 1, 0); printf("[Press return to exit]\n"); fflush(NULL); getchar(); my_exit(0); } else { move(0, 0); clrtoeol(); status(); move(oy, ox); refresh(); mpos = 0; count = 0; to_death = FALSE; } } /* * leave: * Leave quickly, but curteously */ void leave(int sig) { static char buf[BUFSIZ]; NOOP(sig); setbuf(stdout, buf); /* throw away pending output */ if (!isendwin()) { mvcur(0, COLS - 1, LINES - 1, 0); endwin(); } putchar('\n'); my_exit(0); } /* * shell: * Let them escape for a while */ void shell(void) { /* * Set the terminal back to original mode */ move(LINES-1, 0); refresh(); endwin(); resetltchars(); putchar('\n'); in_shell = TRUE; after = FALSE; fflush(stdout); /* * Fork and do a shell */ md_shellescape(); noecho(); raw(); nonl(); keypad(stdscr,1); playltchars(); in_shell = FALSE; clearok(stdscr, TRUE); } /* * my_exit: * Leave the process properly */ void my_exit(int st) { resetltchars(); exit(st); }