OSDN Git Service

Changed so that font changes on the main window while playing do a better job of...
[hengbandforosx/hengbandosx.git] / src / main.c
1 /* File: main.c */
2
3 /*
4  * Copyright (c) 1997 Ben Harrison, and others
5  *
6  * This software may be copied and distributed for educational, research,
7  * and not for profit purposes provided that this copyright and statement
8  * are included in all such copies.
9  */
10
11 #include "angband.h"
12
13
14 /*
15  * Some machines have a "main()" function in their "main-xxx.c" file,
16  * all the others use this file for their "main()" function.
17  */
18
19
20 #if !defined(MACINTOSH) && !defined(WINDOWS) && !defined(ACORN) && !defined(MACH_O_CARBON) && !defined(MACH_O_COCOA)
21
22
23 /*
24  * A hook for "quit()".
25  *
26  * Close down, then fall back into "quit()".
27  */
28 static void quit_hook(concptr s)
29 {
30         int j;
31
32         /* Unused */
33         (void)s;
34
35         /* Scan windows */
36         for (j = 8 - 1; j >= 0; j--)
37         {
38                 /* Unused */
39                 if (!angband_term[j]) continue;
40
41                 /* Nuke it */
42                 term_nuke(angband_term[j]);
43         }
44 }
45
46
47 /*
48  * Initialize and verify the file paths, and the score file.
49  *
50  * Use the ANGBAND_PATH environment var if possible, else use
51  * DEFAULT_PATH, and in either case, branch off appropriately.
52  *
53  * First, we'll look for the ANGBAND_PATH environment variable,
54  * and then look for the files in there.  If that doesn't work,
55  * we'll try the DEFAULT_PATH constant.  So be sure that one of
56  * these two things works...
57  *
58  * We must ensure that the path ends with "PATH_SEP" if needed,
59  * since the "init_file_paths()" function will simply append the
60  * relevant "sub-directory names" to the given path.
61  *
62  * Make sure that the path doesn't overflow the buffer.  We have
63  * to leave enough space for the path separator, directory, and
64  * filenames.
65  */
66 static void init_stuff(void)
67 {
68         char path[1024];
69
70         concptr tail;
71
72         /* Get the environment variable */
73         tail = getenv("ANGBAND_PATH");
74
75         /* Use the angband_path, or a default */
76         strncpy(path, tail ? tail : DEFAULT_PATH, 511);
77
78         /* Make sure it's terminated */
79         path[511] = '\0';
80
81         /* Hack -- Add a path separator (only if needed) */
82         if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);
83
84         /* Initialize */
85         init_file_paths(path, path, path);
86 }
87
88
89
90 /*
91  * Handle a "-d<what>=<path>" option
92  *
93  * The "<what>" can be any string starting with the same letter as the
94  * name of a subdirectory of the "lib" folder (i.e. "i" or "info").
95  *
96  * The "<path>" can be any legal path for the given system, and should
97  * not end in any special path separator (i.e. "/tmp" or "~/.ang-info").
98  */
99 static void change_path(concptr info)
100 {
101         concptr s;
102
103         /* Find equal sign */
104         s = my_strchr(info, '=');
105
106         /* Verify equal sign */
107         if (!s) quit_fmt("Try '-d<what>=<path>' not '-d%s'", info);
108
109         /* Analyze */
110         switch (tolower(info[0]))
111         {
112                 case 'a':
113                 {
114                         string_free(ANGBAND_DIR_APEX);
115                         ANGBAND_DIR_APEX = string_make(s+1);
116                         break;
117                 }
118
119                 case 'f':
120                 {
121                         string_free(ANGBAND_DIR_FILE);
122                         ANGBAND_DIR_FILE = string_make(s+1);
123                         break;
124                 }
125
126                 case 'h':
127                 {
128                         string_free(ANGBAND_DIR_HELP);
129                         ANGBAND_DIR_HELP = string_make(s+1);
130                         break;
131                 }
132
133                 case 'i':
134                 {
135                         string_free(ANGBAND_DIR_INFO);
136                         ANGBAND_DIR_INFO = string_make(s+1);
137                         break;
138                 }
139
140                 case 'u':
141                 {
142                         string_free(ANGBAND_DIR_USER);
143                         ANGBAND_DIR_USER = string_make(s+1);
144                         break;
145                 }
146
147                 case 'x':
148                 {
149                         string_free(ANGBAND_DIR_XTRA);
150                         ANGBAND_DIR_XTRA = string_make(s+1);
151                         break;
152                 }
153
154 #ifdef VERIFY_SAVEFILE
155
156                 case 'b':
157                 case 'd':
158                 case 'e':
159                 case 's':
160                 {
161                         quit_fmt("Restricted option '-d%s'", info);
162                 }
163
164 #else /* VERIFY_SAVEFILE */
165
166                 case 'b':
167                 {
168                         string_free(ANGBAND_DIR_BONE);
169                         ANGBAND_DIR_BONE = string_make(s+1);
170                         break;
171                 }
172
173                 case 'd':
174                 {
175                         string_free(ANGBAND_DIR_DATA);
176                         ANGBAND_DIR_DATA = string_make(s+1);
177                         break;
178                 }
179
180                 case 'e':
181                 {
182                         string_free(ANGBAND_DIR_EDIT);
183                         ANGBAND_DIR_EDIT = string_make(s+1);
184                         break;
185                 }
186
187                 case 's':
188                 {
189                         string_free(ANGBAND_DIR_SAVE);
190                         ANGBAND_DIR_SAVE = string_make(s+1);
191                         break;
192                 }
193
194                 case 'z':
195                 {
196                         string_free(ANGBAND_DIR_SCRIPT);
197                         ANGBAND_DIR_SCRIPT = string_make(s+1);
198                         break;
199                 }
200
201 #endif /* VERIFY_SAVEFILE */
202
203                 default:
204                 {
205                         quit_fmt("Bad semantics in '-d%s'", info);
206                 }
207         }
208 }
209
210
211 /*
212  * Simple "main" function for multiple platforms.
213  *
214  * Note the special "--" option which terminates the processing of
215  * standard options.  All non-standard options (if any) are passed
216  * directly to the "init_xxx()" function.
217  */
218 int main(int argc, char *argv[])
219 {
220         int i;
221
222         bool done = FALSE;
223         bool new_game = FALSE;
224         int show_score = 0;
225         concptr mstr = NULL;
226         bool args = TRUE;
227
228         /* Save the "program name" XXX XXX XXX */
229         argv0 = argv[0];
230
231 #ifdef SET_UID
232
233         /* Default permissions on files */
234         (void)umask(022);
235
236 # ifdef SECURE
237         /* Authenticate */
238         Authenticate();
239 # endif
240
241 #endif
242
243
244         /* Get the file paths */
245         init_stuff();
246
247
248 #ifdef SET_UID
249
250         /* Get the user id (?) */
251         player_uid = getuid();
252
253 #ifdef VMS
254         /* Mega-Hack -- Factor group id */
255         player_uid += (getgid() * 1000);
256 #endif
257
258 # ifdef SAFE_SETUID
259
260 #  ifdef _POSIX_SAVED_IDS
261
262         /* Save some info for later */
263         player_euid = geteuid();
264         player_egid = getegid();
265
266 #  endif
267
268 #  if 0 /* XXX XXX XXX */
269
270         /* Redundant setting necessary in case root is running the game */
271         /* If not root or game not setuid the following two calls do nothing */
272
273         if (setgid(getegid()) != 0)
274         {
275                 quit("setgid(): cannot set permissions correctly!");
276         }
277
278         if (setuid(geteuid()) != 0)
279         {
280                 quit("setuid(): cannot set permissions correctly!");
281         }
282
283 #  endif
284
285 # endif
286
287 #endif
288
289
290         /* Drop permissions */
291         safe_setuid_drop();
292
293
294 #ifdef SET_UID
295
296         /* Initialize the "time" checker */
297         if (check_time_init() || check_time())
298         {
299                 quit("The gates to Angband are closed (bad time).");
300         }
301
302         /* Initialize the "load" checker */
303         if (check_load_init() || check_load())
304         {
305                 quit("The gates to Angband are closed (bad load).");
306         }
307
308         /* Acquire the "user name" as a default player name */
309 #ifdef ANGBAND_2_8_1
310         user_name(p_ptr->name, player_uid);
311 #else /* ANGBAND_2_8_1 */
312         user_name(op_ptr->full_name, player_uid);
313 #endif /* ANGBAND_2_8_1 */
314
315 #ifdef PRIVATE_USER_PATH
316
317         /* Create directories for the user's files; handled by init2.c. */
318         create_needed_dirs();
319
320 #endif /* PRIVATE_USER_PATH */
321
322 #endif /* SET_UID */
323
324
325         /* Process the command line arguments */
326         for (i = 1; args && (i < argc); i++)
327         {
328                 /* Require proper options */
329                 if (argv[i][0] != '-') goto usage;
330
331                 /* Analyze option */
332                 switch (argv[i][1])
333                 {
334                         case 'N':
335                         case 'n':
336                         {
337                                 new_game = TRUE;
338                                 break;
339                         }
340
341                         case 'F':
342                         case 'f':
343                         {
344                                 arg_fiddle = TRUE;
345                                 break;
346                         }
347
348                         case 'W':
349                         case 'w':
350                         {
351                                 arg_wizard = TRUE;
352                                 break;
353                         }
354
355                         case 'B':
356                         case 'b':
357                         {
358                                 arg_music = TRUE;
359                                 break;
360                         }
361
362                         case 'V':
363                         case 'v':
364                         {
365                                 arg_sound = TRUE;
366                                 break;
367                         }
368
369                         case 'G':
370                         case 'g':
371                         {
372                                 /* HACK - Graphics mode switches on the original tiles */
373                                 arg_graphics = GRAPHICS_ORIGINAL;
374                                 break;
375                         }
376
377                         case 'R':
378                         case 'r':
379                         {
380                                 arg_force_roguelike = TRUE;
381                                 break;
382                         }
383
384                         case 'O':
385                         case 'o':
386                         {
387                                 arg_force_original = TRUE;
388                                 break;
389                         }
390
391                         case 'S':
392                         case 's':
393                         {
394                                 show_score = atoi(&argv[i][2]);
395                                 if (show_score <= 0) show_score = 10;
396                                 break;
397                         }
398
399                         case 'u':
400                         case 'U':
401                         {
402                                 if (!argv[i][2]) goto usage;
403 #ifdef ANGBAND_2_8_1
404                                 strcpy(p_ptr->name, &argv[i][2]);
405 #else /* ANGBAND_2_8_1 */
406
407                                 /* Get the savefile name */
408                                 strncpy(op_ptr->full_name, &argv[i][2], 32);
409
410                                 /* Make sure it's terminated */
411                                 op_ptr->full_name[31] = '\0';
412
413 #endif /* ANGBAND_2_8_1 */
414                                 break;
415                         }
416
417                         case 'm':
418                         {
419                                 if (!argv[i][2]) goto usage;
420                                 mstr = &argv[i][2];
421                                 break;
422                         }
423
424                         case 'M':
425                         {
426                                 arg_monochrome = TRUE;
427                                 break;
428                         }
429
430                         case 'd':
431                         case 'D':
432                         {
433                                 change_path(&argv[i][2]);
434                                 break;
435                         }
436
437 #ifdef CHUUKEI
438                         case 'p':
439                         case 'P':
440                         {
441                                 if (!argv[i][2]) goto usage;
442                                 chuukei_server = TRUE;
443                                 if (connect_chuukei_server(&argv[i][2]) < 0) chuukei_server = FALSE;
444                                 break;
445                         }
446
447                         case 'c':
448                         case 'C':
449                         {
450                                 if (!argv[i][2]) goto usage;
451                                 chuukei_client = TRUE;
452                                 connect_chuukei_server(&argv[i][2]);
453                                 break;
454                         }
455 #endif
456
457                         case 'x':
458                         {
459                                 if (!argv[i][2]) goto usage;
460                                 prepare_browse_movie(&argv[i][2]);
461                                 break;
462                         }                       
463
464                         case '-':
465                         {
466                                 argv[i] = argv[0];
467                                 argc = argc - i;
468                                 argv = argv + i;
469                                 args = FALSE;
470                                 break;
471                         }
472
473                         default:
474                         usage:
475                         {
476                                 /* Dump usage information */
477                                 puts("Usage: angband [options] [-- subopts]");
478                                 puts("  -n       Start a new character");
479                                 puts("  -f       Request fiddle mode");
480                                 puts("  -w       Request wizard mode");
481                                 puts("  -b       Request BGM mode");
482                                 puts("  -v       Request sound mode");
483                                 puts("  -g       Request graphics mode");
484                                 puts("  -o       Request original keyset");
485                                 puts("  -r       Request rogue-like keyset");
486                                 puts("  -M       Request monochrome mode");
487                                 puts("  -s<num>  Show <num> high scores");
488                                 puts("  -u<who>  Use your <who> savefile");
489                                 puts("  -m<sys>  Force 'main-<sys>.c' usage");
490                                 puts("  -d<def>  Define a 'lib' dir sub-path");
491                                 puts("");
492
493 #ifdef USE_X11
494                                 puts("  -mx11    To use X11");
495                                 puts("  --       Sub options");
496                                 puts("  -- -d    Set display name");
497                                 puts("  -- -o    Request old 8x8 tile graphics");
498                                 puts("  -- -a    Request Adam Bolt 16x16 tile graphics");
499                                 puts("  -- -b    Request Bigtile graphics mode");
500                                 puts("  -- -s    Turn off smoothscaling graphics");
501                                 puts("  -- -n#   Number of terms to use");
502                                 puts("");
503 #endif /* USE_X11 */
504
505 #ifdef USE_GCU
506                                 puts("  -mgcu    To use GCU (GNU Curses)");
507 #endif /* USE_GCU */
508
509 #ifdef USE_CAP
510                                 puts("  -mcap    To use CAP (\"Termcap\" calls)");
511 #endif /* USE_CAP */
512
513 #ifdef USE_DOS
514                                 puts("  -mdos    To use DOS (Graphics)");
515 #endif /* USE_DOS */
516
517 #ifdef USE_IBM
518                                 puts("  -mibm    To use IBM (BIOS text mode)");
519 #endif /* USE_IBM */
520
521                                 /* Actually abort the process */
522                                 quit(NULL);
523                         }
524                 }
525         }
526
527         /* Hack -- Forget standard args */
528         if (args)
529         {
530                 argc = 1;
531                 argv[1] = NULL;
532         }
533
534
535         /* Process the player name */
536         process_player_name(TRUE);
537
538
539
540         /* Install "quit" hook */
541         quit_aux = quit_hook;
542
543
544
545 #ifdef USE_XAW
546         /* Attempt to use the "main-xaw.c" support */
547         if (!done && (!mstr || (streq(mstr, "xaw"))))
548         {
549                 extern errr init_xaw(int, char**);
550                 if (0 == init_xaw(argc, argv))
551                 {
552                         ANGBAND_SYS = "xaw";
553                         done = TRUE;
554                 }
555         }
556 #endif
557
558 #ifdef USE_X11
559         /* Attempt to use the "main-x11.c" support */
560         if (!done && (!mstr || (streq(mstr, "x11"))))
561         {
562                 extern errr init_x11(int, char**);
563                 if (0 == init_x11(argc, argv))
564                 {
565                         ANGBAND_SYS = "x11";
566                         done = TRUE;
567                 }
568         }
569 #endif
570
571 #ifdef USE_GCU
572         /* Attempt to use the "main-gcu.c" support */
573         if (!done && (!mstr || (streq(mstr, "gcu"))))
574         {
575                 extern errr init_gcu(int, char**);
576                 if (0 == init_gcu(argc, argv))
577                 {
578                         ANGBAND_SYS = "gcu";
579                         done = TRUE;
580                 }
581         }
582 #endif
583
584 #ifdef USE_CAP
585         /* Attempt to use the "main-cap.c" support */
586         if (!done && (!mstr || (streq(mstr, "cap"))))
587         {
588                 extern errr init_cap(int, char**);
589                 if (0 == init_cap(argc, argv))
590                 {
591                         ANGBAND_SYS = "cap";
592                         done = TRUE;
593                 }
594         }
595 #endif
596
597
598 #ifdef USE_DOS
599         /* Attempt to use the "main-dos.c" support */
600         if (!done && (!mstr || (streq(mstr, "dos"))))
601         {
602                 extern errr init_dos(void);
603                 if (0 == init_dos())
604                 {
605                         ANGBAND_SYS = "dos";
606                         done = TRUE;
607                 }
608         }
609 #endif
610
611 #ifdef USE_IBM
612         /* Attempt to use the "main-ibm.c" support */
613         if (!done && (!mstr || (streq(mstr, "ibm"))))
614         {
615                 extern errr init_ibm(void);
616                 if (0 == init_ibm())
617                 {
618                         ANGBAND_SYS = "ibm";
619                         done = TRUE;
620                 }
621         }
622 #endif
623
624
625         /* Make sure we have a display! */
626         if (!done) quit("Unable to prepare any 'display module'!");
627
628
629         /* Hack -- If requested, display scores and quit */
630         if (show_score > 0) display_scores(0, show_score);
631
632
633         /* Catch nasty signals */
634         signals_init();
635
636         /* Initialize */
637         init_angband();
638
639         /* Wait for response */
640         pause_line(23);
641
642         /* Play the game */
643         play_game(new_game);
644
645         /* Quit */
646         quit(NULL);
647
648         /* Exit */
649         return (0);
650 }
651
652 #endif
653
654
655