+ PK3_OpenLibrary ();
+ fs_mempool = Mem_AllocPool("file management", 0, NULL);
+ if(com_selffd >= 0)
+ {
+ fs_selfpack = FS_LoadPackPK3FromFD(com_argv[0], com_selffd, true);
+ if(fs_selfpack)
+ {
+ char *buf, *q;
+ const char *p;
+ FS_AddSelfPack();
+ buf = (char *) FS_LoadFile("darkplaces.opt", tempmempool, true, NULL);
+ if(buf)
+ {
+ const char **new_argv;
+ int i = 0;
+ int args_left = 256;
+ new_argv = (const char **)Mem_Alloc(fs_mempool, sizeof(*com_argv) * (com_argc + args_left + 2));
+ if(com_argc == 0)
+ {
+ new_argv[0] = "dummy";
+ com_argc = 1;
+ }
+ else
+ {
+ memcpy((char *)(&new_argv[0]), &com_argv[0], sizeof(*com_argv) * com_argc);
+ }
+ p = buf;
+ while(COM_ParseToken_Console(&p))
+ {
+ if(i >= args_left)
+ break;
+ q = (char *)Mem_Alloc(fs_mempool, strlen(com_token) + 1);
+ strlcpy(q, com_token, strlen(com_token) + 1);
+ new_argv[com_argc + i] = q;
+ ++i;
+ }
+ new_argv[i+com_argc] = NULL;
+ com_argv = new_argv;
+ com_argc = com_argc + i;
+ }
+ Mem_Free(buf);
+ }
+ }
+}
+
+/*
+================
+FS_Init
+================
+*/
+void FS_Init (void)
+{
+ const char *p;
+ int i;
+#ifdef WIN32
+ TCHAR mydocsdir[MAX_PATH + 1];
+#if _MSC_VER >= 1400
+ size_t homedirlen;
+#endif
+#endif
+#ifndef __IPHONEOS__
+ char *homedir;
+#endif
+
+#ifdef WIN32
+ const char* dllnames [] =
+ {
+ "shfolder.dll", // IE 4, or Win NT and higher
+ NULL
+ };
+ Sys_LoadLibrary(dllnames, &shfolder_dll, shfolderfuncs);
+ // don't care for the result; if it fails, %USERPROFILE% will be used instead
+#endif
+
+ *fs_basedir = 0;
+ *fs_userdir = 0;
+ *fs_gamedir = 0;
+
+#ifdef __IPHONEOS__
+ // fs_basedir is "" by default, to utilize this you can simply add your gamedir to the Resources in xcode
+ // fs_userdir stores configurations to the Documents folder of the app
+ strlcpy(fs_userdir, "../Documents/", sizeof(fs_userdir));
+#else
+ // Add the personal game directory
+ if((i = COM_CheckParm("-userdir")) && i < com_argc - 1)
+ {
+ dpsnprintf(fs_userdir, sizeof(fs_userdir), "%s/", com_argv[i+1]);
+ }
+ else if(COM_CheckParm("-nohome"))
+ {
+ *fs_userdir = 0;
+ }
+ else
+ {
+#ifdef WIN32
+ if(qSHGetFolderPath && (qSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, mydocsdir) == S_OK))
+ {
+ dpsnprintf(fs_userdir, sizeof(fs_userdir), "%s/My Games/%s/", mydocsdir, gameuserdirname);
+ Con_DPrintf("Obtained personal directory %s from SHGetFolderPath\n", fs_userdir);
+ }
+ else
+ {
+ // use the environment
+#if _MSC_VER >= 1400
+ _dupenv_s (&homedir, &homedirlen, "USERPROFILE");
+#else
+ homedir = getenv("USERPROFILE");
+#endif
+
+ if(homedir)
+ {
+ dpsnprintf(fs_userdir, sizeof(fs_userdir), "%s/My Documents/My Games/%s/", homedir, gameuserdirname);
+#if _MSC_VER >= 1400
+ free(homedir);
+#endif
+ Con_DPrintf("Obtained personal directory %s from environment\n", fs_userdir);
+ }
+ }
+
+ if(!*fs_userdir)
+ Con_DPrintf("Could not obtain home directory; not supporting -mygames\n");
+#else
+ homedir = getenv ("HOME");
+ if(homedir)
+ dpsnprintf(fs_userdir, sizeof(fs_userdir), "%s/.%s/", homedir, gameuserdirname);
+
+ if(!*fs_userdir)
+ Con_DPrintf("Could not obtain home directory; assuming -nohome\n");
+#endif
+
+#ifdef WIN32
+ if(!COM_CheckParm("-mygames"))
+ {
+#if _MSC_VER >= 1400
+ int fd;
+ _sopen_s(&fd, va("%s%s/config.cfg", fs_basedir, gamedirname1), O_WRONLY | O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE); // note: no O_TRUNC here!
+#else
+ int fd = open (va("%s%s/config.cfg", fs_basedir, gamedirname1), O_WRONLY | O_CREAT, 0666); // note: no O_TRUNC here!
+#endif
+ if(fd >= 0)
+ {
+ close(fd);
+ *fs_userdir = 0; // we have write access to the game dir, so let's use it
+ }
+ }
+#endif
+ }
+
+ strlcpy(fs_gamedir, "", sizeof(fs_gamedir));
+
+// If the base directory is explicitly defined by the compilation process
+#ifdef DP_FS_BASEDIR
+ strlcpy(fs_basedir, DP_FS_BASEDIR, sizeof(fs_basedir));
+#else
+ *fs_basedir = 0;
+
+#ifdef MACOSX
+ // FIXME: is there a better way to find the directory outside the .app?
+ if (strstr(com_argv[0], ".app/"))
+ {
+ char *split;
+
+ split = strstr(com_argv[0], ".app/");
+ while (split > com_argv[0] && *split != '/')
+ split--;
+ strlcpy(fs_basedir, com_argv[0], sizeof(fs_basedir));
+ fs_basedir[split - com_argv[0]] = 0;
+ }
+#endif
+#endif
+#endif
+
+ // -basedir <path>
+ // Overrides the system supplied base directory (under GAMENAME)
+// COMMANDLINEOPTION: Filesystem: -basedir <path> chooses what base directory the game data is in, inside this there should be a data directory for the game (for example id1)
+ i = COM_CheckParm ("-basedir");
+ if (i && i < com_argc-1)
+ {
+ strlcpy (fs_basedir, com_argv[i+1], sizeof (fs_basedir));
+ i = (int)strlen (fs_basedir);
+ if (i > 0 && (fs_basedir[i-1] == '\\' || fs_basedir[i-1] == '/'))
+ fs_basedir[i-1] = 0;
+ }
+
+ // add a path separator to the end of the basedir if it lacks one
+ if (fs_basedir[0] && fs_basedir[strlen(fs_basedir) - 1] != '/' && fs_basedir[strlen(fs_basedir) - 1] != '\\')
+ strlcat(fs_basedir, "/", sizeof(fs_basedir));
+
+ FS_ListGameDirs();
+
+ p = FS_CheckGameDir(gamedirname1);
+ if(!p || p == fs_checkgamedir_missing)
+ Con_Printf("WARNING: base gamedir %s%s/ not found!\n", fs_basedir, gamedirname1);
+
+ if(gamedirname2)
+ {
+ p = FS_CheckGameDir(gamedirname2);
+ if(!p || p == fs_checkgamedir_missing)
+ Con_Printf("WARNING: base gamedir %s%s/ not found!\n", fs_basedir, gamedirname2);
+ }
+
+ // -game <gamedir>
+ // Adds basedir/gamedir as an override game
+ // LordHavoc: now supports multiple -game directories
+ for (i = 1;i < com_argc && fs_numgamedirs < MAX_GAMEDIRS;i++)
+ {
+ if (!com_argv[i])
+ continue;
+ if (!strcmp (com_argv[i], "-game") && i < com_argc-1)
+ {
+ i++;
+ p = FS_CheckGameDir(com_argv[i]);
+ if(!p)
+ Sys_Error("Nasty -game name rejected: %s", com_argv[i]);
+ if(p == fs_checkgamedir_missing)
+ Con_Printf("WARNING: -game %s%s/ not found!\n", fs_basedir, com_argv[i]);
+ // add the gamedir to the list of active gamedirs
+ strlcpy (fs_gamedirs[fs_numgamedirs], com_argv[i], sizeof(fs_gamedirs[fs_numgamedirs]));
+ fs_numgamedirs++;
+ }
+ }
+
+ // generate the searchpath
+ FS_Rescan();
+}
+
+void FS_Init_Commands(void)
+{
+ Cvar_RegisterVariable (&scr_screenshot_name);
+ Cvar_RegisterVariable (&fs_empty_files_in_pack_mark_deletions);
+ Cvar_RegisterVariable (&cvar_fs_gamedir);