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.
20 * Available graphic modes
22 #define GRAPHICS_NONE 0
23 #define GRAPHICS_ORIGINAL 1
24 #define GRAPHICS_ADAM_BOLT 2
25 #define GRAPHICS_HENGBAND 3
28 * Some machines have a "main()" function in their "main-xxx.c" file,
29 * all the others use this file for their "main()" function.
37 * A hook for "quit()".
39 * Close down, then fall back into "quit()".
41 static void quit_hook(concptr s)
49 for (j = 8 - 1; j >= 0; j--)
52 if (!angband_term[j]) continue;
55 term_nuke(angband_term[j]);
61 * Set the stack size and overlay buffer (see main-286.c")
63 #ifdef PRIVATE_USER_PATH
66 * Create an ".angband/" directory in the users home directory.
68 * ToDo: Add error handling.
69 * ToDo: Only create the directories when actually writing files.
71 static void create_user_dir(void)
74 char subdirpath[1024];
76 /* Get an absolute path from the filename */
77 path_parse(dirpath, 1024, PRIVATE_USER_PATH);
79 /* Create the ~/.angband/ directory */
82 /* Build the path to the variant-specific sub-directory */
83 path_build(subdirpath, sizeof(subdirpath), dirpath, VERSION_NAME);
85 /* Create the directory */
86 mkdir(subdirpath, 0700);
89 #endif /* PRIVATE_USER_PATH */
93 * Initialize and verify the file paths, and the score file.
95 * Use the ANGBAND_PATH environment var if possible, else use
96 * DEFAULT_PATH, and in either case, branch off appropriately.
98 * First, we'll look for the ANGBAND_PATH environment variable,
99 * and then look for the files in there. If that doesn't work,
100 * we'll try the DEFAULT_PATH constant. So be sure that one of
101 * these two things works...
103 * We must ensure that the path ends with "PATH_SEP" if needed,
104 * since the "init_file_paths()" function will simply append the
105 * relevant "sub-directory names" to the given path.
107 * Make sure that the path doesn't overflow the buffer. We have
108 * to leave enough space for the path separator, directory, and
111 static void init_stuff(void)
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);
130 init_file_paths(path);
136 * Handle a "-d<what>=<path>" option
138 * The "<what>" can be any string starting with the same letter as the
139 * name of a subdirectory of the "lib" folder (i.e. "i" or "info").
141 * The "<path>" can be any legal path for the given system, and should
142 * not end in any special path separator (i.e. "/tmp" or "~/.ang-info").
144 static void change_path(concptr info)
148 /* Find equal sign */
149 s = my_strchr(info, '=');
151 /* Verify equal sign */
152 if (!s) quit_fmt("Try '-d<what>=<path>' not '-d%s'", info);
155 switch (tolower(info[0]))
159 string_free(ANGBAND_DIR_APEX);
160 ANGBAND_DIR_APEX = string_make(s+1);
166 string_free(ANGBAND_DIR_FILE);
167 ANGBAND_DIR_FILE = string_make(s+1);
173 string_free(ANGBAND_DIR_HELP);
174 ANGBAND_DIR_HELP = string_make(s+1);
180 string_free(ANGBAND_DIR_INFO);
181 ANGBAND_DIR_INFO = string_make(s+1);
187 string_free(ANGBAND_DIR_USER);
188 ANGBAND_DIR_USER = string_make(s+1);
194 string_free(ANGBAND_DIR_XTRA);
195 ANGBAND_DIR_XTRA = string_make(s+1);
201 string_free(ANGBAND_DIR_BONE);
202 ANGBAND_DIR_BONE = string_make(s+1);
208 string_free(ANGBAND_DIR_DATA);
209 ANGBAND_DIR_DATA = string_make(s+1);
215 string_free(ANGBAND_DIR_EDIT);
216 ANGBAND_DIR_EDIT = string_make(s+1);
222 string_free(ANGBAND_DIR_SAVE);
223 ANGBAND_DIR_SAVE = string_make(s+1);
229 string_free(ANGBAND_DIR_SCRIPT);
230 ANGBAND_DIR_SCRIPT = string_make(s+1);
236 quit_fmt("Bad semantics in '-d%s'", info);
243 * Simple "main" function for multiple platforms.
245 * Note the special "--" option which terminates the processing of
246 * standard options. All non-standard options (if any) are passed
247 * directly to the "init_xxx()" function.
249 int main(int argc, char *argv[])
254 bool new_game = FALSE;
259 /* Save the "program name" XXX XXX XXX */
264 /* Default permissions on files */
270 /* Get the file paths */
276 /* Get the user id (?) */
277 p_ptr->player_uid = getuid();
280 /* Mega-Hack -- Factor group id */
281 p_ptr->player_uid += (getgid() * 1000);
286 # ifdef _POSIX_SAVED_IDS
288 /* Save some info for later */
289 p_ptr->player_euid = geteuid();
290 p_ptr->player_egid = getegid();
294 # if 0 /* XXX XXX XXX */
296 /* Redundant setting necessary in case root is running the game */
297 /* If not root or game not setuid the following two calls do nothing */
299 if (setgid(getegid()) != 0)
301 quit("setgid(): cannot set permissions correctly!");
304 if (setuid(geteuid()) != 0)
306 quit("setuid(): cannot set permissions correctly!");
316 /* Drop permissions */
322 /* Acquire the "user name" as a default player name */
323 user_name(p_ptr->name, p_ptr->player_uid);
325 #ifdef PRIVATE_USER_PATH
327 /* Create a directory for the users files. */
330 #endif /* PRIVATE_USER_PATH */
335 /* Process the command line arguments */
336 for (i = 1; args && (i < argc); i++)
338 /* Require proper options */
339 if (argv[i][0] != '-') goto usage;
382 /* HACK - Graphics mode switches on the original tiles */
383 arg_graphics = GRAPHICS_ORIGINAL;
390 arg_force_roguelike = TRUE;
397 arg_force_original = TRUE;
404 show_score = atoi(&argv[i][2]);
405 if (show_score <= 0) show_score = 10;
412 if (!argv[i][2]) goto usage;
413 strcpy(p_ptr->name, &argv[i][2]);
419 if (!argv[i][2]) goto usage;
426 arg_monochrome = TRUE;
433 change_path(&argv[i][2]);
441 if (!argv[i][2]) goto usage;
442 chuukei_server = TRUE;
443 if (connect_chuukei_server(&argv[i][2]) < 0) chuukei_server = FALSE;
450 if (!argv[i][2]) goto usage;
451 chuukei_client = TRUE;
452 connect_chuukei_server(&argv[i][2]);
459 if (!argv[i][2]) goto usage;
460 prepare_browse_movie(&argv[i][2]);
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");
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");
506 puts(" -mgcu To use GCU (GNU Curses)");
510 puts(" -mcap To use CAP (\"Termcap\" calls)");
513 /* Actually abort the process */
519 /* Hack -- Forget standard args */
527 /* Process the player name */
528 process_player_name(p_ptr,TRUE);
532 /* Install "quit" hook */
533 quit_aux = quit_hook;
538 /* Attempt to use the "main-xaw.c" support */
539 if (!done && (!mstr || (streq(mstr, "xaw"))))
541 extern errr init_xaw(int, char**);
542 if (0 == init_xaw(argc, argv))
551 /* Attempt to use the "main-x11.c" support */
552 if (!done && (!mstr || (streq(mstr, "x11"))))
554 extern errr init_x11(int, char**);
555 if (0 == init_x11(argc, argv))
564 /* Attempt to use the "main-gcu.c" support */
565 if (!done && (!mstr || (streq(mstr, "gcu"))))
567 extern errr init_gcu(int, char**);
568 if (0 == init_gcu(argc, argv))
577 /* Attempt to use the "main-cap.c" support */
578 if (!done && (!mstr || (streq(mstr, "cap"))))
580 extern errr init_cap(int, char**);
581 if (0 == init_cap(argc, argv))
589 /* Make sure we have a display! */
590 if (!done) quit("Unable to prepare any 'display module'!");
593 /* Hack -- If requested, display scores and quit */
594 if (show_score > 0) display_scores(0, show_score);
597 /* Catch nasty signals */
603 /* Wait for response */
607 play_game(p_ptr, new_game);