Annotation of early-roguelike/xrogue/main.c, Revision 1.1.1.1
1.1 rubenllo 1: /*
2: main.c - setup code
3:
4: XRogue: Expeditions into the Dungeons of Doom
5: Copyright (C) 1991 Robert Pietkivitch
6: All rights reserved.
7:
8: Based on "Advanced Rogue"
9: Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10: All rights reserved.
11:
12: Based on "Rogue: Exploring the Dungeons of Doom"
13: Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14: All rights reserved.
15:
16: See the file LICENSE.TXT for full copyright and licensing information.
17: */
18:
19: #include <stdlib.h>
20: #include <string.h>
21: #include <curses.h>
22: #include <signal.h>
23: #include <time.h>
24:
25: #include "mach_dep.h"
26: #include "network.h"
27: #include "rogue.h"
28:
29: void open_records(void);
30: bool too_much(void);
31: bool author(void);
32: bool playtime(void);
33: bool betaover(void);
34:
35: int
36: main(int argc, char *argv[], char *envp[])
37: {
38: register char *env;
39: time_t now;
40:
41: md_init();
42:
43: /*
44: * get home and options from environment
45: */
46:
47: strncpy(home, md_gethomedir(), LINELEN);
48:
49: /* Get default save file */
50: strcpy(file_name, home);
51: strcat(file_name, "xrogue.sav");
52:
53: /* Get default score file */
54: #ifdef SCOREFILE
55: strncpy(score_file, SCOREFILE, LINELEN);
56: score_file[LINELEN-1] = '\0';
57: #else
58: strcpy(score_file, md_getroguedir());
59:
60: if (*score_file)
61: strcat(score_file,"/");
62:
63: strcat(score_file, "xrogue.scr");
64: #endif
65:
66: #ifdef SAVEDIR
67: /* Check for common save location */
68: if (argc >= 3 && strcmp(argv[1], "-n") == 0)
69: {
70: strncpy(whoami, argv[2], 79);
71: whoami[79] = '\0';
72: use_savedir = TRUE;
73: if (LINELEN <= snprintf(file_name, LINELEN, "%s/%d-%s.xrsav", SAVEDIR,
74: md_getuid(), whoami))
75: {
76: strcpy(file_name, "xrogue.sav");
77: use_savedir = FALSE;
78: }
79: }
80: #endif
81:
82: if ((env = getenv("ROGUEOPTS")) != NULL)
83: parse_opts(env);
84:
85: if (whoami[0] == '\0')
86: strucpy(whoami, md_getusername(), strlen(md_getusername()));
87:
88: open_records();
89: if (!use_savedir)
90: md_normaluser();
91: /*
92: * check for print-score option
93: */
94: if (argc == 2 && strcmp(argv[1], "-s") == 0)
95: {
96: waswizard = TRUE;
97: score((long)0, SCOREIT, (short)0);
98: exit_game(0);
99: }
100:
101: /*
102: * Check for a network update
103: */
104: if (argc == 2 && strcmp(argv[1], "-u") == 0) {
105: int errcheck, errors = 0;
106: unsigned long amount;
107: short monster;
108:
109: /* Read in the amount and monster values to pass to score */
110: amount = netread(&errcheck, sizeof(unsigned long), stdin);
111: if (errcheck) errors++;
112:
113: monster = (short) netread(&errcheck, sizeof(short), stdin);
114: if (errcheck) errors++;
115:
116: /* Now do the update if there were no errors */
117: if (errors) exit_game(0);
118: else {
119: score((long)amount, UPDATE, (short)monster);
120: exit_game(0);
121: }
122: }
123:
124: /*
125: * Check to see if he is a wizard
126: */
127: #ifdef WIZARD
128: if (argc >= 2 && argv[1][0] == '\0')
129: if (strcmp(PASSWD, xcrypt(md_getpass("Wizard's password: "), "mT")) == 0)
130: {
131: wizard = TRUE;
132: argv++;
133: argc--;
134: }
135: #endif
136:
137: if (betaover())
138: {
139: printf("Sorry, %s, but the test period of this prerelease version\n",whoami);
140: printf("of xrogue is over. Please acquire a new version. Sorry.\n");
141: exit_game(0);
142: }
143:
144: if (!wizard && !author() && !playtime()) {
145: printf("Sorry, %s, but you can't play during working hours.\n", whoami);
146: printf("Try again later.\n");
147: exit_game(0);
148: }
149: if (!wizard && !author() && too_much()) {
150: printf("Sorry, %s, but the system is too loaded now.\n", whoami);
151: printf("Try again later.\n");
152: exit_game(0);
153: }
154:
155: if (use_savedir)
156: {
157: /* restore() will return TRUE if a new game should be started. */
158: if (!restore(file_name, envp))
159: exit_game(0);
160: }
161: if (argc == 2)
162: if (!restore(argv[1], envp)) /* Note: restore will never return */
163: exit_game(0);
164:
165: if (wizard && getenv("SEED") != NULL) {
166: seed = atoi(getenv("SEED"));
167: }
168: else {
169: seed = md_random_seed();
170: }
171: if (wizard)
172: printf("Hello %s, welcome to dungeon #%d\n", whoami, seed);
173: else
174: printf("Hello %s, just a moment while I dig the dungeon...\n", whoami);
175: fflush(stdout);
176:
177: md_srand(seed);
178:
179: init_things(); /* Set up probabilities of things */
180: init_colors(); /* Set up colors of potions */
181: init_stones(); /* Set up stone settings of rings */
182: init_materials(); /* Set up materials of wands */
183: init_names(); /* Set up names of scrolls */
184: init_misc(); /* Set up miscellaneous magic */
185: init_foods(); /* set up the food table */
186:
187: initscr(); /* Start up cursor package */
188:
189: typeahead(-1); /* turn off 3.2/4.0 curses feature */
190:
191: if (COLS < MINCOLS)
192: {
193: printf("\n\nSorry, %s, but your terminal window has too few columns.\n", whoami);
194: printf("Your terminal has %d columns, needs 70.\n",COLS);
195: byebye(0);
196: }
197: if (LINES < MINLINES)
198: {
199: printf("\n\nSorry, %s, but your terminal window has too few lines.\n", whoami);
200: printf("Your terminal has %d lines, needs 22.\n",LINES);
201: byebye(0);
202: }
203:
204: cols = COLS;
205: lines = LINES;
206:
207: if ( cols % 2 != 0) cols -=1; /* must be even for maze code */
208: if (lines % 2 != 0) lines -=1; /* must be even for maze code */
209:
210: /*
211: * Now that we have cols and lines, we can update our window
212: * structure for non-hardware windows.
213: */
214: setup();
215: /*
216: * Set up windows
217: */
218: cw = newwin(lines, cols, 0, 0);
219: mw = newwin(lines, cols, 0, 0);
220: hw = newwin(lines, cols, 0, 0);
221: msgw = newwin(4, cols, 0, 0);
222: if (cw == NULL || hw == NULL || mw == NULL || msgw == NULL) {
223: exit_game(EXIT_CLS | EXIT_ENDWIN);
224: }
225:
226: keypad(cw, TRUE);
227: keypad(hw, TRUE);
228:
229: init_player(); /* Roll up the rogue */
230: waswizard = wizard;
231:
232: draw(cw);
233: /* A super wizard doesn't have to get equipped */
234: /* Check if "" option is TRUE and get environment flag */
235: if (wizard && strcmp(getenv("SUPER"),"YES") == 0 ||
236: def_attr == TRUE) {
237: level = 1;
238: new_level(NORMLEV);
239: }
240: else
241: new_level(STARTLEV); /* Draw current level */
242:
243: /*
244: * Start up daemons and fuses
245: */
246: start_daemon(doctor, &player, AFTER);
247: fuse(swander, NULL, WANDERTIME, AFTER);
248: /* Give characters their innate abilities */
249: if (player.t_ctype == C_MAGICIAN || player.t_ctype == C_RANGER)
250: fuse(spell_recovery, NULL, SPELLTIME, AFTER);
251: if (player.t_ctype == C_DRUID || player.t_ctype == C_MONK)
252: fuse(chant_recovery, NULL, SPELLTIME, AFTER);
253: if (player.t_ctype == C_CLERIC || player.t_ctype == C_PALADIN)
254: fuse(prayer_recovery, NULL, SPELLTIME, AFTER);
255: start_daemon(stomach, NULL, AFTER);
256: if (player.t_ctype == C_THIEF ||
257: player.t_ctype == C_ASSASSIN ||
258: player.t_ctype == C_MONK)
259: start_daemon(trap_look, NULL, AFTER);
260:
261: /* Does this character have any special knowledge? */
262: switch (player.t_ctype) {
263: case C_ASSASSIN:
264: /* Assassins automatically recognize poison */
265: p_know[P_POISON] = TRUE;
266: when C_FIGHTER:
267: /* Fighters automatically recognize skill */
268: p_know[P_SKILL] = TRUE;
269: }
270:
271: /* Choose an initial quest item */
272: if (!wizard) {
273: if (def_attr == FALSE)
274: quest_item = rnd(MAXRELIC);
275: }
276: mpos = 0;
277: draw(cw);
278: msg("You have been quested to retrieve the %s....",
279: rel_magic[quest_item].mi_name);
280: mpos = 0;
281: playit();
282: }
283:
284: /*
285: * endit:
286: * Exit the program abnormally.
287: */
288:
289: void
290: endit(int sig)
291: {
292: NOOP(sig);
293: fatal("Ok, if you want to exit that badly, I'll have to allow it\n");
294: }
295:
296: /*
297: * fatal:
298: * Exit the program, printing a message.
299: */
300:
301: void
302: fatal(char *s)
303: {
304: clear();
305: move(lines-2, 0);
306: printw("%s", s);
307: draw(stdscr);
308: printf("\n"); /* So the curser doesn't stop at the end of the line */
309: exit_game(EXIT_ENDWIN);
310: }
311:
312: /*
313: * rnd:
314: * Pick a very random number.
315: */
316:
317: int
318: rnd(int range)
319: {
320: return( md_rand(range) );
321: }
322:
323: /*
324: * roll:
325: * roll a number of dice
326: */
327:
328: int
329: roll(int number, int sides)
330: {
331: register int dtotal = 0;
332:
333: while(number--)
334: dtotal += rnd(sides)+1;
335: return dtotal;
336: }
337:
338: void
339: setup(void)
340: {
341: md_setup();
342: }
343:
344: /*
345: * playit:
346: * The main loop of the program. Loop until the game is over,
347: * refreshing things and looking at the proper times.
348: */
349:
350: void
351: playit(void)
352: {
353: register char *opts;
354:
355: /*
356: * parse environment declaration of options
357: */
358: if ((opts = getenv("ROGUEOPTS")) != NULL)
359: parse_opts(opts);
360:
361: player.t_oldpos = hero;
362: oldrp = roomin(&hero);
363: after = TRUE;
364: command(); /* Command execution */
365: endit(-1);
366: }
367:
368: /*
369: * see if the system is being used too much for this game
370: */
371:
372: bool
373: too_much(void)
374: {
375: /* we no longer do load checking or user counts */
376: return(FALSE);
377: }
378:
379: /*
380: * author:
381: * See if a user is an author of the program
382: */
383:
384: bool
385: author(void)
386: {
387: switch (md_getuid()) {
388: case 0: /* always OK for root to play */
389: return TRUE;
390: default:
391: return FALSE;
392: }
393: }
394:
395: /*
396: * playtime:
397: * Returns TRUE when it is a good time to play rogue
398: */
399:
400: bool
401: playtime(void)
402: {
403: /* we no longer do playtime checking */
404:
405: return TRUE;
406: }
407:
408: /*
409: * betaover:
410: * Returns TRUE if the test period of this version of the game is over
411: */
412:
413: bool
414: betaover(void)
415: {
416: return(FALSE);
417: }
418:
419:
420: void
421: exit_game(int flag)
422: {
423: int i;
424:
425: if (flag & EXIT_CLS) /* Clear Screen */
426: {
427: wclear(cw);
428: draw(cw);
429: }
430:
431: if (flag & EXIT_ENDWIN) /* Shutdown Curses */
432: {
433: keypad(cw,FALSE);
434: keypad(hw,FALSE);
435: delwin(cw);
436: delwin(mw);
437: delwin(hw);
438: delwin(msgw);
439: if (!isendwin())
440: endwin();
441: }
442: o_free_list(player.t_pack);
443: t_free_list(mlist);
444: t_free_list(rlist);
445: t_free_list(tlist);
446: o_free_list(lvl_obj); /* Free up previous objects (if any) */
447: for (i = 0; i < MAXROOMS; i++)
448: {
449: r_free_list(rooms[i].r_exit); /* Free up the exit lists */
450: _r_free_fire_list(&rooms[i].r_fires);
451: }
452:
453: for(i=0; i<MAXSCROLLS; i++)
454: {
455: if (s_names[i] != NULL)
456: free( s_names[i] );
457: if (s_guess[i] != NULL)
458: free( s_guess[i] );
459: }
460:
461: for(i=0; i<MAXPOTIONS; i++)
462: {
463: if (p_guess[i] != NULL)
464: free( p_guess[i] );
465: }
466:
467: for(i=0; i<MAXRINGS; i++)
468: {
469: if (r_guess[i] != NULL)
470: free( r_guess[i] );
471: }
472:
473: for(i=0; i<MAXSTICKS; i++)
474: {
475: if (ws_guess[i] != NULL)
476: free( ws_guess[i] );
477: }
478:
479: exit(0);
480: }
481:
482: void
483: open_records(void)
484: {
485: if (scorefi == NULL)
486: scorefi = fopen(score_file, "rb+");
487: if (scorefi == NULL)
488: scorefi = fopen(score_file, "wb+");
489: /* If opening fails, that will be handled when trying to write. */
490: #ifdef LOGFILE
491: if (logfile == NULL)
492: logfile = fopen(LOGFILE, "a");
493: #endif
494: return;
495: }
496:
CVSweb