comparison 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
comparison
equal deleted inserted replaced
35:05018c63a721 36:2128c7dc8a40
1 /*
2 * Rogue
3 * Exploring the dungeons of doom
4 *
5 * @(#)main.c 9.0 (rdk) 7/17/84
6 *
7 * Super-Rogue
8 * Copyright (C) 1984 Robert D. Kindelberger
9 * All rights reserved.
10 *
11 * Based on "Rogue: Exploring the Dungeons of Doom"
12 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
13 * All rights reserved.
14 *
15 * See the file LICENSE.TXT for full copyright and licensing information.
16 */
17
18 #include <time.h>
19 #include <termios.h>
20 #include <fcntl.h>
21 #include <stdio.h>
22 #include <signal.h>
23 #include <pwd.h>
24 #include <limits.h>
25 #include <sys/stat.h>
26 #include "rogue.h"
27
28 #ifdef ATT
29 #include <time.h>
30 #endif
31
32 #ifdef BSD
33 #define srand48(seed) srandom(seed)
34 #define lrand48() random()
35 #include <sys/time.h>
36 #endif
37
38 #include "rogue.ext"
39
40 struct termios terminal;
41
42 main(argc, argv, envp)
43 char **argv;
44 char **envp;
45 {
46 register char *env;
47 register struct linked_list *item;
48 register struct object *obj;
49 struct passwd *pw;
50 struct passwd *getpwuid();
51 char alldone, wpt;
52 char *getpass(), *xcrypt(), *strrchr();
53 int lowtime;
54 time_t now;
55 char *roguehome();
56 char *homedir = roguehome();
57
58 #ifdef __DJGPP__
59 _fmode = O_BINARY;
60 #endif
61
62 if (homedir == NULL)
63 homedir = "";
64
65 playuid = getuid();
66
67 if (setuid(playuid) < 0) {
68 printf("Cannot change to effective uid: %d\n", playuid);
69 exit(1);
70 }
71 playgid = getgid();
72
73 /* check for print-score option */
74
75 strcpy(scorefile, homedir);
76
77 if (*scorefile)
78 strcat(scorefile,"/");
79 strcat(scorefile, "srogue.scr");
80
81 if(argc >= 2 && strcmp(argv[1], "-s") == 0)
82 {
83 showtop(0);
84 exit(0);
85 }
86
87 if (argc >= 2 && author() && strcmp(argv[1],"-a") == 0)
88 {
89 wizard = TRUE;
90 argv++;
91 argc--;
92 }
93
94 /* Check to see if he is a wizard */
95
96 if (argc >= 2 && strcmp(argv[1],"-w") == 0)
97 {
98 if (strcmp(PASSWD, xcrypt(getpass(wizstr),"mT")) == 0)
99 {
100 wizard = TRUE;
101 argv++;
102 argc--;
103 }
104 }
105 time(&now);
106 lowtime = (int) now;
107
108 /* get home and options from environment */
109
110 if ((env = getenv("HOME")) != NULL)
111 strcpy(home, env);
112 else if ((pw = getpwuid(playuid)) != NULL)
113 strcpy(home, pw->pw_dir);
114 else
115 home[0] = '\0';
116
117 if (strcmp(home,"/") == 0)
118 home[0] = '\0';
119
120 if ((strlen(home) > 0) && (home[strlen(home)-1] != '/'))
121 strcat(home, "/");
122
123 strcpy(file_name, home);
124 strcat(file_name, "srogue.sav");
125
126 if ((env = getenv("ROGUEOPTS")) != NULL)
127 parse_opts(env);
128
129 if (env == NULL || whoami[0] == '\0')
130 {
131 if((pw = getpwuid(playuid)) == NULL)
132 {
133 printf("Say, who are you?\n");
134 exit(1);
135 }
136 else
137 strucpy(whoami, pw->pw_name, strlen(pw->pw_name));
138 }
139
140 if (env == NULL || fruit[0] == '\0')
141 strcpy(fruit, "juicy-fruit");
142
143 if (argc == 2)
144 if(!restore(argv[1], envp)) /* NOTE: NEVER RETURNS */
145 exit(1);
146
147 dnum = (wizard && getenv("SEED") != NULL ?
148 atoi(getenv("SEED")) : lowtime + getpid());
149
150 if(wizard)
151 printf("Hello %s, welcome to dungeon #%d\n", whoami, dnum);
152 else
153 printf("Hello %s, One moment while I open the door to the dungeon...\n", whoami);
154
155 fflush(stdout);
156 seed = dnum;
157 srand48(seed); /* init rnd number gen */
158
159 signal(SIGINT, byebye); /* just in case */
160 signal(SIGQUIT ,byebye);
161
162 init_everything();
163
164 #ifdef __INTERIX
165 setenv("TERM","interix");
166 #endif
167
168 initscr(); /* Start up cursor package */
169
170 if (strcmp(termname(),"dumb") == 0)
171 {
172 endwin();
173 printf("ERROR in terminal parameters.\n");
174 printf("Check TERM in environment.\n");
175 byebye(1);
176 }
177
178 if (LINES < 24 || COLS < 80) {
179 endwin();
180 printf("ERROR: screen size too small\n");
181 byebye(1);
182 }
183
184 if ((whoami == NULL) || (*whoami == '\0') || (strcmp(whoami,"dosuser")==0))
185 {
186 echo();
187 mvaddstr(23,2,"Rogue's Name? ");
188 wgetnstr(stdscr,whoami,MAXSTR);
189 noecho();
190 }
191
192 if ((whoami == NULL) || (*whoami == '\0'))
193 strcpy(whoami,"Rodney");
194
195 setup();
196
197 /* Set up windows */
198
199 cw = newwin(0, 0, 0, 0);
200 mw = newwin(0, 0, 0, 0);
201 hw = newwin(0, 0, 0, 0);
202 waswizard = wizard;
203
204 /* Draw current level */
205
206 new_level(NORMLEV);
207
208 /* Start up daemons and fuses */
209
210 daemon(status, TRUE, BEFORE);
211 daemon(doctor, TRUE, BEFORE);
212 daemon(stomach, TRUE, BEFORE);
213 daemon(runners, TRUE, AFTER);
214 fuse(swander, TRUE, WANDERTIME);
215
216 /* Give the rogue his weaponry */
217
218 do {
219 wpt = pick_one(w_magic);
220 switch (wpt)
221 {
222 case MACE: case SWORD: case TWOSWORD:
223 case SPEAR: case TRIDENT: case SPETUM:
224 case BARDICHE: case PIKE: case BASWORD:
225 case HALBERD:
226 alldone = TRUE;
227 otherwise:
228 alldone = FALSE;
229 }
230 } while(!alldone);
231
232 item = new_thing(FALSE, WEAPON, wpt);
233 obj = OBJPTR(item);
234 obj->o_hplus = rnd(3);
235 obj->o_dplus = rnd(3);
236 obj->o_flags = ISKNOW;
237 add_pack(item, TRUE);
238 cur_weapon = obj;
239
240 /* Now a bow */
241
242 item = new_thing(FALSE, WEAPON, BOW);
243 obj = OBJPTR(item);
244 obj->o_hplus = rnd(3);
245 obj->o_dplus = rnd(3);
246 obj->o_flags = ISKNOW;
247 add_pack(item, TRUE);
248
249 /* Now some arrows */
250
251 item = new_thing(FALSE, WEAPON, ARROW);
252 obj = OBJPTR(item);
253 obj->o_count = 25 + rnd(15);
254 obj->o_hplus = rnd(2);
255 obj->o_dplus = rnd(2);
256 obj->o_flags = ISKNOW;
257 add_pack(item, TRUE);
258
259 /* And his suit of armor */
260
261 wpt = pick_one(a_magic);
262 item = new_thing(FALSE, ARMOR, wpt);
263 obj = OBJPTR(item);
264 obj->o_flags = ISKNOW;
265 obj->o_ac = armors[wpt].a_class - rnd(4);
266 cur_armor = obj;
267 add_pack(item, TRUE);
268
269 /* Give him some food */
270
271 item = new_thing(FALSE, FOOD, 0);
272 add_pack(item, TRUE);
273
274 playit();
275 }
276
277
278 /*
279 * endit:
280 * Exit the program abnormally.
281 */
282 void
283 endit(int a)
284 {
285 fatal("Ok, if you want to exit that badly, I'll have to allow it");
286 }
287
288 /*
289 * fatal:
290 * Exit the program, printing a message.
291 */
292
293 fatal(s)
294 char *s;
295 {
296 clear();
297 refresh();
298 endwin();
299 fprintf(stderr,"%s\n\r",s);
300 fflush(stderr);
301 byebye(2);
302 }
303
304 /*
305 * byebye:
306 * Exit here and reset the users terminal parameters
307 * to the way they were when he started
308 */
309
310 void
311 byebye(how)
312 int how;
313 {
314 if (!isendwin())
315 endwin();
316
317 exit(how); /* exit like flag says */
318 }
319
320
321 /*
322 * rnd:
323 * Pick a very random number.
324 */
325 rnd(range)
326 int range;
327 {
328 reg int wh;
329
330 if (range == 0)
331 wh = 0;
332 else {
333 wh = lrand48() % range;
334 wh &= 0x7FFFFFFF;
335 }
336 return wh;
337 }
338
339 /*
340 * roll:
341 * roll a number of dice
342 */
343 roll(number, sides)
344 int number, sides;
345 {
346 reg int dtotal = 0;
347
348 while(number-- > 0)
349 dtotal += rnd(sides)+1;
350 return dtotal;
351 }
352
353
354 /*
355 ** setup: Setup signal catching functions
356 */
357 setup()
358 {
359 signal(SIGHUP, auto_save);
360 signal(SIGINT, auto_save);
361 signal(SIGQUIT, byebye);
362 signal(SIGILL, game_err);
363 signal(SIGTRAP, game_err);
364 #ifdef SIGIOT
365 signal(SIGIOT, game_err);
366 #endif
367 #ifdef SIGEMT
368 signal(SIGEMT, game_err);
369 #endif
370 signal(SIGFPE, game_err);
371 #ifdef SIGBUS
372 signal(SIGBUS, game_err);
373 #endif
374 signal(SIGSEGV, game_err);
375 #ifdef SIGSYS
376 signal(SIGSYS, game_err);
377 #endif
378 signal(SIGPIPE, game_err);
379 signal(SIGTERM, game_err);
380
381 cbreak();
382 noecho();
383 }
384
385 /*
386 ** playit: The main loop of the program. Loop until the game is over,
387 ** refreshing things and looking at the proper times.
388 */
389
390 playit()
391 {
392 reg char *opts;
393
394 tcgetattr(0,&terminal);
395
396
397 /* parse environment declaration of options */
398
399 if ((opts = getenv("ROGUEOPTS")) != NULL)
400 parse_opts(opts);
401
402 player.t_oldpos = hero;
403 oldrp = roomin(&hero);
404 nochange = FALSE;
405 while (playing)
406 command(); /* Command execution */
407 endit(0);
408 }
409
410
411 /*
412 ** author: See if a user is an author of the program
413 */
414 author()
415 {
416 switch (playuid) {
417 case 100:
418 case 0:
419 return TRUE;
420 default:
421 return FALSE;
422 }
423 }
424
425 int
426 directory_exists(char *dirname)
427 {
428 struct stat sb;
429
430 if (stat(dirname, &sb) == 0) /* path exists */
431 return (S_ISDIR (sb.st_mode));
432
433 return(0);
434 }
435
436 char *
437 roguehome()
438 {
439 static char path[1024];
440 char *end,*home;
441
442 if ( (home = getenv("ROGUEHOME")) != NULL)
443 {
444 if (*home)
445 {
446 strncpy(path, home, PATH_MAX - 20);
447
448 end = &path[strlen(path)-1];
449
450
451 while( (end >= path) && ((*end == '/') || (*end == '\\')))
452 *end-- = '\0';
453
454 if (directory_exists(path))
455 return(path);
456 }
457 }
458
459 if (directory_exists("/var/games/roguelike"))
460 return("/var/games/roguelike");
461 if (directory_exists("/var/lib/roguelike"))
462 return("/var/lib/roguelike");
463 if (directory_exists("/var/roguelike"))
464 return("/var/roguelike");
465 if (directory_exists("/usr/games/lib"))
466 return("/usr/games/lib");
467 if (directory_exists("/games/roguelik"))
468 return("/games/roguelik");
469
470 return(NULL);
471 }
472