// Add IWAD directories parsed from splitting a path string containing // paths separated by PATH_SEPARATOR. 'suffix' is a string to concatenate // to the end of the paths before adding them. static void AddIWADPath(char *path, char *suffix) { char *left, *p; path = M_StringDuplicate(path); // Split into individual dirs within the list. left = path; for (;;) { p = strchr(left, PATH_SEPARATOR); if (p != NULL) { // Break at the separator and use the left hand side // as another iwad dir *p = '\0'; AddIWADDir(M_StringJoin(left, suffix, NULL)); left = p + 1; } else { break; } } AddIWADDir(M_StringJoin(left, suffix, NULL)); free(path); }
// Add standard directories where IWADs are located on Unix systems. // To respect the freedesktop.org specification we support overriding // using standard environment variables. See the XDG Base Directory // Specification: // <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html> static void AddXdgDirs(void) { char *env, *tmp_env; // Quote: // > $XDG_DATA_HOME defines the base directory relative to which // > user specific data files should be stored. If $XDG_DATA_HOME // > is either not set or empty, a default equal to // > $HOME/.local/share should be used. env = getenv("XDG_DATA_HOME"); tmp_env = NULL; if (env == NULL) { char *homedir = getenv("HOME"); if (homedir == NULL) { homedir = "/"; } tmp_env = M_StringJoin(homedir, "/.local/share", NULL); env = tmp_env; } // We support $XDG_DATA_HOME/games/doom (which will usually be // ~/.local/share/games/doom) as a user-writeable extension to // the usual /usr/share/games/doom location. AddIWADDir(M_StringJoin(env, "/games/doom", NULL)); free(tmp_env); // Quote: // > $XDG_DATA_DIRS defines the preference-ordered set of base // > directories to search for data files in addition to the // > $XDG_DATA_HOME base directory. The directories in $XDG_DATA_DIRS // > should be seperated with a colon ':'. // > // > If $XDG_DATA_DIRS is either not set or empty, a value equal to // > /usr/local/share/:/usr/share/ should be used. env = getenv("XDG_DATA_DIRS"); if (env == NULL) { // (Trailing / omitted from paths, as it is added below) env = "/usr/local/share:/usr/share"; } // The "standard" location for IWADs on Unix that is supported by most // source ports is /usr/share/games/doom - we support this through the // XDG_DATA_DIRS mechanism, through which it can be overridden. AddIWADPath(env, "/games/doom"); // The convention set by RBDOOM-3-BFG is to install Doom 3: BFG // Edition into this directory, under which includes the Doom // Classic WADs. AddIWADPath(env, "/games/doom3bfg/base/wads"); }
void SetDisplayDriver(void) { static int first_time = 1; if (first_time) { system_video_env_set = getenv("SDL_VIDEODRIVER") != NULL; first_time = 0; } // Don't override the command line environment, if it has been set. if (system_video_env_set) { return; } // Use the value from the configuration file, if it has been set. if (strcmp(video_driver, "") != 0) { char *env_string; env_string = M_StringJoin("SDL_VIDEODRIVER=", video_driver, NULL); putenv(env_string); free(env_string); } }
static char *CheckDirectoryHasIWAD(char *dir, char *iwadname) { char *filename; // As a special case, the "directory" may refer directly to an // IWAD file if the path comes from DOOMWADDIR or DOOMWADPATH. if (DirIsFile(dir, iwadname) && M_FileExists(dir)) { return M_StringDuplicate(dir); } // Construct the full path to the IWAD if it is located in // this directory, and check if it exists. if (!strcmp(dir, ".")) { filename = M_StringDuplicate(iwadname); } else { filename = M_StringJoin(dir, DIR_SEPARATOR_S, iwadname, NULL); } if (M_FileExists(filename)) { return filename; } free(filename); return NULL; }
void I_InitTimidityConfig(void) { char *env_string; boolean success; temp_timidity_cfg = M_TempFile("timidity.cfg"); if (snd_musicdevice == SNDDEVICE_GUS) { success = GUS_WriteConfig(temp_timidity_cfg); } else { success = WriteWrapperTimidityConfig(temp_timidity_cfg); } // Set the TIMIDITY_CFG environment variable to point to the temporary // config file. if (success) { env_string = M_StringJoin("TIMIDITY_CFG=", temp_timidity_cfg, NULL); putenv(env_string); } else { free(temp_timidity_cfg); temp_timidity_cfg = NULL; } }
static void CheckInstallRootPaths(void) { unsigned int i; for (i=0; i<arrlen(root_path_keys); ++i) { char *install_path; char *subpath; unsigned int j; install_path = GetRegistryString(&root_path_keys[i]); if (install_path == NULL) { continue; } for (j=0; j<arrlen(root_path_subdirs); ++j) { subpath = M_StringJoin(install_path, DIR_SEPARATOR_S, root_path_subdirs[j], NULL); AddIWADDir(subpath); } free(install_path); } }
char *D_FindWADByName(char *name) { char *path; int i; // Absolute path? if (M_FileExists(name)) return name; BuildIWADDirList(); // Search through all IWAD paths for a file with the given name. for (i = 0; i < num_iwad_dirs; ++i) { // As a special case, if this is in DOOMWADDIR or DOOMWADPATH, // the "directory" may actually refer directly to an IWAD // file. if (D_CheckFilename(iwad_dirs[i], name) && M_FileExists(iwad_dirs[i])) return strdup(iwad_dirs[i]); // Construct a string for the full path path = M_StringJoin(iwad_dirs[i], DIR_SEPARATOR_S, name, NULL); if (M_FileExists(path)) return path; free(path); } // File not found return NULL; }
// Only the fields d_name and (as an XSI extension) d_ino are specified // in POSIX.1. Other than Linux, the d_type field is available mainly // only on BSD systems. The remaining fields are available on many, but // not all systems. static boolean IsDirectory(char *dir, struct dirent *de) { #if defined(_DIRENT_HAVE_D_TYPE) if (de->d_type != DT_UNKNOWN && de->d_type != DT_LNK) { return de->d_type == DT_DIR; } else #endif { char *filename; struct stat sb; int result; filename = M_StringJoin(dir, DIR_SEPARATOR_S, de->d_name, NULL); result = stat(filename, &sb); free(filename); if (result != 0) { return false; } return S_ISDIR(sb.st_mode); } }
void I_InitWindowTitle(void) { char *buf; buf = M_StringJoin(window_title, " - ", PACKAGE_STRING, NULL); SDL_WM_SetCaption(buf, NULL); free(buf); }
// Get the filename of a temporary file to write the savegame to. After // the file has been successfully saved, it will be renamed to the // real file. char *P_TempSaveGameFile(void) { static char *filename; if (!filename) filename = M_StringJoin(savegamefolder, "temp.save", NULL); return filename; }
char *P_TempSaveGameFile(void) { static char *filename = NULL; if (filename == NULL) { filename = M_StringJoin(savegamedir, "temp.dsg", NULL); } return filename; }
// // SetSaveGameDir // // Chooses the directory used to store saved games. // void D_SetSaveGameDir(void) { char *iwad_name = SaveGameIWADName(); if (iwad_name == NULL) iwad_name = "unknown.wad"; M_MakeDirectory("savegames"); savegamedir = M_StringJoin("savegames", DIR_SEPARATOR_S, iwad_name, DIR_SEPARATOR_S, NULL); M_MakeDirectory(savegamedir); }
static void SetSDLVideoDriver(void) { // Allow a default value for the SDL video driver to be specified // in the configuration file. if (strcmp(video_driver, "") != 0) { char *env_string; env_string = M_StringJoin("SDL_VIDEODRIVER=", video_driver, NULL); putenv(env_string); free(env_string); } }
static void SetExecutable(mission_config_t *config) { char *extension; free(executable); #ifdef _WIN32 extension = ".exe"; #else extension = ""; #endif executable = M_StringJoin(config->executable, extension, NULL); }
static char *NextGlob(glob_t *glob) { struct dirent *de; do { de = readdir(glob->dir); if (de == NULL) { return NULL; } } while (IsDirectory(glob->directory, de) || !MatchesAnyGlob(de->d_name, glob)); // Return the fully-qualified path, not just the bare filename. return M_StringJoin(glob->directory, DIR_SEPARATOR_S, de->d_name, NULL); }
void I_InitTimidityConfig(void) { dboolean success; temp_timidity_cfg = M_TempFile("timidity.cfg"); success = WriteWrapperTimidityConfig(temp_timidity_cfg); // Set the TIMIDITY_CFG environment variable to point to the temporary // config file. if (success) putenv(M_StringJoin("TIMIDITY_CFG=", temp_timidity_cfg, NULL)); else { free(temp_timidity_cfg); temp_timidity_cfg = NULL; } }
// Check for Doom downloaded via Steam static void CheckSteamEdition(void) { char *install_path = GetRegistryString(&steam_install_location); char *subpath; size_t i; if (install_path == NULL) return; for (i = 0; i < arrlen(steam_install_subdirs); ++i) { subpath = M_StringJoin(install_path, DIR_SEPARATOR_S, steam_install_subdirs[i], NULL); AddIWADDir(subpath); } free(install_path); }
// Check for Doom: Collector's Edition static void CheckCollectorsEdition(void) { char *install_path; char *subpath; unsigned int i; install_path = GetRegistryString(&collectors_edition_value); if (install_path == NULL) return; for (i = 0; i < arrlen(collectors_edition_subdirs); ++i) { subpath = M_StringJoin(install_path, DIR_SEPARATOR_S, collectors_edition_subdirs[i], NULL); AddIWADDir(subpath); } free(install_path); }
char *M_TempFile(char *s) { char *tempdir; #ifdef _WIN32 // Check the TEMP environment variable to find the location. tempdir = getenv("TEMP"); if (tempdir == NULL) { tempdir = "."; } #else // In Unix, just use /tmp. tempdir = "/tmp"; #endif return M_StringJoin(tempdir, DIR_SEPARATOR_S, s, NULL); }
// // M_LoadCVARs // void M_LoadCVARs(char *filename) { int bindcount = 0; int cvarcount = 0; int statcount = 0; // read the file in, overriding any set defaults FILE *file = fopen(filename, "r"); if (!file) { M_CheckCVARs(); M_SaveCVARs(); C_Output("Created <b>%s</b>.", filename); cvarsloaded = true; return; } for (int i = 0; i < MAXALIASES; i++) { aliases[i].name[0] = '\0'; aliases[i].string[0] = '\0'; } // Clear all default controls before reading them from config file if (!togglingvanilla && M_StringEndsWith(filename, PACKAGE_CONFIG)) { for (int i = 0; *actions[i].action; i++) { if (actions[i].keyboard1) *(int *)actions[i].keyboard1 = 0; if (actions[i].keyboard2) *(int *)actions[i].keyboard2 = 0; if (actions[i].mouse1) *(int *)actions[i].mouse1 = -1; if (actions[i].gamepad1) *(int *)actions[i].gamepad1 = 0; if (actions[i].gamepad2) *(int *)actions[i].gamepad2 = 0; } for (int i = 0; i < NUMKEYS; i++) keyactionlist[i][0] = '\0'; } while (!feof(file)) { char cvar[64] = ""; char value[256] = ""; if (fscanf(file, "%63s %255[^\n]\n", cvar, value) != 2) continue; if (cvar[0] == ';') continue; if (M_StringCompare(cvar, "bind")) { bind_cmd_func2("bind", value); bindcount++; continue; } else if (M_StringCompare(cvar, "alias")) { if (!togglingvanilla) alias_cmd_func2("alias", value); continue; } // Strip off trailing non-printable characters (\r characters from DOS text files) while (*value && !isprint((unsigned char)value[strlen(value) - 1])) value[strlen(value) - 1] = '\0'; if (togglingvanilla) { char *value_free = uncommify(value); C_ValidateInput(M_StringJoin(cvar, " ", value_free, NULL)); free(value_free); continue; } // Find the setting in the list for (int i = 0; i < arrlen(cvars); i++) { char *s; if (!M_StringCompare(cvar, cvars[i].name)) continue; // not this one if (M_StringStartsWith(cvar, "stat_")) statcount++; else cvarcount++; // parameter found switch (cvars[i].type) { case DEFAULT_STRING: s = M_StringDuplicate(value + 1); s[strlen(s) - 1] = '\0'; *(char **)cvars[i].location = s; break; case DEFAULT_INT: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); *(int *)cvars[i].location = ParseIntParameter(value, cvars[i].valuealiastype); free(value_free); break; } case DEFAULT_INT_UNSIGNED: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); sscanf(value, "%10u", (unsigned int *)cvars[i].location); free(value_free); break; } case DEFAULT_INT_PERCENT: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); s = M_StringDuplicate(value); if (*s && s[strlen(s) - 1] == '%') s[strlen(s) - 1] = '\0'; *(int *)cvars[i].location = ParseIntParameter(s, cvars[i].valuealiastype); free(value_free); break; } case DEFAULT_FLOAT: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); *(float *)cvars[i].location = ParseFloatParameter(value, cvars[i].valuealiastype); free(value_free); break; } case DEFAULT_FLOAT_PERCENT: { char *value_free = uncommify(value); M_StringCopy(value, value_free, sizeof(value)); s = M_StringDuplicate(value); if (*s && s[strlen(s) - 1] == '%') s[strlen(s) - 1] = '\0'; *(float *)cvars[i].location = ParseFloatParameter(s, cvars[i].valuealiastype); free(value_free); break; } case DEFAULT_OTHER: *(char **)cvars[i].location = M_StringDuplicate(value); break; } // finish break; } } fclose(file); if (!togglingvanilla) { char *cvarcount_str = commify(cvarcount); char *statcount_str = commify(statcount); char *bindcount_str = commify(bindcount); C_Output("Loaded %s CVARs and %s player stats from <b>%s</b>.", cvarcount_str, statcount_str, filename); C_Output("Bound %s actions to the keyboard, mouse and gamepad.", bindcount_str); M_CheckCVARs(); cvarsloaded = true; free(cvarcount_str); free(statcount_str); free(bindcount_str); } }