Mercurial > hg > early-roguelike
comparison rogue5/main.c @ 33:f502bf60e6e4
Import Rogue 5.4 from the Roguelike Restoration Project (r1490)
| author | elwin |
|---|---|
| date | Mon, 24 May 2010 20:10:59 +0000 |
| parents | |
| children | 655c317b6237 |
comparison
equal
deleted
inserted
replaced
| 32:2dcd75e6a736 | 33:f502bf60e6e4 |
|---|---|
| 1 /* | |
| 2 * Rogue: Exploring the Dungeons of Doom | |
| 3 * Copyright (C) 1980-1983, 1985, 1999 Michael Toy, Ken Arnold and Glenn Wichman | |
| 4 * All rights reserved. | |
| 5 * | |
| 6 * See the file LICENSE.TXT for full copyright and licensing information. | |
| 7 * | |
| 8 * @(#)main.c 4.22 (Berkeley) 02/05/99 | |
| 9 */ | |
| 10 | |
| 11 #include <stdlib.h> | |
| 12 #include <string.h> | |
| 13 #include <signal.h> | |
| 14 #include <time.h> | |
| 15 #include <curses.h> | |
| 16 #include "rogue.h" | |
| 17 | |
| 18 /* | |
| 19 * main: | |
| 20 * The main program, of course | |
| 21 */ | |
| 22 int | |
| 23 main(int argc, char **argv) | |
| 24 { | |
| 25 char *env; | |
| 26 time_t lowtime; | |
| 27 | |
| 28 md_init(); | |
| 29 | |
| 30 #ifdef MASTER | |
| 31 /* | |
| 32 * Check to see if he is a wizard | |
| 33 */ | |
| 34 if (argc >= 2 && argv[1][0] == '\0') | |
| 35 if (strcmp(PASSWD, md_crypt(md_getpass("wizard's password: "), "mT")) == 0) | |
| 36 { | |
| 37 wizard = TRUE; | |
| 38 player.t_flags |= SEEMONST; | |
| 39 argv++; | |
| 40 argc--; | |
| 41 } | |
| 42 | |
| 43 #endif | |
| 44 | |
| 45 /* | |
| 46 * get home and options from environment | |
| 47 */ | |
| 48 | |
| 49 strcpy(home, md_gethomedir()); | |
| 50 | |
| 51 if (strlen(home) > MAXSTR - strlen("rogue.save") - 1) | |
| 52 *home = 0; | |
| 53 | |
| 54 strcpy(file_name, home); | |
| 55 strcat(file_name, "rogue.save"); | |
| 56 | |
| 57 if ((env = getenv("ROGUEOPTS")) != NULL) | |
| 58 parse_opts(env); | |
| 59 if (env == NULL || whoami[0] == '\0') | |
| 60 strucpy(whoami, md_getusername(), strlen(md_getusername())); | |
| 61 lowtime = time(NULL); | |
| 62 if (getenv("SEED") != NULL) | |
| 63 { | |
| 64 dnum = atoi(getenv("SEED")); | |
| 65 noscore = 1; | |
| 66 } | |
| 67 else | |
| 68 dnum = (unsigned int) lowtime + md_getpid(); | |
| 69 seed = dnum; | |
| 70 | |
| 71 open_score(); | |
| 72 | |
| 73 /* | |
| 74 * Drop setuid/setgid after opening the scoreboard file. | |
| 75 */ | |
| 76 | |
| 77 md_normaluser(); | |
| 78 | |
| 79 /* | |
| 80 * check for print-score option | |
| 81 */ | |
| 82 | |
| 83 md_normaluser(); /* we drop any setgid/setuid priveldges here */ | |
| 84 | |
| 85 if (argc == 2) | |
| 86 { | |
| 87 if (strcmp(argv[1], "-s") == 0) | |
| 88 { | |
| 89 noscore = TRUE; | |
| 90 score(0, -1, 0); | |
| 91 exit(0); | |
| 92 } | |
| 93 else if (strcmp(argv[1], "-d") == 0) | |
| 94 { | |
| 95 dnum = rnd(100); /* throw away some rnd()s to break patterns */ | |
| 96 while (--dnum) | |
| 97 rnd(100); | |
| 98 purse = rnd(100) + 1; | |
| 99 level = rnd(100) + 1; | |
| 100 initscr(); | |
| 101 getltchars(); | |
| 102 death(death_monst()); | |
| 103 exit(0); | |
| 104 } | |
| 105 } | |
| 106 | |
| 107 init_check(); /* check for legal startup */ | |
| 108 if (argc == 2) | |
| 109 if (!restore(argv[1])) /* Note: restore will never return */ | |
| 110 my_exit(1); | |
| 111 #ifdef MASTER | |
| 112 if (wizard) | |
| 113 printf("Hello %s, welcome to dungeon #%d", whoami, dnum); | |
| 114 else | |
| 115 #endif | |
| 116 printf("Hello %s, just a moment while I dig the dungeon...", whoami); | |
| 117 fflush(stdout); | |
| 118 | |
| 119 initscr(); /* Start up cursor package */ | |
| 120 init_probs(); /* Set up prob tables for objects */ | |
| 121 init_player(); /* Set up initial player stats */ | |
| 122 init_names(); /* Set up names of scrolls */ | |
| 123 init_colors(); /* Set up colors of potions */ | |
| 124 init_stones(); /* Set up stone settings of rings */ | |
| 125 init_materials(); /* Set up materials of wands */ | |
| 126 setup(); | |
| 127 | |
| 128 /* | |
| 129 * The screen must be at least NUMLINES x NUMCOLS | |
| 130 */ | |
| 131 if (LINES < NUMLINES || COLS < NUMCOLS) | |
| 132 { | |
| 133 printf("\nSorry, the screen must be at least %dx%d\n", NUMLINES, NUMCOLS); | |
| 134 endwin(); | |
| 135 my_exit(1); | |
| 136 } | |
| 137 | |
| 138 /* | |
| 139 * Set up windows | |
| 140 */ | |
| 141 hw = newwin(LINES, COLS, 0, 0); | |
| 142 idlok(stdscr, TRUE); | |
| 143 idlok(hw, TRUE); | |
| 144 #ifdef MASTER | |
| 145 noscore = wizard; | |
| 146 #endif | |
| 147 new_level(); /* Draw current level */ | |
| 148 /* | |
| 149 * Start up daemons and fuses | |
| 150 */ | |
| 151 start_daemon(runners, 0, AFTER); | |
| 152 start_daemon(doctor, 0, AFTER); | |
| 153 fuse(swander, 0, WANDERTIME, AFTER); | |
| 154 start_daemon(stomach, 0, AFTER); | |
| 155 playit(); | |
| 156 return(0); | |
| 157 } | |
| 158 | |
| 159 /* | |
| 160 * endit: | |
| 161 * Exit the program abnormally. | |
| 162 */ | |
| 163 | |
| 164 void | |
| 165 endit(int sig) | |
| 166 { | |
| 167 NOOP(sig); | |
| 168 fatal("Okay, bye bye!\n"); | |
| 169 } | |
| 170 | |
| 171 /* | |
| 172 * fatal: | |
| 173 * Exit the program, printing a message. | |
| 174 */ | |
| 175 | |
| 176 void | |
| 177 fatal(const char *s) | |
| 178 { | |
| 179 mvaddstr(LINES - 2, 0, s); | |
| 180 refresh(); | |
| 181 endwin(); | |
| 182 my_exit(0); | |
| 183 } | |
| 184 | |
| 185 /* | |
| 186 * rnd: | |
| 187 * Pick a very random number. | |
| 188 */ | |
| 189 int | |
| 190 rnd(int range) | |
| 191 { | |
| 192 return range == 0 ? 0 : abs((int) RN) % range; | |
| 193 } | |
| 194 | |
| 195 /* | |
| 196 * roll: | |
| 197 * Roll a number of dice | |
| 198 */ | |
| 199 int | |
| 200 roll(int number, int sides) | |
| 201 { | |
| 202 int dtotal = 0; | |
| 203 | |
| 204 while (number--) | |
| 205 dtotal += rnd(sides)+1; | |
| 206 return dtotal; | |
| 207 } | |
| 208 | |
| 209 /* | |
| 210 * tstp: | |
| 211 * Handle stop and start signals | |
| 212 */ | |
| 213 | |
| 214 void | |
| 215 tstp(int ignored) | |
| 216 { | |
| 217 int y, x; | |
| 218 int oy, ox; | |
| 219 | |
| 220 NOOP(ignored); | |
| 221 | |
| 222 /* | |
| 223 * leave nicely | |
| 224 */ | |
| 225 getyx(curscr, oy, ox); | |
| 226 mvcur(0, COLS - 1, LINES - 1, 0); | |
| 227 endwin(); | |
| 228 resetltchars(); | |
| 229 fflush(stdout); | |
| 230 md_tstpsignal(); | |
| 231 | |
| 232 /* | |
| 233 * start back up again | |
| 234 */ | |
| 235 md_tstpresume(); | |
| 236 raw(); | |
| 237 noecho(); | |
| 238 keypad(stdscr,1); | |
| 239 playltchars(); | |
| 240 clearok(curscr, TRUE); | |
| 241 wrefresh(curscr); | |
| 242 getyx(curscr, y, x); | |
| 243 mvcur(y, x, oy, ox); | |
| 244 fflush(stdout); | |
| 245 curscr->_cury = oy; | |
| 246 curscr->_curx = ox; | |
| 247 } | |
| 248 | |
| 249 /* | |
| 250 * playit: | |
| 251 * The main loop of the program. Loop until the game is over, | |
| 252 * refreshing things and looking at the proper times. | |
| 253 */ | |
| 254 | |
| 255 void | |
| 256 playit(void) | |
| 257 { | |
| 258 char *opts; | |
| 259 | |
| 260 /* | |
| 261 * set up defaults for slow terminals | |
| 262 */ | |
| 263 | |
| 264 if (baudrate() <= 1200) | |
| 265 { | |
| 266 terse = TRUE; | |
| 267 jump = TRUE; | |
| 268 see_floor = FALSE; | |
| 269 } | |
| 270 | |
| 271 if (md_hasclreol()) | |
| 272 inv_type = INV_CLEAR; | |
| 273 | |
| 274 /* | |
| 275 * parse environment declaration of options | |
| 276 */ | |
| 277 if ((opts = getenv("ROGUEOPTS")) != NULL) | |
| 278 parse_opts(opts); | |
| 279 | |
| 280 | |
| 281 oldpos = hero; | |
| 282 oldrp = roomin(&hero); | |
| 283 while (playing) | |
| 284 command(); /* Command execution */ | |
| 285 endit(0); | |
| 286 } | |
| 287 | |
| 288 /* | |
| 289 * quit: | |
| 290 * Have player make certain, then exit. | |
| 291 */ | |
| 292 | |
| 293 void | |
| 294 quit(int sig) | |
| 295 { | |
| 296 int oy, ox; | |
| 297 | |
| 298 NOOP(sig); | |
| 299 | |
| 300 /* | |
| 301 * Reset the signal in case we got here via an interrupt | |
| 302 */ | |
| 303 if (!q_comm) | |
| 304 mpos = 0; | |
| 305 getyx(curscr, oy, ox); | |
| 306 msg("really quit?"); | |
| 307 if (readchar() == 'y') | |
| 308 { | |
| 309 signal(SIGINT, leave); | |
| 310 clear(); | |
| 311 mvprintw(LINES - 2, 0, "You quit with %d gold pieces", purse); | |
| 312 move(LINES - 1, 0); | |
| 313 refresh(); | |
| 314 score(purse, 1, 0); | |
| 315 my_exit(0); | |
| 316 } | |
| 317 else | |
| 318 { | |
| 319 move(0, 0); | |
| 320 clrtoeol(); | |
| 321 status(); | |
| 322 move(oy, ox); | |
| 323 refresh(); | |
| 324 mpos = 0; | |
| 325 count = 0; | |
| 326 to_death = FALSE; | |
| 327 } | |
| 328 } | |
| 329 | |
| 330 /* | |
| 331 * leave: | |
| 332 * Leave quickly, but curteously | |
| 333 */ | |
| 334 | |
| 335 void | |
| 336 leave(int sig) | |
| 337 { | |
| 338 static char buf[BUFSIZ]; | |
| 339 | |
| 340 NOOP(sig); | |
| 341 | |
| 342 setbuf(stdout, buf); /* throw away pending output */ | |
| 343 | |
| 344 if (!isendwin()) | |
| 345 { | |
| 346 mvcur(0, COLS - 1, LINES - 1, 0); | |
| 347 endwin(); | |
| 348 } | |
| 349 | |
| 350 putchar('\n'); | |
| 351 my_exit(0); | |
| 352 } | |
| 353 | |
| 354 /* | |
| 355 * shell: | |
| 356 * Let them escape for a while | |
| 357 */ | |
| 358 | |
| 359 void | |
| 360 shell(void) | |
| 361 { | |
| 362 /* | |
| 363 * Set the terminal back to original mode | |
| 364 */ | |
| 365 move(LINES-1, 0); | |
| 366 refresh(); | |
| 367 endwin(); | |
| 368 resetltchars(); | |
| 369 putchar('\n'); | |
| 370 in_shell = TRUE; | |
| 371 after = FALSE; | |
| 372 fflush(stdout); | |
| 373 /* | |
| 374 * Fork and do a shell | |
| 375 */ | |
| 376 md_shellescape(); | |
| 377 | |
| 378 noecho(); | |
| 379 raw(); | |
| 380 keypad(stdscr,1); | |
| 381 playltchars(); | |
| 382 in_shell = FALSE; | |
| 383 clearok(stdscr, TRUE); | |
| 384 } | |
| 385 | |
| 386 /* | |
| 387 * my_exit: | |
| 388 * Leave the process properly | |
| 389 */ | |
| 390 | |
| 391 void | |
| 392 my_exit(int st) | |
| 393 { | |
| 394 resetltchars(); | |
| 395 exit(st); | |
| 396 } | |
| 397 |
