Main.c

/* File: main.c */ /* * Copyright (c) 1997 Ben Harrison, and others * * This software may be copied and distributed for educational, research, * and not for profit purposes provided that this copyright and statement * are included in all such copies. */ /* * Some machines have a "main" function in their "main-xxx.c" file, * all the others use this file for their "main" function. */    || (!defined(WINDOWS) && !defined(RISCOS)) \ || defined(USE_SDL) /* * List of the available modules in the order they are tried. */ static const struct module modules[] = { 	{ "gtk", help_gtk, init_gtk }, { "xaw", help_xaw, init_xaw }, { "x11", help_x11, init_x11 }, { "sdl", help_sdl, init_sdl }, { "gcu", help_gcu, init_gcu }, }; /* * List of sound modules in the order they should be tried. */ static const struct module sound_modules[] = { 	{ "sdl", "SDL_mixer sound module", init_sound_sdl }, { "dummy", "Dummy module", NULL }, }; /* * A hook for "quit". * * Close down, then fall back into "quit". */ static void quit_hook(cptr s) { int j; 	/* Unused parameter */ (void)s; /* Scan windows */ for (j = ANGBAND_TERM_MAX - 1; j >= 0; j--) { 		/* Unused */ if (!angband_term[j]) continue; /* Nuke it */ term_nuke(angband_term[j]); } } /* * SDL needs a look-in */ /* * Initialize and verify the file paths, and the score file. * * Use the ANGBAND_PATH environment var if possible, else use * DEFAULT_PATH, and in either case, branch off appropriately. * * First, we'll look for the ANGBAND_PATH environment variable, * and then look for the files in there. If that doesn't work, * we'll try the DEFAULT_PATH constant. So be sure that one of * these two things works... * * We must ensure that the path ends with "PATH_SEP" if needed, * since the "init_file_paths" function will simply append the * relevant "sub-directory names" to the given path. * * Make sure that the path doesn't overflow the buffer. We have * to leave enough space for the path separator, directory, and * filenames. */ static void init_stuff(void) { 	char path[1024]; cptr tail = NULL; /* Get the environment variable */ tail = getenv("ANGBAND_PATH"); /* Use the angband_path, or a default */ my_strcpy(path, tail ? tail : DEFAULT_PATH, sizeof(path)); /* Make sure it's terminated */ path[511] = '\0'; /* Hack -- Add a path separator (only if needed) */ if (!suffix(path, PATH_SEP)) my_strcat(path, PATH_SEP, sizeof(path)); /* Initialize */ init_file_paths(path); } /* * Handle a "-d = " option * * The " " can be any string starting with the same letter as the * name of a subdirectory of the "lib" folder (i.e. "i" or "info"). * * The " " can be any legal path for the given system, and should * not end in any special path separator (i.e. "/tmp" or "~/.ang-info"). */ static void change_path(cptr info) { 	cptr s; 	/* Find equal sign */ s = strchr(info, '='); /* Verify equal sign */ if (!s) quit_fmt("Try '-d = ' not '-d%s'", info); /* Analyze */ switch (tolower((unsigned char)info[0])) { 		case 'a': { 			string_free(ANGBAND_DIR_APEX); ANGBAND_DIR_APEX = string_make(s+1); break; } 		case 'f': { 			string_free(ANGBAND_DIR_FILE); ANGBAND_DIR_FILE = string_make(s+1); break; } 		case 'h': { 			string_free(ANGBAND_DIR_HELP); ANGBAND_DIR_HELP = string_make(s+1); break; } 		case 'i': { 			string_free(ANGBAND_DIR_INFO); ANGBAND_DIR_INFO = string_make(s+1); break; } 		case 'x': { 			string_free(ANGBAND_DIR_XTRA); ANGBAND_DIR_XTRA = string_make(s+1); break; } 		case 'b': { 			string_free(ANGBAND_DIR_BONE); ANGBAND_DIR_BONE = string_make(s+1); break; } 		case 'd': { 			string_free(ANGBAND_DIR_DATA); ANGBAND_DIR_DATA = string_make(s+1); break; } 		case 'e': { 			string_free(ANGBAND_DIR_EDIT); ANGBAND_DIR_EDIT = string_make(s+1); break; } 		case 's': { 			string_free(ANGBAND_DIR_SAVE); ANGBAND_DIR_SAVE = string_make(s+1); break; } 		case 'u': { 			string_free(ANGBAND_DIR_USER); ANGBAND_DIR_USER = string_make(s+1); break; } 		default: { 			quit_fmt("Bad semantics in '-d%s'", info); } 	} } /* * Simple "main" function for multiple platforms. * * Note the special "--" option which terminates the processing of  * standard options. All non-standard options (if any) are passed * directly to the "init_xxx" function. */ int main(int argc, char *argv[]) { 	int i; 	bool done = FALSE; bool new_game = FALSE; int show_score = 0; const char *mstr = NULL; bool args = TRUE; /* Save the "program name" XXX XXX XXX */ argv0 = argv[0]; /* Default permissions on files */ (void)umask(022); /* Get the file paths */ init_stuff; /* Get the user id */ player_uid = getuid; /* Save the effective GID for later recall */ player_egid = getegid; /* Drop permissions */ safe_setuid_drop; /* Get the "user name" as a default player name */ user_name(op_ptr->full_name, sizeof(op_ptr->full_name), player_uid); /* Create directories for the users files */ create_user_dirs; /* Process the command line arguments */ for (i = 1; args && (i < argc); i++) { 		cptr arg = argv[i]; /* Require proper options */ if (*arg++ != '-') goto usage; /* Analyze option */ switch (*arg++) { 			case 'N': case 'n': { 				new_game = TRUE; break; } 			case 'F': case 'f': { 				arg_fiddle = TRUE; break; } 			case 'W': case 'w': { 				arg_wizard = TRUE; break; } 			case 'V': case 'v': { 				arg_sound = TRUE; break; } 			case 'G': case 'g': { 				/* Default graphics tile */ arg_graphics = GRAPHICS_ADAM_BOLT; break; } 			case 'S': case 's': { 				show_score = atoi(arg); if (show_score <= 0) show_score = 10; continue; } 			case 'u': case 'U': { 				if (!*arg) goto usage; /* Get the savefile name */ my_strcpy(op_ptr->full_name, arg, sizeof(op_ptr->full_name)); continue; } 			case 'm': case 'M': { 				if (!*arg) goto usage; mstr = arg; continue; } 			case 'd': case 'D': { 				change_path(arg); continue; } 			case '-': { 				argv[i] = argv[0]; argc = argc - i; 				argv = argv + i; 				args = FALSE; break; } 			default: usage: { 				/* Dump usage information */ puts("Usage: angband [options] [-- subopts]"); puts(" -n             Start a new character"); puts(" -w             Resurrect dead character (marks savefile)"); puts(" -f             Request fiddle (verbose) mode"); puts(" -v             Request sound mode"); puts(" -g             Request graphics mode"); puts(" -s        Show high scores (default: 10)"); puts(" -u        Use your savefile"); puts(" -d = Instead of lib/, use "); puts(" -m        Use module, where can be:"); /* Print the name and help for each available module */ for (i = 0; i < (int)N_ELEMENTS(modules); i++) { 					printf("    %s   %s\n", 					       modules[i].name, modules[i].help); } 				/* Actually abort the process */ quit(NULL); } 		} 		if (*arg) goto usage; } 	/* Hack -- Forget standard args */ if (args) { 		argc = 1; argv[1] = NULL; } 	/* Process the player name */ process_player_name(TRUE); /* Install "quit" hook */ quit_aux = quit_hook; /* Try the modules in the order specified by modules[] */ for (i = 0; i < (int)N_ELEMENTS(modules); i++) { 		/* User requested a specific module? */ 		if (!mstr || (streq(mstr, modules[i].name))) { 			if (0 == modules[i].init(argc, argv)) { 				ANGBAND_SYS = modules[i].name; done = TRUE; break; } 		} 	} 	/* Make sure we have a display! */ 	if (!done) quit("Unable to prepare any 'display module'!"); /* Try the modules in the order specified by sound_modules[] */ for (i = 0; i < (int)N_ELEMENTS(sound_modules) - 1; i++) { 		if (0 == sound_modules[i].init(argc, argv)) break; } 	/* Catch nasty signals */ signals_init; /* Initialize */ init_angband; /* Hack -- If requested, display scores and quit */ if (show_score > 0) display_scores(0, show_score); /* Wait for response */ pause_line(Term->hgt - 1); /* Play the game */ play_game(new_game); /* Free resources */ cleanup_angband; /* Quit */ quit(NULL); /* Exit */ return (0); }
 * 1) include "angband.h"
 * 1) if defined(WIN32_CONSOLE_MODE) \
 * 1) include "main.h"
 * 1) ifdef USE_GTK
 * 1) endif /* USE_GTK */
 * 1) ifdef USE_XAW
 * 1) endif /* USE_XAW */
 * 1) ifdef USE_X11
 * 1) endif /* USE_X11 */
 * 1) ifdef USE_SDL
 * 1) endif /* USE_SDL */
 * 1) ifdef USE_GCU
 * 1) endif /* USE_GCU */
 * 1) ifdef USE_SOUND
 * 1) ifdef SOUND_SDL
 * 1) endif /* SOUND_SDL */
 * 1) endif
 * 1) ifdef USE_SDL
 * 2) include "SDL.h"
 * 3) endif
 * 1) ifndef FIXED_PATHS
 * 1) endif /* FIXED_PATHS */
 * 1) ifndef FIXED_PATHS
 * 1) endif /* FIXED_PATHS */
 * 1) ifdef SET_UID
 * 1) endif /* SET_UID */
 * 1) ifdef SET_UID
 * 1) endif /* SET_UID */
 * 1) ifdef SET_UID
 * 1) ifdef PRIVATE_USER_PATH
 * 1) endif /* PRIVATE_USER_PATH */
 * 1) endif /* SET_UID */
 * 1) ifdef USE_SOUND
 * 1) endif
 * 1) endif /* !defined(MACINTOSH) && !defined(WINDOWS) && !defined(RISCOS) */