+ // look for the pop.lmp file and set registered to true if it is found
+ if ((gamemode == GAME_NORMAL || gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE) && !FS_FileExists("gfx/pop.lmp"))
+ {
+ if (fs_modified)
+ Con_Print("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
+ else
+ Con_Print("Playing shareware version.\n");
+ }
+ else
+ {
+ Cvar_Set ("registered", "1");
+ if (gamemode == GAME_NORMAL || gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
+ Con_Print("Playing registered version.\n");
+ }
+}
+
+
+/*
+================
+FS_ChangeGameDir
+================
+*/
+void Host_SaveConfig_f (void);
+void Host_LoadConfig_f (void);
+qboolean FS_ChangeGameDir(const char *string)
+{
+ // if already using the requested gamedir, do nothing
+ if (fs_numgamedirs == 1 && !strcmp(fs_gamedirs[0], string))
+ return false;
+
+ // if string is nasty, reject it
+ if(FS_CheckNastyPath(string, true)) // overflowed or nasty?
+ {
+ Con_Printf("FS_ChangeGameDir(\"%s\"): nasty filename rejected\n", string);
+ return false;
+ }
+
+ // save the current config
+ Host_SaveConfig_f();
+
+ // change to the new gamedir
+ fs_numgamedirs = 1;
+ strlcpy(fs_gamedirs[0], string, sizeof(fs_gamedirs[0]));
+
+ // reinitialize filesystem to detect the new paks
+ FS_Rescan_f();
+
+ // exec the new config
+ Host_LoadConfig_f();
+
+ // reinitialize the loaded sounds
+ S_Reload_f();
+
+ // reinitialize renderer (this reloads hud/console background/etc)
+ R_Modules_Restart();
+
+ return true;
+}
+
+/*
+================
+FS_GameDir_f
+================
+*/
+void FS_GameDir_f (void)
+{
+ int i;
+
+ if (Cmd_Argc() < 2)
+ {
+ Con_Printf("gamedirs active:");
+ for (i = 0;i < fs_numgamedirs;i++)
+ Con_Printf(" %s", fs_gamedirs[i]);
+ Con_Printf("\n");
+ return;
+ }
+
+ if (cls.state != ca_disconnected || sv.active)
+ {
+ Con_Printf("Can not change gamedir while client is connected or server is running!\n");
+ return;
+ }
+
+ Host_SaveConfig_f();
+
+ fs_numgamedirs = 0;
+ for (i = 1;i < Cmd_Argc() && fs_numgamedirs < MAX_GAMEDIRS;i++)
+ {
+ // if string is nasty, reject it
+ if(FS_CheckNastyPath(Cmd_Argv(i), true)) // overflowed or nasty?
+ {
+ Con_Printf("FS_GameDir_f(\"%s\"): nasty filename rejected\n", Cmd_Argv(i));
+ continue;
+ }
+
+ strlcpy(fs_gamedirs[fs_numgamedirs], Cmd_Argv(i), sizeof(fs_gamedirs[fs_numgamedirs]));
+ fs_numgamedirs++;
+ }
+
+ // reinitialize filesystem to detect the new paks
+ FS_Rescan_f();
+
+ // exec the new config
+ Host_LoadConfig_f();
+
+ // reinitialize the loaded sounds
+ S_Reload_f();
+
+ // reinitialize renderer (this reloads hud/console background/etc)
+ R_Modules_Restart();
+}
+
+
+/*
+================
+FS_Init
+================
+*/
+void FS_Init (void)
+{
+ int i;
+
+ fs_mempool = Mem_AllocPool("file management", 0, NULL);
+
+ 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
+ strlcpy(fs_basedir, "", sizeof(fs_basedir));
+
+#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
+
+ PK3_OpenLibrary ();
+
+ // -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));
+
+ // -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++;
+ // add the gamedir to the list of active gamedirs
+ strlcpy (fs_gamedirs[fs_numgamedirs], com_argv[i], sizeof(fs_gamedirs[fs_numgamedirs]));
+ fs_numgamedirs++;
+ }
+ }
+
+ // update the searchpath
+ FS_Rescan_f();
+}
+
+void FS_Init_Commands(void)
+{
+ Cvar_RegisterVariable (&scr_screenshot_name);
+
+ Cmd_AddCommand ("gamedir", FS_GameDir_f, "changes active gamedir list (can take multiple arguments), not including base directory (example usage: gamedir ctf)");
+ Cmd_AddCommand ("fs_rescan", FS_Rescan_f, "rescans filesystem for new pack archives and any other changes");
+ Cmd_AddCommand ("path", FS_Path_f, "print searchpath (game directories and archives)");
+ Cmd_AddCommand ("dir", FS_Dir_f, "list files in searchpath matching an * filename pattern, one per line");
+ Cmd_AddCommand ("ls", FS_Ls_f, "list files in searchpath matching an * filename pattern, multiple per line");
+}
+
+/*
+================
+FS_Shutdown
+================
+*/
+void FS_Shutdown (void)
+{
+ Mem_FreePool (&fs_mempool);
+}
+
+/*