1 /* SCCS Id: @(#)bemain.c 3.4 1998/07/15 */
2 /* Copyright (c) Dean Luick, 1996. */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 #include "hack.h"
6 #include "dlb.h"
7 #include <fcntl.h>
8
9 static void whoami(void);
10 static void process_options(int argc, char **argv);
11 static void chdirx(const char *dir);
12 static void getlock(void);
13
14 #ifdef __begui__
15 #define MAIN nhmain
16 int nhmain(int argc, char **argv);
17 #else
18 #define MAIN main
19 #endif
20
21
MAIN(int argc,char ** argv)22 int MAIN(int argc, char **argv)
23 {
24 int fd;
25 char *dir;
26
27 dir = nh_getenv("NETHACKDIR");
28 if (!dir) dir = nh_getenv("HACKDIR");
29
30 choose_windows(DEFAULT_WINDOW_SYS);
31 chdirx(dir);
32 initoptions();
33
34 init_nhwindows(&argc, argv);
35 whoami();
36
37 /*
38 * It seems you really want to play.
39 */
40 u.uhp = 1; /* prevent RIP on early quits */
41 process_options(argc, argv); /* command line options */
42
43
44 #ifdef WIZARD
45 if (wizard)
46 Strcpy(plname, "wizard");
47 else
48 #endif
49 if(!*plname || !strncmp(plname, "player", 4)
50 || !strncmp(plname, "games", 4))
51 askname();
52 plnamesuffix(); /* strip suffix from name; calls askname() */
53 /* again if suffix was whole name */
54 /* accepts any suffix */
55
56 Sprintf(lock,"%d%s", getuid(), plname);
57 getlock();
58
59
60 dlb_init(); /* must be before newgame() */
61
62 /*
63 * Initialization of the boundaries of the mazes
64 * Both boundaries have to be even.
65 */
66 x_maze_max = COLNO-1;
67 if (x_maze_max % 2)
68 x_maze_max--;
69 y_maze_max = ROWNO-1;
70 if (y_maze_max % 2)
71 y_maze_max--;
72
73 /*
74 * Initialize the vision system. This must be before mklev() on a
75 * new game or before a level restore on a saved game.
76 */
77 vision_init();
78
79 display_gamewindows();
80
81 if ((fd = restore_saved_game()) >= 0) {
82 #ifdef WIZARD
83 /* Since wizard is actually flags.debug, restoring might
84 * overwrite it.
85 */
86 boolean remember_wiz_mode = wizard;
87 #endif
88 #ifdef NEWS
89 if(iflags.news) {
90 display_file(NEWS, FALSE);
91 iflags.news = FALSE; /* in case dorecover() fails */
92 }
93 #endif
94 pline("Restoring save file...");
95 mark_synch(); /* flush output */
96 if(!dorecover(fd))
97 goto not_recovered;
98 #ifdef WIZARD
99 if(!wizard && remember_wiz_mode) wizard = TRUE;
100 #endif
101 check_special_room(FALSE);
102 if (discover)
103 You("are in non-scoring discovery mode.");
104
105 if (discover || wizard) {
106 if(yn("Do you want to keep the save file?") == 'n')
107 (void) delete_savefile();
108 else {
109 compress(fqname(SAVEF, SAVEPREFIX, 0));
110 }
111 }
112
113 flags.move = 0;
114 } else {
115 not_recovered:
116 player_selection();
117 newgame();
118 if (discover)
119 You("are in non-scoring discovery mode.");
120
121 flags.move = 0;
122 set_wear();
123 (void) pickup(1);
124 }
125
126 moveloop();
127 return 0;
128 }
129
whoami(void)130 static void whoami(void)
131 {
132 /*
133 * Who am i? Algorithm: 1. Use name as specified in NETHACKOPTIONS
134 * 2. Use $USER or $LOGNAME (if 1. fails)
135 * The resulting name is overridden by command line options.
136 * If everything fails, or if the resulting name is some generic
137 * account like "games", "play", "player", "hack" then eventually
138 * we'll ask him.
139 */
140 char *s;
141
142 if (*plname) return;
143 if (s = nh_getenv("USER")) {
144 (void) strncpy(plname, s, sizeof(plname)-1);
145 return;
146 }
147 if (s = nh_getenv("LOGNAME")) {
148 (void) strncpy(plname, s, sizeof(plname)-1);
149 return;
150 }
151 }
152
153 /* normalize file name - we don't like .'s, /'s, spaces */
regularize(char * s)154 void regularize(char *s)
155 {
156 register char *lp;
157
158 while((lp=strchr(s, '.')) || (lp=strchr(s, '/')) || (lp=strchr(s,' ')))
159 *lp = '_';
160 }
161
process_options(int argc,char ** argv)162 static void process_options(int argc, char **argv)
163 {
164 int i;
165
166 while (argc > 1 && argv[1][0] == '-') {
167 argv++;
168 argc--;
169 switch (argv[0][1]) {
170 case 'D':
171 #ifdef WIZARD
172 wizard = TRUE;
173 break;
174 #endif
175 /* otherwise fall thru to discover */
176 case 'X':
177 discover = TRUE;
178 break;
179 #ifdef NEWS
180 case 'n':
181 iflags.news = FALSE;
182 break;
183 #endif
184 case 'u':
185 if(argv[0][2])
186 (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
187 else if (argc > 1) {
188 argc--;
189 argv++;
190 (void) strncpy(plname, argv[0], sizeof(plname)-1);
191 } else
192 raw_print("Player name expected after -u");
193 break;
194 case 'p': /* profession (role) */
195 if (argv[0][2]) {
196 if ((i = str2role(&argv[0][2])) >= 0)
197 flags.initrole = i;
198 } else if (argc > 1) {
199 argc--;
200 argv++;
201 if ((i = str2role(argv[0])) >= 0)
202 flags.initrole = i;
203 }
204 break;
205 case 'r': /* race */
206 if (argv[0][2]) {
207 if ((i = str2race(&argv[0][2])) >= 0)
208 flags.initrace = i;
209 } else if (argc > 1) {
210 argc--;
211 argv++;
212 if ((i = str2race(argv[0])) >= 0)
213 flags.initrace = i;
214 }
215 break;
216 case '@':
217 flags.randomall = 1;
218 break;
219 default:
220 raw_printf("Unknown option: %s", *argv);
221 break;
222 }
223 }
224 }
225
chdirx(const char * dir)226 static void chdirx(const char *dir)
227 {
228 if (!dir) dir = HACKDIR;
229
230 if (chdir(dir) < 0)
231 error("Cannot chdir to %s.", dir);
232
233 /* Warn the player if we can't write the record file */
234 /* perhaps we should also test whether . is writable */
235 check_recordfile(dir);
236 }
237
getlock(void)238 void getlock(void)
239 {
240 int fd;
241
242 regularize(lock);
243 set_levelfile_name(lock, 0);
244 fd = creat(lock, FCMASK);
245 if(fd == -1) {
246 error("cannot creat lock file.");
247 } else {
248 if(write(fd, (genericptr_t) &hackpid, sizeof(hackpid))
249 != sizeof(hackpid)){
250 error("cannot write lock");
251 }
252 if(close(fd) == -1) {
253 error("cannot close lock");
254 }
255 }
256 }
257
258 #ifndef __begui__
259 /*
260 * If we are not using the Be GUI, then just exit -- we don't need to
261 * do anything extra.
262 */
263 void nethack_exit(int status);
nethack_exit(int status)264 void nethack_exit(int status)
265 {
266 exit(status);
267 }
268 #endif /* !__begui__ */
269