4 * Copyright (c) 1997 Ben Harrison, and others
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.
15 * Some machines have a "main()" function in their "main-xxx.c" file,
16 * all the others use this file for their "main()" function.
20 #if !defined(MACINTOSH) && !defined(WINDOWS) && !defined(ACORN)
24 * A hook for "quit()".
26 * Close down, then fall back into "quit()".
28 static void quit_hook(cptr s)
36 for (j = 8 - 1; j >= 0; j--)
39 if (!angband_term[j]) continue;
42 term_nuke(angband_term[j]);
48 * Set the stack size and overlay buffer (see main-286.c")
52 extern unsigned _stklen = 32768U;
53 extern unsigned _ovrbuffer = 0x1500;
56 #ifdef PRIVATE_USER_PATH
59 * Create an ".angband/" directory in the users home directory.
61 * ToDo: Add error handling.
62 * ToDo: Only create the directories when actually writing files.
64 static void create_user_dir(void)
67 char subdirpath[1024];
69 /* Get an absolute path from the filename */
70 path_parse(dirpath, 1024, PRIVATE_USER_PATH);
72 /* Create the ~/.angband/ directory */
75 /* Build the path to the variant-specific sub-directory */
76 path_build(subdirpath, sizeof(subdirpath), dirpath, VERSION_NAME);
78 /* Create the directory */
79 mkdir(subdirpath, 0700);
82 #endif /* PRIVATE_USER_PATH */
86 * Initialize and verify the file paths, and the score file.
88 * Use the ANGBAND_PATH environment var if possible, else use
89 * DEFAULT_PATH, and in either case, branch off appropriately.
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...
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.
100 * Make sure that the path doesn't overflow the buffer. We have
101 * to leave enough space for the path separator, directory, and
104 static void init_stuff(void)
110 /* Hack -- prepare "path" */
111 strcpy(path, "Angband:");
117 /* Get the environment variable */
118 tail = getenv("ANGBAND_PATH");
120 /* Use the angband_path, or a default */
121 strncpy(path, tail ? tail : DEFAULT_PATH, 511);
123 /* Make sure it's terminated */
126 /* Hack -- Add a path separator (only if needed) */
127 if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP);
132 init_file_paths(path);
138 * Handle a "-d<what>=<path>" option
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").
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").
146 static void change_path(cptr info)
150 /* Find equal sign */
151 s = my_strchr(info, '=');
153 /* Verify equal sign */
154 if (!s) quit_fmt("Try '-d<what>=<path>' not '-d%s'", info);
157 switch (tolower(info[0]))
161 string_free(ANGBAND_DIR_APEX);
162 ANGBAND_DIR_APEX = string_make(s+1);
168 string_free(ANGBAND_DIR_FILE);
169 ANGBAND_DIR_FILE = string_make(s+1);
175 string_free(ANGBAND_DIR_HELP);
176 ANGBAND_DIR_HELP = string_make(s+1);
182 string_free(ANGBAND_DIR_INFO);
183 ANGBAND_DIR_INFO = string_make(s+1);
189 string_free(ANGBAND_DIR_USER);
190 ANGBAND_DIR_USER = string_make(s+1);
196 string_free(ANGBAND_DIR_XTRA);
197 ANGBAND_DIR_XTRA = string_make(s+1);
201 #ifdef VERIFY_SAVEFILE
208 quit_fmt("Restricted option '-d%s'", info);
211 #else /* VERIFY_SAVEFILE */
215 string_free(ANGBAND_DIR_BONE);
216 ANGBAND_DIR_BONE = string_make(s+1);
222 string_free(ANGBAND_DIR_DATA);
223 ANGBAND_DIR_DATA = string_make(s+1);
229 string_free(ANGBAND_DIR_EDIT);
230 ANGBAND_DIR_EDIT = string_make(s+1);
236 string_free(ANGBAND_DIR_SAVE);
237 ANGBAND_DIR_SAVE = string_make(s+1);
243 string_free(ANGBAND_DIR_SCRIPT);
244 ANGBAND_DIR_SCRIPT = string_make(s+1);
248 #endif /* VERIFY_SAVEFILE */
252 quit_fmt("Bad semantics in '-d%s'", info);
259 * Simple "main" function for multiple platforms.
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.
265 int main(int argc, char *argv[])
271 bool new_game = FALSE;
280 /* Save the "program name" XXX XXX XXX */
284 /* Attempt to use XMS (or EMS) memory for swap space */
285 if (_OvrInitExt(0L, 0L))
287 _OvrInitEms(0, 0, 64);
294 /* Default permissions on files */
305 /* Get the file paths */
311 /* Get the user id (?) */
312 player_uid = getuid();
315 /* Mega-Hack -- Factor group id */
316 player_uid += (getgid() * 1000);
321 # ifdef _POSIX_SAVED_IDS
323 /* Save some info for later */
324 player_euid = geteuid();
325 player_egid = getegid();
329 # if 0 /* XXX XXX XXX */
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 */
334 if (setgid(getegid()) != 0)
336 quit("setgid(): cannot set permissions correctly!");
339 if (setuid(geteuid()) != 0)
341 quit("setuid(): cannot set permissions correctly!");
351 /* Drop permissions */
357 /* Initialize the "time" checker */
358 if (check_time_init() || check_time())
360 quit("The gates to Angband are closed (bad time).");
363 /* Initialize the "load" checker */
364 if (check_load_init() || check_load())
366 quit("The gates to Angband are closed (bad load).");
369 /* Acquire the "user name" as a default player name */
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 */
376 #ifdef PRIVATE_USER_PATH
378 /* Create a directory for the users files. */
381 #endif /* PRIVATE_USER_PATH */
386 /* Process the command line arguments */
387 for (i = 1; args && (i < argc); i++)
389 /* Require proper options */
390 if (argv[i][0] != '-') goto usage;
433 /* HACK - Graphics mode switches on the original tiles */
434 arg_graphics = GRAPHICS_ORIGINAL;
441 arg_force_roguelike = TRUE;
448 arg_force_original = TRUE;
455 show_score = atoi(&argv[i][2]);
456 if (show_score <= 0) show_score = 10;
463 if (!argv[i][2]) goto usage;
465 strcpy(player_name, &argv[i][2]);
466 #else /* ANGBAND_2_8_1 */
468 /* Get the savefile name */
469 strncpy(op_ptr->full_name, &argv[i][2], 32);
471 /* Make sure it's terminated */
472 op_ptr->full_name[31] = '\0';
474 #endif /* ANGBAND_2_8_1 */
480 if (!argv[i][2]) goto usage;
487 arg_monochrome = TRUE;
494 change_path(&argv[i][2]);
502 if (!argv[i][2]) goto usage;
503 chuukei_server = TRUE;
504 if (connect_chuukei_server(&argv[i][2]) < 0) chuukei_server = FALSE;
511 if (!argv[i][2]) goto usage;
512 chuukei_client = TRUE;
513 connect_chuukei_server(&argv[i][2]);
520 if (!argv[i][2]) goto usage;
521 prepare_browse_movie(&argv[i][2]);
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");
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");
567 puts(" -mgcu To use GCU (GNU Curses)");
571 puts(" -mcap To use CAP (\"Termcap\" calls)");
575 puts(" -mdos To use DOS (Graphics)");
579 puts(" -mibm To use IBM (BIOS text mode)");
583 puts(" -msla To use SLA (SLANG)");
587 puts(" -mlsl To use LSL (Linux-SVGALIB)");
591 puts(" -mvme To use VME (VAX/ESA)");
594 /* Actually abort the process */
600 /* Hack -- Forget standard args */
608 /* Process the player name */
609 process_player_name(TRUE);
613 /* Install "quit" hook */
614 quit_aux = quit_hook;
619 /* Attempt to use the "main-xaw.c" support */
620 if (!done && (!mstr || (streq(mstr, "xaw"))))
622 extern errr init_xaw(int, char**);
623 if (0 == init_xaw(argc, argv))
632 /* Attempt to use the "main-x11.c" support */
633 if (!done && (!mstr || (streq(mstr, "x11"))))
635 extern errr init_x11(int, char**);
636 if (0 == init_x11(argc, argv))
645 /* Attempt to use the "main-gcu.c" support */
646 if (!done && (!mstr || (streq(mstr, "gcu"))))
648 extern errr init_gcu(int, char**);
649 if (0 == init_gcu(argc, argv))
658 /* Attempt to use the "main-cap.c" support */
659 if (!done && (!mstr || (streq(mstr, "cap"))))
661 extern errr init_cap(int, char**);
662 if (0 == init_cap(argc, argv))
672 /* Attempt to use the "main-dos.c" support */
673 if (!done && (!mstr || (streq(mstr, "dos"))))
675 extern errr init_dos(void);
685 /* Attempt to use the "main-ibm.c" support */
686 if (!done && (!mstr || (streq(mstr, "ibm"))))
688 extern errr init_ibm(void);
699 /* Attempt to use the "main-emx.c" support */
700 if (!done && (!mstr || (streq(mstr, "emx"))))
702 extern errr init_emx(void);
713 /* Attempt to use the "main-sla.c" support */
714 if (!done && (!mstr || (streq(mstr, "sla"))))
716 extern errr init_sla(void);
727 /* Attempt to use the "main-lsl.c" support */
728 if (!done && (!mstr || (streq(mstr, "lsl"))))
730 extern errr init_lsl(void);
741 /* Attempt to use the "main-ami.c" support */
742 if (!done && (!mstr || (streq(mstr, "ami"))))
744 extern errr init_ami(void);
755 /* Attempt to use the "main-vme.c" support */
756 if (!done && (!mstr || (streq(mstr, "vme"))))
758 extern errr init_vme(void);
768 /* Make sure we have a display! */
769 if (!done) quit("Unable to prepare any 'display module'!");
772 /* Hack -- If requested, display scores and quit */
773 if (show_score > 0) display_scores(0, show_score);
776 /* Catch nasty signals */
782 /* Wait for response */