Annotation of early-roguelike/srogue/main.c, Revision 1.1.1.1
1.1 rubenllo 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 <stdlib.h>
19: #include <string.h>
20: #include <time.h>
21: #include <fcntl.h>
22: #include <stdio.h>
23: #include <limits.h>
24: #include <errno.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: #include <sys/time.h>
34: #endif
35:
36: #include "rogue.ext"
37:
38: char *roguehome(void);
39: void open_records(void);
40:
41: extern FILE *scoreboard;
42: extern FILE *logfile;
43:
44: int
45: main(int argc, char *argv[], char *envp[])
46: {
47: register char *env;
48: register struct linked_list *item;
49: register struct object *obj;
50: char alldone;
51: int wpt;
52: char *getpass(), *xcrypt(), *strrchr();
53: char *homedir = roguehome();
54:
55: md_init();
56:
57: if (homedir == NULL)
58: homedir = "";
59:
60: playuid = md_getuid();
61: playgid = md_getgid();
62:
63: /* check for print-score option */
64: #ifdef SCOREFILE
65: strncpy(scorefile, SCOREFILE, LINLEN);
66: scorefile[LINLEN - 1] = '\0';
67: #else
68:
69: strncpy(scorefile, homedir, LINLEN-11);
70: if (scorefile[LINLEN-12] != '\0')
71: scorefile[0] = '\0';
72:
73: if (*scorefile)
74: strcat(scorefile,"/");
75: strcat(scorefile, "srogue.scr");
76: #endif
77: open_records();
78:
79: if(argc >= 2 && strcmp(argv[1], "-s") == 0)
80: {
81: showtop(0);
82: exit(0);
83: }
84:
85: #ifdef WIZARD
86: if (argc >= 2 && author() && strcmp(argv[1],"-a") == 0)
87: {
88: wizard = TRUE;
89: argv++;
90: argc--;
91: }
92:
93: /* Check to see if he is a wizard */
94:
95: if (argc >= 2 && strcmp(argv[1],"-w") == 0)
96: {
97: if (strcmp(PASSWD, xcrypt(getpass(wizstr),"mT")) == 0)
98: {
99: wizard = TRUE;
100: argv++;
101: argc--;
102: }
103: }
104: #endif
105:
106: #ifdef SAVEDIR
107: if (argc >= 3 && !strcmp(argv[1], "-n")) {
108: strncpy(whoami, argv[2], LINLEN);
109: whoami[LINLEN - 1] = '\0';
110: use_savedir = TRUE;
111: if (snprintf(file_name, 256, "%s/%d-%s.srsav", SAVEDIR,
112: playuid, whoami) >= 256) {
113: /* Just in case it doesn't fit */
114: strcpy(file_name, "srogue.save");
115: use_savedir = FALSE;
116: }
117: }
118: #endif
119:
120: if (!use_savedir)
121: md_normaluser();
122:
123: /* get home and options from environment */
124:
125: if ((env = getenv("HOME")) != NULL)
126: strcpy(home, env);
127: else {
128: strncpy(home, md_gethomedir(), LINLEN);
129: if (home[LINLEN-1] != '\0')
130: home[0] = '\0';
131: }
132:
133: if (strcmp(home,"/") == 0)
134: home[0] = '\0';
135:
136: if ((strlen(home) > 0) && (home[strlen(home)-1] != '/'))
137: strcat(home, "/");
138:
139: if (!use_savedir) {
140: strcpy(file_name, home);
141: strcat(file_name, "srogue.sav");
142: }
143:
144: if ((env = getenv("ROGUEOPTS")) != NULL)
145: parse_opts(env);
146:
147: if (!use_savedir && (env == NULL || whoami[0] == '\0'))
148: {
149: strucpy(whoami, md_getusername(), strlen(md_getusername()));
150: }
151:
152: if (env == NULL || fruit[0] == '\0')
153: strcpy(fruit, "juicy-fruit");
154:
155: if (use_savedir)
156: {
157: /* restore() won't return if the restore succeeded. If
158: * file_name doesn't exist, it will return TRUE. In that
159: * case, start a new game. */
160: if (!restore(file_name, envp))
161: exit(1);
162: }
163: else if (argc == 2)
164: if(!restore(argv[1], envp)) /* NOTE: NEVER RETURNS */
165: exit(1);
166:
167: /* START NEW GAME */
168:
169: dnum = (wizard && getenv("SEED") != NULL ?
170: atoi(getenv("SEED")) : md_random_seed());
171:
172: if(wizard)
173: printf("Hello %s, welcome to dungeon #%d\n", whoami, dnum);
174: else
175: printf("Hello %s, One moment while I open the door to the dungeon...\n", whoami);
176:
177: fflush(stdout);
178: seed = dnum;
179: md_srandom(seed); /* init rnd number gen */
180:
181: md_onsignal_exit(); /* just in case */
182:
183: init_everything();
184:
185: #ifdef __INTERIX
186: setenv("TERM","interix");
187: #endif
188:
189: initscr(); /* Start up cursor package */
190:
191: if (strcmp(termname(),"dumb") == 0)
192: {
193: endwin();
194: printf("ERROR in terminal parameters.\n");
195: printf("Check TERM in environment.\n");
196: byebye(1);
197: }
198:
199: if (LINES < 24 || COLS < 80) {
200: endwin();
201: printf("ERROR: screen size too small\n");
202: byebye(1);
203: }
204:
205: if ((*whoami == '\0') || (strcmp(whoami,"dosuser")==0))
206: {
207: echo();
208: mvaddstr(23,2,"Rogue's Name? ");
209: wgetnstr(stdscr,whoami,MAXSTR);
210: noecho();
211: }
212:
213: if (*whoami == '\0')
214: strcpy(whoami,"Rodney");
215:
216: setup();
217:
218: /* Set up windows */
219:
220: cw = newwin(0, 0, 0, 0);
221: mw = newwin(0, 0, 0, 0);
222: hw = newwin(0, 0, 0, 0);
223: keypad(cw, 1);
224: waswizard = wizard;
225:
226: /* Draw current level */
227:
228: new_level(NORMLEV);
229:
230: /* Start up daemons and fuses */
231:
232: start_daemon(status, TRUE, BEFORE);
233: start_daemon(runners, TRUE, AFTER);
234: /*
235: * These daemons have been moved to AFTER because BEFORE daemons
236: * get called every command, even invalid ones. Hopefully this
237: * won't break anything.
238: */
239: start_daemon(doctor, TRUE, AFTER);
240: start_daemon(stomach, TRUE, AFTER);
241: fuse(swander, TRUE, WANDERTIME);
242:
243: /* Give the rogue his weaponry */
244:
245: do {
246: wpt = pick_one(w_magic);
247: switch (wpt)
248: {
249: case MACE: case SWORD: case TWOSWORD:
250: case SPEAR: case TRIDENT: case SPETUM:
251: case BARDICHE: case PIKE: case BASWORD:
252: case HALBERD:
253: alldone = TRUE;
254: otherwise:
255: alldone = FALSE;
256: }
257: } while(!alldone);
258:
259: item = new_thing(FALSE, WEAPON, wpt);
260: obj = OBJPTR(item);
261: obj->o_hplus = rnd(3);
262: obj->o_dplus = rnd(3);
263: obj->o_flags = ISKNOW;
264: add_pack(item, TRUE);
265: cur_weapon = obj;
266:
267: /* Now a bow */
268:
269: item = new_thing(FALSE, WEAPON, BOW);
270: obj = OBJPTR(item);
271: obj->o_hplus = rnd(3);
272: obj->o_dplus = rnd(3);
273: obj->o_flags = ISKNOW;
274: add_pack(item, TRUE);
275:
276: /* Now some arrows */
277:
278: item = new_thing(FALSE, WEAPON, ARROW);
279: obj = OBJPTR(item);
280: obj->o_count = 25 + rnd(15);
281: obj->o_hplus = rnd(2);
282: obj->o_dplus = rnd(2);
283: obj->o_flags = ISKNOW;
284: add_pack(item, TRUE);
285:
286: /* And his suit of armor */
287:
288: wpt = pick_one(a_magic);
289: item = new_thing(FALSE, ARMOR, wpt);
290: obj = OBJPTR(item);
291: obj->o_flags = ISKNOW;
292: obj->o_ac = armors[wpt].a_class - rnd(4);
293: cur_armor = obj;
294: add_pack(item, TRUE);
295:
296: /* Give him some food */
297:
298: item = new_thing(FALSE, FOOD, 0);
299: add_pack(item, TRUE);
300:
301: playit();
302: }
303:
304:
305: /*
306: * endit:
307: * Exit the program abnormally.
308: */
309: void
310: endit(int a)
311: {
312: fatal("Ok, if you want to exit that badly, I'll have to allow it");
313: }
314:
315: /*
316: * fatal:
317: * Exit the program, printing a message.
318: */
319:
320: void
321: fatal(char *s)
322: {
323: clear();
324: refresh();
325: endwin();
326: fprintf(stderr,"%s\n\r",s);
327: fflush(stderr);
328: byebye(2);
329: }
330:
331: /*
332: * byebye:
333: * Exit here and reset the users terminal parameters
334: * to the way they were when he started
335: */
336:
337: void
338: byebye(int how)
339: {
340: if (!isendwin())
341: endwin();
342:
343: exit(how); /* exit like flag says */
344: }
345:
346:
347: /*
348: * rnd:
349: * Pick a very random number.
350: */
351: int
352: rnd(int range)
353: {
354: reg int wh;
355:
356: if (range == 0)
357: wh = 0;
358: else {
359: wh = md_random() % range;
360: wh &= 0x7FFFFFFF;
361: }
362: return wh;
363: }
364:
365: /*
366: * roll:
367: * roll a number of dice
368: */
369: int
370: roll(int number, int sides)
371: {
372: reg int dtotal = 0;
373:
374: while(number-- > 0)
375: dtotal += rnd(sides)+1;
376: return dtotal;
377: }
378:
379:
380: /*
381: ** setup: Setup signal catching functions
382: */
383: void
384: setup(void)
385: {
386: md_onsignal_autosave();
387:
388: nonl();
389: cbreak();
390: noecho();
391: }
392:
393: /*
394: ** playit: The main loop of the program. Loop until the game is over,
395: ** refreshing things and looking at the proper times.
396: */
397:
398: void
399: playit(void)
400: {
401: reg char *opts;
402:
403: /* parse environment declaration of options */
404:
405: if ((opts = getenv("ROGUEOPTS")) != NULL)
406: parse_opts(opts);
407:
408: player.t_oldpos = hero;
409: oldrp = roomin(&hero);
410: nochange = FALSE;
411: while (playing)
412: command(); /* Command execution */
413: endit(0);
414: }
415:
416:
417: /*
418: ** author: See if a user is an author of the program
419: */
420: bool
421: author(void)
422: {
423: switch (playuid) {
424: case 100:
425: case 0:
426: return TRUE;
427: default:
428: return FALSE;
429: }
430: }
431:
432: int
433: directory_exists(char *dirname)
434: {
435: struct stat sb;
436:
437: if (stat(dirname, &sb) == 0) /* path exists */
438: return ((sb.st_mode & S_IFMT) == S_IFDIR);
439:
440: return(0);
441: }
442:
443: char *
444: roguehome(void)
445: {
446: static char path[LINLEN+16];
447: char *end,*home;
448:
449: if ( (home = getenv("ROGUEHOME")) != NULL)
450: {
451: if (*home)
452: {
453: /* LINLEN - 11 is all that will fit into scorefile */
454: strncpy(path, home, LINLEN - 11);
455: if (path[LINLEN - 12] == '\0')
456: {
457: end = &path[strlen(path)-1];
458: while( (end >= path) && ((*end == '/') || (*end == '\\')))
459: *end-- = '\0';
460:
461: if (directory_exists(path))
462: return(path);
463: }
464: /* Otherwise home was truncated and should be ignored */
465: }
466: }
467:
468: if (directory_exists("/var/games/roguelike"))
469: return("/var/games/roguelike");
470: if (directory_exists("/var/lib/roguelike"))
471: return("/var/lib/roguelike");
472: if (directory_exists("/var/roguelike"))
473: return("/var/roguelike");
474: if (directory_exists("/usr/games/lib"))
475: return("/usr/games/lib");
476: if (directory_exists("/games/roguelik"))
477: return("/games/roguelik");
478:
479: return(NULL);
480: }
481:
482: void
483: open_records(void)
484: {
485: if (scoreboard == NULL)
486: scoreboard = fopen(scorefile, "r+");
487: if (scoreboard == NULL && errno == ENOENT) {
488: scoreboard = fopen(scorefile, "w+");
489: }
490: #ifdef LOGFILE
491: if (logfile == NULL)
492: logfile = fopen(LOGFILE, "a");
493: #endif
494: }
495:
CVSweb