OSDN Git Service

#define AMIGA プリプロセッサを除去。 / Remove #define AMIGA preprocessor.
[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)
21
22
23 /*
24  * A hook for "quit()".
25  *
26  * Close down, then fall back into "quit()".
27  */
28 static void quit_hook(cptr 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  * Set the stack size and overlay buffer (see main-286.c")
49  */
50 #ifdef USE_286
51 # include <dos.h>
52 extern unsigned _stklen = 32768U;
53 extern unsigned _ovrbuffer = 0x1500;
54 #endif
55
56 #ifdef PRIVATE_USER_PATH
57
58 /*
59  * Create an ".angband/" directory in the users home directory.
60  *
61  * ToDo: Add error handling.
62  * ToDo: Only create the directories when actually writing files.
63  */
64 static void create_user_dir(void)
65 {
66         char dirpath[1024];
67         char subdirpath[1024];
68
69         /* Get an absolute path from the filename */
70         path_parse(dirpath, 1024, PRIVATE_USER_PATH);
71
72         /* Create the ~/.angband/ directory */
73         mkdir(dirpath, 0700);
74
75         /* Build the path to the variant-specific sub-directory */
76         path_build(subdirpath, sizeof(subdirpath), dirpath, VERSION_NAME);
77
78         /* Create the directory */
79         mkdir(subdirpath, 0700);
80 }
81
82 #endif /* PRIVATE_USER_PATH */
83
84
85 /*
86  * Initialize and verify the file paths, and the score file.
87  *
88  * Use the ANGBAND_PATH environment var if possible, else use
89  * DEFAULT_PATH, and in either case, branch off appropriately.
90  *
91  * First, we'll look for the ANGBAND_PATH environment variable,
92  * and then look for the files in there.  If that doesn't work,
93  * we'll try the DEFAULT_PATH constant.  So be sure that one of
94  * these two things works...
95  *
96  * We must ensure that the path ends with "PATH_SEP" if needed,
97  * since the "init_file_paths()" function will simply append the
98  * relevant "sub-directory names" to the given path.
99  *
100  * Make sure that the path doesn't overflow the buffer.  We have
101  * to leave enough space for the path separator, directory, and
102  * filenames.
103  */
104 static void init_stuff(void)
105 {
106         char path[1024];
107
108 #if defined(VM)
109
110         /* Hack -- prepare "path" */
111         strcpy(path, "Angband:");
112
113 #else /* VM */
114
115         cptr tail;
116
117         /* Get the environment variable */
118         tail = getenv("ANGBAND_PATH");
119
120         /* Use the angband_path, or a default */
121         strncpy(path, tail ? tail : DEFAULT_PATH, 511);
122
123         /* Make sure it's terminated */
124         path[511] = '\0';
125
126         /* Hack -- Add a path separator (only if needed) */
127         if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);
128
129 #endif /* VM */
130
131         /* Initialize */
132         init_file_paths(path);
133 }
134
135
136
137 /*
138  * Handle a "-d<what>=<path>" option
139  *
140  * The "<what>" can be any string starting with the same letter as the
141  * name of a subdirectory of the "lib" folder (i.e. "i" or "info").
142  *
143  * The "<path>" can be any legal path for the given system, and should
144  * not end in any special path separator (i.e. "/tmp" or "~/.ang-info").
145  */
146 static void change_path(cptr info)
147 {
148         cptr s;
149
150         /* Find equal sign */
151         s = my_strchr(info, '=');
152
153         /* Verify equal sign */
154         if (!s) quit_fmt("Try '-d<what>=<path>' not '-d%s'", info);
155
156         /* Analyze */
157         switch (tolower(info[0]))
158         {
159                 case 'a':
160                 {
161                         string_free(ANGBAND_DIR_APEX);
162                         ANGBAND_DIR_APEX = string_make(s+1);
163                         break;
164                 }
165
166                 case 'f':
167                 {
168                         string_free(ANGBAND_DIR_FILE);
169                         ANGBAND_DIR_FILE = string_make(s+1);
170                         break;
171                 }
172
173                 case 'h':
174                 {
175                         string_free(ANGBAND_DIR_HELP);
176                         ANGBAND_DIR_HELP = string_make(s+1);
177                         break;
178                 }
179
180                 case 'i':
181                 {
182                         string_free(ANGBAND_DIR_INFO);
183                         ANGBAND_DIR_INFO = string_make(s+1);
184                         break;
185                 }
186
187                 case 'u':
188                 {
189                         string_free(ANGBAND_DIR_USER);
190                         ANGBAND_DIR_USER = string_make(s+1);
191                         break;
192                 }
193
194                 case 'x':
195                 {
196                         string_free(ANGBAND_DIR_XTRA);
197                         ANGBAND_DIR_XTRA = string_make(s+1);
198                         break;
199                 }
200
201 #ifdef VERIFY_SAVEFILE
202
203                 case 'b':
204                 case 'd':
205                 case 'e':
206                 case 's':
207                 {
208                         quit_fmt("Restricted option '-d%s'", info);
209                 }
210
211 #else /* VERIFY_SAVEFILE */
212
213                 case 'b':
214                 {
215                         string_free(ANGBAND_DIR_BONE);
216                         ANGBAND_DIR_BONE = string_make(s+1);
217                         break;
218                 }
219
220                 case 'd':
221                 {
222                         string_free(ANGBAND_DIR_DATA);
223                         ANGBAND_DIR_DATA = string_make(s+1);
224                         break;
225                 }
226
227                 case 'e':
228                 {
229                         string_free(ANGBAND_DIR_EDIT);
230                         ANGBAND_DIR_EDIT = string_make(s+1);
231                         break;
232                 }
233
234                 case 's':
235                 {
236                         string_free(ANGBAND_DIR_SAVE);
237                         ANGBAND_DIR_SAVE = string_make(s+1);
238                         break;
239                 }
240
241                 case 'z':
242                 {
243                         string_free(ANGBAND_DIR_SCRIPT);
244                         ANGBAND_DIR_SCRIPT = string_make(s+1);
245                         break;
246                 }
247
248 #endif /* VERIFY_SAVEFILE */
249
250                 default:
251                 {
252                         quit_fmt("Bad semantics in '-d%s'", info);
253                 }
254         }
255 }
256
257
258 /*
259  * Simple "main" function for multiple platforms.
260  *
261  * Note the special "--" option which terminates the processing of
262  * standard options.  All non-standard options (if any) are passed
263  * directly to the "init_xxx()" function.
264  */
265 int main(int argc, char *argv[])
266 {
267         int i;
268
269         bool done = FALSE;
270
271         bool new_game = FALSE;
272
273         int show_score = 0;
274
275         cptr mstr = NULL;
276
277         bool args = TRUE;
278
279
280         /* Save the "program name" XXX XXX XXX */
281         argv0 = argv[0];
282
283 #ifdef USE_286
284         /* Attempt to use XMS (or EMS) memory for swap space */
285         if (_OvrInitExt(0L, 0L))
286         {
287                 _OvrInitEms(0, 0, 64);
288         }
289 #endif
290
291
292 #ifdef SET_UID
293
294         /* Default permissions on files */
295         (void)umask(022);
296
297 # ifdef SECURE
298         /* Authenticate */
299         Authenticate();
300 # endif
301
302 #endif
303
304
305         /* Get the file paths */
306         init_stuff();
307
308
309 #ifdef SET_UID
310
311         /* Get the user id (?) */
312         player_uid = getuid();
313
314 #ifdef VMS
315         /* Mega-Hack -- Factor group id */
316         player_uid += (getgid() * 1000);
317 #endif
318
319 # ifdef SAFE_SETUID
320
321 #  ifdef _POSIX_SAVED_IDS
322
323         /* Save some info for later */
324         player_euid = geteuid();
325         player_egid = getegid();
326
327 #  endif
328
329 #  if 0 /* XXX XXX XXX */
330
331         /* Redundant setting necessary in case root is running the game */
332         /* If not root or game not setuid the following two calls do nothing */
333
334         if (setgid(getegid()) != 0)
335         {
336                 quit("setgid(): cannot set permissions correctly!");
337         }
338
339         if (setuid(geteuid()) != 0)
340         {
341                 quit("setuid(): cannot set permissions correctly!");
342         }
343
344 #  endif
345
346 # endif
347
348 #endif
349
350
351         /* Drop permissions */
352         safe_setuid_drop();
353
354
355 #ifdef SET_UID
356
357         /* Initialize the "time" checker */
358         if (check_time_init() || check_time())
359         {
360                 quit("The gates to Angband are closed (bad time).");
361         }
362
363         /* Initialize the "load" checker */
364         if (check_load_init() || check_load())
365         {
366                 quit("The gates to Angband are closed (bad load).");
367         }
368
369         /* Acquire the "user name" as a default player name */
370 #ifdef ANGBAND_2_8_1
371         user_name(player_name, player_uid);
372 #else /* ANGBAND_2_8_1 */
373         user_name(op_ptr->full_name, player_uid);
374 #endif /* ANGBAND_2_8_1 */
375
376 #ifdef PRIVATE_USER_PATH
377
378         /* Create a directory for the users files. */
379         create_user_dir();
380
381 #endif /* PRIVATE_USER_PATH */
382
383 #endif /* SET_UID */
384
385
386         /* Process the command line arguments */
387         for (i = 1; args && (i < argc); i++)
388         {
389                 /* Require proper options */
390                 if (argv[i][0] != '-') goto usage;
391
392                 /* Analyze option */
393                 switch (argv[i][1])
394                 {
395                         case 'N':
396                         case 'n':
397                         {
398                                 new_game = TRUE;
399                                 break;
400                         }
401
402                         case 'F':
403                         case 'f':
404                         {
405                                 arg_fiddle = TRUE;
406                                 break;
407                         }
408
409                         case 'W':
410                         case 'w':
411                         {
412                                 arg_wizard = TRUE;
413                                 break;
414                         }
415
416                         case 'B':
417                         case 'b':
418                         {
419                                 arg_music = TRUE;
420                                 break;
421                         }
422
423                         case 'V':
424                         case 'v':
425                         {
426                                 arg_sound = TRUE;
427                                 break;
428                         }
429
430                         case 'G':
431                         case 'g':
432                         {
433                                 /* HACK - Graphics mode switches on the original tiles */
434                                 arg_graphics = GRAPHICS_ORIGINAL;
435                                 break;
436                         }
437
438                         case 'R':
439                         case 'r':
440                         {
441                                 arg_force_roguelike = TRUE;
442                                 break;
443                         }
444
445                         case 'O':
446                         case 'o':
447                         {
448                                 arg_force_original = TRUE;
449                                 break;
450                         }
451
452                         case 'S':
453                         case 's':
454                         {
455                                 show_score = atoi(&argv[i][2]);
456                                 if (show_score <= 0) show_score = 10;
457                                 break;
458                         }
459
460                         case 'u':
461                         case 'U':
462                         {
463                                 if (!argv[i][2]) goto usage;
464 #ifdef ANGBAND_2_8_1
465                                 strcpy(player_name, &argv[i][2]);
466 #else /* ANGBAND_2_8_1 */
467
468                                 /* Get the savefile name */
469                                 strncpy(op_ptr->full_name, &argv[i][2], 32);
470
471                                 /* Make sure it's terminated */
472                                 op_ptr->full_name[31] = '\0';
473
474 #endif /* ANGBAND_2_8_1 */
475                                 break;
476                         }
477
478                         case 'm':
479                         {
480                                 if (!argv[i][2]) goto usage;
481                                 mstr = &argv[i][2];
482                                 break;
483                         }
484
485                         case 'M':
486                         {
487                                 arg_monochrome = TRUE;
488                                 break;
489                         }
490
491                         case 'd':
492                         case 'D':
493                         {
494                                 change_path(&argv[i][2]);
495                                 break;
496                         }
497
498 #ifdef CHUUKEI
499                         case 'p':
500                         case 'P':
501                         {
502                                 if (!argv[i][2]) goto usage;
503                                 chuukei_server = TRUE;
504                                 if (connect_chuukei_server(&argv[i][2]) < 0) chuukei_server = FALSE;
505                                 break;
506                         }
507
508                         case 'c':
509                         case 'C':
510                         {
511                                 if (!argv[i][2]) goto usage;
512                                 chuukei_client = TRUE;
513                                 connect_chuukei_server(&argv[i][2]);
514                                 break;
515                         }
516 #endif
517
518                         case 'x':
519                         {
520                                 if (!argv[i][2]) goto usage;
521                                 prepare_browse_movie(&argv[i][2]);
522                                 break;
523                         }                       
524
525                         case '-':
526                         {
527                                 argv[i] = argv[0];
528                                 argc = argc - i;
529                                 argv = argv + i;
530                                 args = FALSE;
531                                 break;
532                         }
533
534                         default:
535                         usage:
536                         {
537                                 /* Dump usage information */
538                                 puts("Usage: angband [options] [-- subopts]");
539                                 puts("  -n       Start a new character");
540                                 puts("  -f       Request fiddle mode");
541                                 puts("  -w       Request wizard mode");
542                                 puts("  -b       Request BGM mode");
543                                 puts("  -v       Request sound mode");
544                                 puts("  -g       Request graphics mode");
545                                 puts("  -o       Request original keyset");
546                                 puts("  -r       Request rogue-like keyset");
547                                 puts("  -M       Request monochrome mode");
548                                 puts("  -s<num>  Show <num> high scores");
549                                 puts("  -u<who>  Use your <who> savefile");
550                                 puts("  -m<sys>  Force 'main-<sys>.c' usage");
551                                 puts("  -d<def>  Define a 'lib' dir sub-path");
552                                 puts("");
553
554 #ifdef USE_X11
555                                 puts("  -mx11    To use X11");
556                                 puts("  --       Sub options");
557                                 puts("  -- -d    Set display name");
558                                 puts("  -- -o    Request old 8x8 tile graphics");
559                                 puts("  -- -a    Request Adam Bolt 16x16 tile graphics");
560                                 puts("  -- -b    Request Bigtile graphics mode");
561                                 puts("  -- -s    Turn off smoothscaling graphics");
562                                 puts("  -- -n#   Number of terms to use");
563                                 puts("");
564 #endif /* USE_X11 */
565
566 #ifdef USE_GCU
567                                 puts("  -mgcu    To use GCU (GNU Curses)");
568 #endif /* USE_GCU */
569
570 #ifdef USE_CAP
571                                 puts("  -mcap    To use CAP (\"Termcap\" calls)");
572 #endif /* USE_CAP */
573
574 #ifdef USE_DOS
575                                 puts("  -mdos    To use DOS (Graphics)");
576 #endif /* USE_DOS */
577
578 #ifdef USE_IBM
579                                 puts("  -mibm    To use IBM (BIOS text mode)");
580 #endif /* USE_IBM */
581
582 #ifdef USE_SLA
583                                 puts("  -msla    To use SLA (SLANG)");
584 #endif /* USE_SLA */
585
586 #ifdef USE_LSL
587                                 puts("  -mlsl    To use LSL (Linux-SVGALIB)");
588 #endif /* USE_LSL */
589
590 #ifdef USE_VME
591                                 puts("  -mvme    To use VME (VAX/ESA)");
592 #endif /* USE_VME */
593
594                                 /* Actually abort the process */
595                                 quit(NULL);
596                         }
597                 }
598         }
599
600         /* Hack -- Forget standard args */
601         if (args)
602         {
603                 argc = 1;
604                 argv[1] = NULL;
605         }
606
607
608         /* Process the player name */
609         process_player_name(TRUE);
610
611
612
613         /* Install "quit" hook */
614         quit_aux = quit_hook;
615
616
617
618 #ifdef USE_XAW
619         /* Attempt to use the "main-xaw.c" support */
620         if (!done && (!mstr || (streq(mstr, "xaw"))))
621         {
622                 extern errr init_xaw(int, char**);
623                 if (0 == init_xaw(argc, argv))
624                 {
625                         ANGBAND_SYS = "xaw";
626                         done = TRUE;
627                 }
628         }
629 #endif
630
631 #ifdef USE_X11
632         /* Attempt to use the "main-x11.c" support */
633         if (!done && (!mstr || (streq(mstr, "x11"))))
634         {
635                 extern errr init_x11(int, char**);
636                 if (0 == init_x11(argc, argv))
637                 {
638                         ANGBAND_SYS = "x11";
639                         done = TRUE;
640                 }
641         }
642 #endif
643
644 #ifdef USE_GCU
645         /* Attempt to use the "main-gcu.c" support */
646         if (!done && (!mstr || (streq(mstr, "gcu"))))
647         {
648                 extern errr init_gcu(int, char**);
649                 if (0 == init_gcu(argc, argv))
650                 {
651                         ANGBAND_SYS = "gcu";
652                         done = TRUE;
653                 }
654         }
655 #endif
656
657 #ifdef USE_CAP
658         /* Attempt to use the "main-cap.c" support */
659         if (!done && (!mstr || (streq(mstr, "cap"))))
660         {
661                 extern errr init_cap(int, char**);
662                 if (0 == init_cap(argc, argv))
663                 {
664                         ANGBAND_SYS = "cap";
665                         done = TRUE;
666                 }
667         }
668 #endif
669
670
671 #ifdef USE_DOS
672         /* Attempt to use the "main-dos.c" support */
673         if (!done && (!mstr || (streq(mstr, "dos"))))
674         {
675                 extern errr init_dos(void);
676                 if (0 == init_dos())
677                 {
678                         ANGBAND_SYS = "dos";
679                         done = TRUE;
680                 }
681         }
682 #endif
683
684 #ifdef USE_IBM
685         /* Attempt to use the "main-ibm.c" support */
686         if (!done && (!mstr || (streq(mstr, "ibm"))))
687         {
688                 extern errr init_ibm(void);
689                 if (0 == init_ibm())
690                 {
691                         ANGBAND_SYS = "ibm";
692                         done = TRUE;
693                 }
694         }
695 #endif
696
697
698 #ifdef USE_EMX
699         /* Attempt to use the "main-emx.c" support */
700         if (!done && (!mstr || (streq(mstr, "emx"))))
701         {
702                 extern errr init_emx(void);
703                 if (0 == init_emx())
704                 {
705                         ANGBAND_SYS = "emx";
706                         done = TRUE;
707                 }
708         }
709 #endif
710
711
712 #ifdef USE_SLA
713         /* Attempt to use the "main-sla.c" support */
714         if (!done && (!mstr || (streq(mstr, "sla"))))
715         {
716                 extern errr init_sla(void);
717                 if (0 == init_sla())
718                 {
719                         ANGBAND_SYS = "sla";
720                         done = TRUE;
721                 }
722         }
723 #endif
724
725
726 #ifdef USE_LSL
727         /* Attempt to use the "main-lsl.c" support */
728         if (!done && (!mstr || (streq(mstr, "lsl"))))
729         {
730                 extern errr init_lsl(void);
731                 if (0 == init_lsl())
732                 {
733                         ANGBAND_SYS = "lsl";
734                         done = TRUE;
735                 }
736         }
737 #endif
738
739
740 #ifdef USE_AMI
741         /* Attempt to use the "main-ami.c" support */
742         if (!done && (!mstr || (streq(mstr, "ami"))))
743         {
744                 extern errr init_ami(void);
745                 if (0 == init_ami())
746                 {
747                         ANGBAND_SYS = "ami";
748                         done = TRUE;
749                 }
750         }
751 #endif
752
753
754 #ifdef USE_VME
755         /* Attempt to use the "main-vme.c" support */
756         if (!done && (!mstr || (streq(mstr, "vme"))))
757         {
758                 extern errr init_vme(void);
759                 if (0 == init_vme())
760                 {
761                         ANGBAND_SYS = "vme";
762                         done = TRUE;
763                 }
764         }
765 #endif
766
767
768         /* Make sure we have a display! */
769         if (!done) quit("Unable to prepare any 'display module'!");
770
771
772         /* Hack -- If requested, display scores and quit */
773         if (show_score > 0) display_scores(0, show_score);
774
775
776         /* Catch nasty signals */
777         signals_init();
778
779         /* Initialize */
780         init_angband();
781
782         /* Wait for response */
783         pause_line(23);
784
785         /* Play the game */
786         play_game(new_game);
787
788         /* Quit */
789         quit(NULL);
790
791         /* Exit */
792         return (0);
793 }
794
795 #endif
796
797
798