diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 691 |
1 files changed, 691 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c new file mode 100644 index 00000000..48ab3f04 --- /dev/null +++ b/src/main.c @@ -0,0 +1,691 @@ +/* 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. + */ + +#include "angband.h" + + + +/* + * Some machines have a "main()" function in their "main-xxx.c" file, + * all the others use this file for their "main()" function. + */ + + +#if !defined(MACINTOSH) && !defined(WINDOWS) + + +/* + * A hook for "quit()". + * + * Close down, then fall back into "quit()". + */ +static void quit_hook(cptr s) +{ + int j; + + /* Scan windows */ + for (j = 8 - 1; j >= 0; j--) + { + /* Unused */ + if (!angband_term[j]) continue; + + /* Nuke it */ + term_nuke(angband_term[j]); + } +} + + + +/* + * Check and create if needed the directory dirpath + */ +bool_ private_check_user_directory(cptr dirpath) +{ + /* Is this used anywhere else in *bands? */ + struct stat stat_buf; + + int ret; + + /* See if it already exists */ + ret = stat(dirpath, &stat_buf); + + /* It does */ + if (ret == 0) + { + /* Now we see if it's a directory */ + if ((stat_buf.st_mode & S_IFMT) == S_IFDIR) return (TRUE); + + /* + * Something prevents us from create a directory with + * the same pathname + */ + return (FALSE); + } + + /* No - this maybe the first time. Try to create a directory */ + else + { + /* Create the ~/.ToME directory */ + ret = mkdir(dirpath, 0700); + + /* An error occured */ + if (ret == -1) return (FALSE); + + /* Success */ + return (TRUE); + } +} + +/* + * Check existence of ".ToME/" directory in the user's + * home directory or try to create it if it doesn't exist. + * Returns FALSE if all the attempts fail. + */ +static bool_ check_create_user_dir(void) +{ + char dirpath[1024]; + char versionpath[1024]; + char savepath[1024]; + + /* Get an absolute path from the filename */ + path_parse(dirpath, 1024, PRIVATE_USER_PATH); + strcpy(versionpath, dirpath); + strcat(versionpath, USER_PATH_VERSION); + strcpy(savepath, versionpath); + strcat(savepath, "/save"); + + return private_check_user_directory(dirpath) && private_check_user_directory(versionpath) && private_check_user_directory(savepath); +} + + +/* + * 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. + */ +static void init_stuff(void) +{ + char path[1024]; + + cptr tail; + + /* Get the environment variable */ + tail = getenv("TOME_PATH"); + + /* Use the angband_path, or a default */ + strcpy(path, tail ? tail : DEFAULT_PATH); + + /* Hack -- Add a path separator (only if needed) */ + if (!suffix(path, PATH_SEP)) strcat(path, PATH_SEP); + + /* Initialize */ + init_file_paths(path); +} + + + +/* + * Handle a "-d<what>=<path>" option + * + * The "<what>" 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 "<path>" 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<what>=<path>' not '-d%s'", info); + + /* Analyze */ + switch (tolower(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 'u': + { + string_free(ANGBAND_DIR_USER); + ANGBAND_DIR_USER = string_make(s + 1); + break; + } + + case 'x': + { + string_free(ANGBAND_DIR_XTRA); + ANGBAND_DIR_XTRA = 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; + } + + 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; + + cptr mstr = NULL; + + bool_ args = TRUE; + +#ifdef CHECK_MEMORY_LEAKS + GC_find_leak = 1; +#endif /* CHECK_MEMORY_LEAKS */ + + + /* 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(); + + /* Acquire the "user name" as a default player name */ + user_name(player_name, player_uid); + + + /* + * On multiuser systems, users' private directories are + * used to store pref files, chardumps etc. + */ + { + bool_ ret; + + /* Create a directory for the user's files */ + ret = check_create_user_dir(); + + /* Oops */ + if (ret == FALSE) quit("Cannot create directory " PRIVATE_USER_PATH); + } + + + + + /* Process the command line arguments */ + for (i = 1; args && (i < argc); i++) + { + /* Require proper options */ + if (argv[i][0] != '-') goto usage; + + /* Analyze option */ + switch (argv[i][1]) + { + 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': + { + arg_graphics = TRUE; + break; + } + + case 'R': + case 'r': + { + arg_force_roguelike = TRUE; + break; + } + + case 'O': + case 'o': + { + arg_force_original = TRUE; + break; + } + + case 'S': + case 's': + { + show_score = atoi(&argv[i][2]); + if (show_score <= 0) show_score = 10; + break; + } + + case 'u': + case 'U': + { + if (!argv[i][2]) goto usage; + strcpy(player_name, &argv[i][2]); + strcpy(player_base, &argv[i][2]); + no_begin_screen = TRUE; + break; + } + + case 'm': + { + if (!argv[i][2]) goto usage; + mstr = &argv[i][2]; + break; + } + + case 'M': + { + if (!argv[i][2]) goto usage; + force_module = string_make(&argv[i][2]); + break; + } + + case 'h': + { + goto usage; + break; + } + + case 'H': + { + char *s; + int j; + + init_lua(); + for (j = i + 1; j < argc; j++) + { + s = argv[j]; + + while (*s != '.') s++; + *s = '\0'; + s++; + txt_to_html("head.aux", "foot.aux", argv[j], s, FALSE, FALSE); + } + + return 0; + } + + case 'd': + case 'D': + { + change_path(&argv[i][2]); + break; + } + + case '-': + { + if (argv[i][2] == 'h' && !strcmp((argv[i] + 2), "help")) + goto usage; + else + { + argv[i] = argv[0]; + argc = argc - i; + argv = argv + i; + args = FALSE; + break; + } + } + + default: +usage: + { + int j; + + /* Dump usage information */ + for (j = 0; j < argc; j++) printf("%s ", argv[j]); + printf("\n"); + puts("Usage: tome [options] [-- subopts]"); + puts(" -h This help"); + puts(" -n Start a new character"); + puts(" -f Request fiddle mode"); + puts(" -w Request wizard mode"); + puts(" -v Request sound mode"); + puts(" -g Request graphics mode"); + puts(" -o Request original keyset"); + puts(" -r Request rogue-like keyset"); + puts(" -H <list of files> Convert helpfile to html"); + puts(" -s<num> Show <num> high scores"); + puts(" -u<who> Use your <who> savefile"); + puts(" -M<which> Use the <which> module"); + puts(" -m<sys> Force 'main-<sys>.c' usage"); + puts(" -d<def> Define a 'lib' dir sub-path"); + +#ifdef USE_GTK2 + puts(" -mgtk2 To use GTK2"); + puts(" -- Sub options"); + puts(" -- -n# Number of terms to use"); + puts(" -- -b Turn off software backing store"); +# ifdef USE_GRAPHICS + puts(" -- -s Turn off smoothscaling graphics"); + puts(" -- -o Requests \"old\" graphics"); + puts(" -- -g Requests \"new\" graphics"); + puts(" -- -t Enable transparency effect"); +# endif /* USE_GRAPHICS */ +#endif /* USE_GTK2 */ + +#ifdef USE_XAW + puts(" -mxaw To use XAW"); + puts(" -- Sub options"); + puts(" -- -n# Number of terms to use"); + puts(" -- -d<name> Display to use"); +# ifdef USE_GRAPHICS + puts(" -- -s Turn off smoothscaling graphics"); + puts(" -- -o Requests \"old\" graphics"); +# endif /* USE_GRAPHICS */ +#endif /* USE_XAW */ + +#ifdef USE_X11 + puts(" -mx11 To use X11"); + puts(" -- Sub options"); + puts(" -- -n# Number of terms to use"); + puts(" -- -d<name> Display to use"); +# ifdef USE_GRAPHICS + puts(" -- -s Turn off smoothscaling graphics"); + puts(" -- -o Requests \"old\" graphics"); + puts(" -- -b Requests double-width tiles"); +# endif /* USE_GRAPHICS */ +#endif /* USE_X11 */ + +#ifdef USE_GCU + puts(" -mgcu To use curses"); + puts(" -- Sub options"); + puts(" -- -b Requests big screen"); +#endif /* USE_GCU */ + +#ifdef USE_SLA + puts(" -msla To use SLang"); +#endif /* USE_SLA */ + +#ifdef USE_SDL + puts(" -msdl To use SDL"); + puts(" -- Sub options"); + puts(" -- -n # Number of virtual consoles to use"); + puts(" -- -g Request new graphics (16x16)"); + puts(" -- -o Request old graphics (8x8)"); + puts(" -- -b Requests double-width tiles"); + puts(" -- -w # Request screen width in pixels"); + puts(" -- -h # Request screen height in pixels"); + puts(" -- -bpp # Request screen color depth in bits"); + puts(" -- -fs Start with full-screen display"); + puts(" -- -s # Request font size"); + puts(" -- -f <font> Request true-type font by name"); +#endif /* USE_SDL */ + + /* Actually abort the process */ + quit(NULL); + } + } + } + + /* 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; + + +#ifdef USE_GLU + /* Attempt to use the "main-glu.c" support */ + if (!done && (!mstr || (streq(mstr, "glu")))) + { + extern errr init_glu(int, char**); + if (0 == init_glu(argc, argv)) + { + ANGBAND_SYS = "glu"; + done = TRUE; + } + } +#endif + +#ifdef USE_GTK2 + /* Attempt to use the "main-gtk2.c" support */ + if (!done && (!mstr || (streq(mstr, "gtk2")))) + { + extern errr init_gtk2(int, char**); + if (0 == init_gtk2(argc, argv)) + { + ANGBAND_SYS = "gtk2"; + done = TRUE; + } + } +#endif + +#ifdef USE_GTK + /* Attempt to use the "main-gtk.c" support */ + if (!done && (!mstr || (streq(mstr, "gtk")))) + { + extern errr init_gtk(int, char**); + if (0 == init_gtk(argc, argv)) + { + ANGBAND_SYS = "gtk"; + done = TRUE; + } + } +#endif + +#ifdef USE_XAW + /* Attempt to use the "main-xaw.c" support */ + if (!done && (!mstr || (streq(mstr, "xaw")))) + { + extern errr init_xaw(int, char**); + if (0 == init_xaw(argc, argv)) + { + ANGBAND_SYS = "xaw"; + done = TRUE; + } + } +#endif + +#ifdef USE_X11 + /* Attempt to use the "main-x11.c" support */ + if (!done && (!mstr || (streq(mstr, "x11")))) + { + extern errr init_x11(int, char**); + if (0 == init_x11(argc, argv)) + { + ANGBAND_SYS = "x11"; + done = TRUE; + } + } +#endif + +#ifdef USE_GCU + /* Attempt to use the "main-gcu.c" support */ + if (!done && (!mstr || (streq(mstr, "gcu")))) + { + extern errr init_gcu(int, char**); + if (0 == init_gcu(argc, argv)) + { + ANGBAND_SYS = "gcu"; + done = TRUE; + } + } +#endif + +#ifdef USE_GLU + /* Attempt to use the "main-glu.c" support */ + if (!done && (!mstr || (streq(mstr, "glu")))) + { + extern errr init_glu(int, char**); + if (0 == init_glu(argc, argv)) + { + ANGBAND_SYS = "glu"; + done = TRUE; + } + } +#endif + + +#ifdef USE_SLA + /* Attempt to use the "main-sla.c" support */ + if (!done && (!mstr || (streq(mstr, "sla")))) + { + extern errr init_sla(void); + if (0 == init_sla()) + { + ANGBAND_SYS = "sla"; + done = TRUE; + } + } +#endif + + +#ifdef USE_SDL + /* Attempt to use the "main-sdl.c" support */ + if (!done && (!mstr || (streq(mstr, "sdl")))) + { + extern errr init_sdl(int, char**); + if (0 == init_sdl(argc, argv)) + { + ANGBAND_SYS = "sdl"; + done = TRUE; + } + } +#endif + + /* Make sure we have a display! */ + if (!done) quit("Unable to prepare any 'display module'!"); + + + /* 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(23); + + /* Play the game */ + play_game(new_game); + +#ifdef CHECK_MEMORY_LEAKS + CHECK_LEAKS(); +#endif + + /* Quit */ + quit(NULL); + + /* Exit */ + return (0); +} + +#endif |