Mercurial > hg > early-roguelike
comparison rogue3/main.c @ 0:527e2150eaf0
Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author | edwarj4 |
---|---|
date | Tue, 13 Oct 2009 13:33:34 +0000 |
parents | |
children | b4856d4d4c4e |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:527e2150eaf0 |
---|---|
1 /* | |
2 * @(#)main.c 3.27 (Berkeley) 6/15/81 | |
3 * | |
4 * Rogue: Exploring the Dungeons of Doom | |
5 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
6 * All rights reserved. | |
7 * | |
8 * See the file LICENSE.TXT for full copyright and licensing information. | |
9 */ | |
10 | |
11 #include "curses.h" | |
12 #include <time.h> | |
13 #include <signal.h> | |
14 #include <limits.h> | |
15 #include <stdlib.h> | |
16 #include <stdarg.h> | |
17 #include <string.h> | |
18 #include "machdep.h" | |
19 #include "rogue.h" | |
20 | |
21 int num_checks = 0; /* times we've gone over in checkout() */ | |
22 WINDOW *cw; /* Window that the player sees */ | |
23 WINDOW *hw; /* Used for the help command */ | |
24 WINDOW *mw; /* Used to store mosnters */ | |
25 FILE *scoreboard = NULL; | |
26 | |
27 main(argc, argv, envp) | |
28 char **argv; | |
29 char **envp; | |
30 { | |
31 char *env; | |
32 struct linked_list *item; | |
33 struct object *obj; | |
34 int lowtime; | |
35 time_t now; | |
36 | |
37 md_init(MD_STRIP_CTRL_KEYPAD); | |
38 | |
39 open_score(); | |
40 | |
41 /* | |
42 * Drop setuid/setgid after opening the scoreboard file. | |
43 */ | |
44 | |
45 md_normaluser(); | |
46 | |
47 /* | |
48 * check for print-score option | |
49 */ | |
50 if (argc == 2 && strcmp(argv[1], "-s") == 0) | |
51 { | |
52 waswizard = TRUE; | |
53 score(0, -1, 0); | |
54 exit(0); | |
55 } | |
56 /* | |
57 * Check to see if he is a wizard | |
58 */ | |
59 if (argc >= 2 && argv[1][0] == '\0') | |
60 if (strcmp(PASSWD, crypt(md_getpass("Wizard's password: "), "mT")) == 0) | |
61 { | |
62 wizard = TRUE; | |
63 argv++; | |
64 argc--; | |
65 } | |
66 | |
67 /* | |
68 * get home and options from environment | |
69 */ | |
70 strcpy(home, md_gethomedir()); | |
71 | |
72 if (strlen(home) > PATH_MAX - strlen("rogue.save") - 1) | |
73 *home = 0; | |
74 | |
75 strcpy(file_name, home); | |
76 strcat(file_name, "rogue.save"); | |
77 | |
78 if ((env = getenv("ROGUEOPTS")) != NULL) | |
79 parse_opts(env); | |
80 if (env == NULL || whoami[0] == '\0') | |
81 strucpy(whoami, md_getusername(), strlen(md_getusername())); | |
82 if (env == NULL || fruit[0] == '\0') | |
83 strcpy(fruit, "slime-mold"); | |
84 | |
85 if (too_much() && !wizard && !author()) | |
86 { | |
87 printf("Sorry, %s, but the system is too loaded now.\n", whoami); | |
88 printf("Try again later. Meanwhile, why not enjoy a%s %s?\n", | |
89 vowelstr(fruit), fruit); | |
90 exit(1); | |
91 } | |
92 | |
93 if (argc == 2) | |
94 if (!restore(argv[1], envp)) /* Note: restore will never return */ | |
95 exit(1); | |
96 | |
97 time(&now); | |
98 lowtime = (int) now; | |
99 | |
100 env = getenv("SEED"); | |
101 | |
102 if (env) | |
103 seed = atoi(env); | |
104 else | |
105 seed = 0; | |
106 | |
107 if (seed > 0) | |
108 { | |
109 waswizard = 1; /* don't save scores if SEED specified */ | |
110 dnum = seed; | |
111 } | |
112 else | |
113 dnum = lowtime + md_getpid(); | |
114 | |
115 if (wizard || env) | |
116 printf("Hello %s, welcome to dungeon #%d", whoami, dnum); | |
117 else | |
118 printf("Hello %s, just a moment while I dig the dungeon...", whoami); | |
119 | |
120 fflush(stdout); | |
121 seed = dnum; | |
122 init_player(); /* Roll up the rogue */ | |
123 init_things(); /* Set up probabilities of things */ | |
124 init_names(); /* Set up names of scrolls */ | |
125 init_colors(); /* Set up colors of potions */ | |
126 init_stones(); /* Set up stone settings of rings */ | |
127 init_materials(); /* Set up materials of wands */ | |
128 initscr(); /* Start up cursor package */ | |
129 | |
130 if (COLS < 70) | |
131 { | |
132 endwin(); | |
133 printf("\n\nSorry, %s, but your terminal window has too few columns.\n", whoami); | |
134 printf("Your terminal has %d columns, needs 70.\n",COLS); | |
135 exit(1); | |
136 } | |
137 if (LINES < 22) | |
138 { | |
139 endwin(); | |
140 printf("\n\nSorry, %s, but your terminal window has too few lines.\n", whoami); | |
141 printf("Your terminal has %d lines, needs 22.\n",LINES); | |
142 exit(1); | |
143 } | |
144 | |
145 | |
146 setup(); | |
147 /* | |
148 * Set up windows | |
149 */ | |
150 cw = newwin(LINES, COLS, 0, 0); | |
151 mw = newwin(LINES, COLS, 0, 0); | |
152 hw = newwin(LINES, COLS, 0, 0); | |
153 keypad(cw,1); | |
154 waswizard = wizard; | |
155 new_level(); /* Draw current level */ | |
156 /* | |
157 * Start up daemons and fuses | |
158 */ | |
159 start_daemon(doctor, 0, AFTER); | |
160 fuse(swander, 0, WANDERTIME, AFTER); | |
161 start_daemon(stomach, 0, AFTER); | |
162 start_daemon(runners, 0, AFTER); | |
163 /* | |
164 * Give the rogue his weaponry. First a mace. | |
165 */ | |
166 item = new_item(sizeof *obj); | |
167 obj = (struct object *) ldata(item); | |
168 obj->o_type = WEAPON; | |
169 obj->o_which = MACE; | |
170 init_weapon(obj, MACE); | |
171 obj->o_hplus = 1; | |
172 obj->o_dplus = 1; | |
173 obj->o_flags |= ISKNOW; | |
174 add_pack(item, TRUE); | |
175 cur_weapon = obj; | |
176 /* | |
177 * Now a +1 bow | |
178 */ | |
179 item = new_item(sizeof *obj); | |
180 obj = (struct object *) ldata(item); | |
181 obj->o_type = WEAPON; | |
182 obj->o_which = BOW; | |
183 init_weapon(obj, BOW); | |
184 obj->o_hplus = 1; | |
185 obj->o_dplus = 0; | |
186 obj->o_flags |= ISKNOW; | |
187 add_pack(item, TRUE); | |
188 /* | |
189 * Now some arrows | |
190 */ | |
191 item = new_item(sizeof *obj); | |
192 obj = (struct object *) ldata(item); | |
193 obj->o_type = WEAPON; | |
194 obj->o_which = ARROW; | |
195 init_weapon(obj, ARROW); | |
196 obj->o_count = 25+rnd(15); | |
197 obj->o_hplus = obj->o_dplus = 0; | |
198 obj->o_flags |= ISKNOW; | |
199 add_pack(item, TRUE); | |
200 /* | |
201 * And his suit of armor | |
202 */ | |
203 item = new_item(sizeof *obj); | |
204 obj = (struct object *) ldata(item); | |
205 obj->o_type = ARMOR; | |
206 obj->o_which = RING_MAIL; | |
207 obj->o_ac = a_class[RING_MAIL] - 1; | |
208 obj->o_flags |= ISKNOW; | |
209 cur_armor = obj; | |
210 add_pack(item, TRUE); | |
211 /* | |
212 * Give him some food too | |
213 */ | |
214 item = new_item(sizeof *obj); | |
215 obj = (struct object *) ldata(item); | |
216 obj->o_type = FOOD; | |
217 obj->o_count = 1; | |
218 obj->o_which = 0; | |
219 add_pack(item, TRUE); | |
220 playit(); | |
221 } | |
222 | |
223 /* | |
224 * endit: | |
225 * Exit the program abnormally. | |
226 */ | |
227 | |
228 void | |
229 endit(int p) | |
230 { | |
231 fatal("Ok, if you want to exit that badly, I'll have to allow it\n"); | |
232 } | |
233 | |
234 /* | |
235 * fatal: | |
236 * Exit the program, printing a message. | |
237 */ | |
238 | |
239 void | |
240 fatal(char *s) | |
241 { | |
242 clear(); | |
243 move(LINES-2, 0); | |
244 printw("%s", s); | |
245 draw(stdscr); | |
246 endwin(); | |
247 exit(0); | |
248 } | |
249 | |
250 /* | |
251 * rnd: | |
252 * Pick a very random number. | |
253 */ | |
254 | |
255 int | |
256 rnd(int range) | |
257 { | |
258 return range == 0 ? 0 : abs(RN) % range; | |
259 } | |
260 | |
261 /* | |
262 * roll: | |
263 * roll a number of dice | |
264 */ | |
265 | |
266 int | |
267 roll(int number, int sides) | |
268 { | |
269 int dtotal = 0; | |
270 | |
271 while(number--) | |
272 dtotal += rnd(sides)+1; | |
273 return dtotal; | |
274 } | |
275 /* | |
276 * handle stop and start signals | |
277 */ | |
278 | |
279 void | |
280 tstp(int p) | |
281 { | |
282 #ifdef SIGTSTP | |
283 signal(SIGTSTP, SIG_IGN); | |
284 #endif | |
285 mvcur(0, COLS - 1, LINES - 1, 0); | |
286 endwin(); | |
287 fflush(stdout); | |
288 #ifdef SIGTSTP | |
289 signal(SIGTSTP, SIG_DFL); | |
290 kill(0, SIGTSTP); | |
291 signal(SIGTSTP, tstp); | |
292 #endif | |
293 crmode(); | |
294 noecho(); | |
295 clearok(curscr, TRUE); | |
296 touchwin(cw); | |
297 draw(cw); | |
298 flush_type(); /* flush input */ | |
299 } | |
300 | |
301 void | |
302 setup() | |
303 { | |
304 #ifdef SIGHUP | |
305 signal(SIGHUP, auto_save); | |
306 #endif | |
307 signal(SIGILL, auto_save); | |
308 #ifdef SIGTRAP | |
309 signal(SIGTRAP, auto_save); | |
310 #endif | |
311 #ifdef SIGIOT | |
312 signal(SIGIOT, auto_save); | |
313 #endif | |
314 #ifdef SIGEMT | |
315 signal(SIGEMT, auto_save); | |
316 #endif | |
317 signal(SIGFPE, auto_save); | |
318 #ifdef SIGBUS | |
319 signal(SIGBUS, auto_save); | |
320 #endif | |
321 signal(SIGSEGV, auto_save); | |
322 #ifdef SIGSYS | |
323 signal(SIGSYS, auto_save); | |
324 #endif | |
325 #ifdef SIGPIPE | |
326 signal(SIGPIPE, auto_save); | |
327 #endif | |
328 signal(SIGTERM, auto_save); | |
329 signal(SIGINT, quit); | |
330 #ifdef SIGQUIT | |
331 signal(SIGQUIT, endit); | |
332 #endif | |
333 #ifdef SIGTSTP | |
334 signal(SIGTSTP, tstp); | |
335 #endif | |
336 | |
337 if (!author()) | |
338 { | |
339 #ifdef SIGALRM | |
340 signal(SIGALRM, checkout); | |
341 alarm(CHECKTIME * 60); | |
342 #endif | |
343 num_checks = 0; | |
344 } | |
345 | |
346 crmode(); /* Cbreak mode */ | |
347 noecho(); /* Echo off */ | |
348 } | |
349 | |
350 /* | |
351 * playit: | |
352 * The main loop of the program. Loop until the game is over, | |
353 * refreshing things and looking at the proper times. | |
354 */ | |
355 | |
356 void | |
357 playit() | |
358 { | |
359 char *opts; | |
360 | |
361 /* | |
362 * set up defaults for slow terminals | |
363 */ | |
364 | |
365 | |
366 if (baudrate() < 1200) | |
367 { | |
368 terse = TRUE; | |
369 jump = TRUE; | |
370 } | |
371 | |
372 /* | |
373 * parse environment declaration of options | |
374 */ | |
375 if ((opts = getenv("ROGUEOPTS")) != NULL) | |
376 parse_opts(opts); | |
377 | |
378 | |
379 oldpos = hero; | |
380 oldrp = roomin(&hero); | |
381 while (playing) | |
382 command(); /* Command execution */ | |
383 endit(-1); | |
384 } | |
385 | |
386 /* | |
387 * see if the system is being used too much for this game | |