basic (very!) implementation of the new filesystem directory struture code.

All the details of game directories will be fully configurable (search
paths and gamecode file name currently supported). Downloading of skins to
qw/skins only currently broken (will download to $gamedir/skins for now).
This commit is contained in:
Bill Currie 2003-01-10 22:47:18 +00:00
parent 33365ef00d
commit 2e0ed3377c
10 changed files with 263 additions and 99 deletions

View file

@ -44,12 +44,17 @@ typedef struct searchpath_s {
struct searchpath_s *next; struct searchpath_s *next;
} searchpath_t; } searchpath_t;
typedef struct gamedir_s {
const char *name;
const char *path;
const char *gamecode;
} gamedir_t;
extern searchpath_t *com_searchpaths; extern searchpath_t *com_searchpaths;
extern gamedir_t *qfs_gamedir;
extern struct cvar_s *fs_userpath; extern struct cvar_s *fs_userpath;
extern struct cvar_s *fs_sharepath; extern struct cvar_s *fs_sharepath;
extern struct cvar_s *fs_basegame;
extern struct cvar_s *fs_skinbase;
extern int file_from_pak; extern int file_from_pak;
extern int com_filesize; extern int com_filesize;
@ -81,8 +86,7 @@ byte *COM_LoadHunkFile (const char *path);
void COM_LoadCacheFile (const char *path, struct cache_user_s *cu); void COM_LoadCacheFile (const char *path, struct cache_user_s *cu);
void COM_CreatePath (const char *path); void COM_CreatePath (const char *path);
void COM_Gamedir (const char *dir); void COM_Gamedir (const char *dir);
void COM_Filesystem_Init (void); void QFS_Init (const char *game);
void COM_Filesystem_Init_Cvars (void);
void COM_Path_f (void); void COM_Path_f (void);
void COM_CreateGameDirectory (const char *gamename); void COM_CreateGameDirectory (const char *gamename);

View file

@ -69,11 +69,13 @@ static const char rcsid[] =
#include "QF/cmd.h" #include "QF/cmd.h"
#include "QF/cvar.h" #include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/hash.h" #include "QF/hash.h"
#include "QF/pak.h" #include "QF/pak.h"
#include "QF/pakfile.h" #include "QF/pakfile.h"
#include "QF/qargs.h" #include "QF/qargs.h"
#include "QF/qendian.h" #include "QF/qendian.h"
#include "QF/qfplist.h"
#include "QF/qtypes.h" #include "QF/qtypes.h"
#include "QF/quakefs.h" #include "QF/quakefs.h"
#include "QF/sys.h" #include "QF/sys.h"
@ -113,8 +115,7 @@ int fnmatch (const char *__pattern, const char *__string, int __flags);
cvar_t *fs_userpath; cvar_t *fs_userpath;
cvar_t *fs_sharepath; cvar_t *fs_sharepath;
cvar_t *fs_basegame; cvar_t *fs_dirconf;
cvar_t *fs_skinbase;
char gamedirfile[MAX_OSPATH]; char gamedirfile[MAX_OSPATH];
@ -122,8 +123,192 @@ char com_gamedir[MAX_OSPATH];
int com_filesize; int com_filesize;
searchpath_t *com_searchpaths; searchpath_t *com_searchpaths;
searchpath_t *com_base_searchpaths; // without gamedirs
//QFS
static void COM_AddGameDirectory (const char *dir); //FIXME
gamedir_t *qfs_gamedir;
static plitem_t *qfs_gd_plist;
static const char *qfs_game = "";
static const char *qfs_default_dirconf =
"{"
" Quake = {"
" Path = \"id1\";"
" };"
" QuakeWorld = {"
" Inherit = (Quake);"
" Path = \"qw\";"
" SkinPath = \"qw/skins\";"
" };"
" \"qw:*\" = {"
" Inherit = (QuakeWorld);"
" Path = \"$gamedir\";"
" GameCode = \"qwprogs.dat\";"
" };"
" \"nq:*\" = {"
" Inherit = (Quake);"
" GameCode = \"progs.dat\";"
" };"
"}";
static void
qfs_get_gd_params (plitem_t *gdpl, gamedir_t *gamedir, dstring_t *path)
{
plitem_t *p;
if ((p = PL_ObjectForKey (gdpl, "Path"))) {
if (path->str[0])
dstring_appendstr (path, ":");
dstring_appendstr (path, p->data);
}
if (!gamedir->gamecode && (p = PL_ObjectForKey (gdpl, "GameCode")))
gamedir->gamecode = strdup (p->data);
}
static void
qfs_inherit (plitem_t *plist, plitem_t *gdpl, gamedir_t *gamedir,
dstring_t *path, hashtab_t *dirs)
{
plitem_t *base;
if (!(base = PL_ObjectForKey (gdpl, "Inherit")))
return;
if (base->type == QFString) {
if (Hash_Find (dirs, base->data))
return;
gdpl = PL_ObjectForKey (plist, base->data);
if (!gdpl) {
Sys_Printf ("base `%s' not found\n", (char *)base->data);
return;
}
Hash_Add (dirs, base->data);
qfs_get_gd_params (gdpl, gamedir, path);
qfs_inherit (plist, gdpl, gamedir, path, dirs);
} else if (base->type == QFArray) {
int i;
plarray_t *a = base->data;
for (i = 0; i < a->numvals; i++) {
base = a->values[i];
if (Hash_Find (dirs, base->data))
continue;
gdpl = PL_ObjectForKey (plist, base->data);
if (!gdpl) {
Sys_Printf ("base `%s' not found\n", (char *)base->data);
continue;
}
Hash_Add (dirs, base->data);
qfs_get_gd_params (gdpl, gamedir, path);
qfs_inherit (plist, gdpl, gamedir, path, dirs);
}
}
}
static int
qfs_compare (const void *a, const void *b)
{
return strcmp ((*(dictkey_t **)a)->key, (*(dictkey_t **)b)->key);
}
static const char *
qfs_dir_get_key (void *_k, void *unused)
{
return _k;
}
static gamedir_t *
qfs_get_gamedir (const char *name)
{
gamedir_t *gamedir;
plitem_t *gdpl;
dstring_t *path;
hashtab_t *dirs = Hash_NewTable (31, qfs_dir_get_key, 0, 0);
gdpl = PL_ObjectForKey (qfs_gd_plist, name);
if (!gdpl) {
dictkey_t **list = (dictkey_t **) Hash_GetList (qfs_gd_plist->data);
dictkey_t **l;
for (l = list; *l; l++)
;
qsort (list, l - list, sizeof (char *), qfs_compare);
while (l-- != list) {
if (!fnmatch ((*l)->key, name, 0)) {
gdpl = (*l)->value;
Hash_Add (dirs, (*l)->key);
break;
}
}
free (list);
if (!gdpl) {
Sys_Printf ("gamedir `%s' not found\n", name);
Hash_DelTable (dirs);
return 0;
}
} else {
Hash_Add (dirs, (void *)name);
}
gamedir = calloc (1, sizeof (gamedir_t));
gamedir->name = strdup (name);
path = dstring_newstr ();
qfs_get_gd_params (gdpl, gamedir, path);
qfs_inherit (qfs_gd_plist, gdpl, gamedir, path, dirs);
gamedir->path = path->str;
free (path);
Hash_DelTable (dirs);
return gamedir;
}
static void
qfs_load_config (void)
{
QFile *f;
int len;
char *buf;
if (!(f = Qopen (fs_dirconf->string, "rt"))) {
Sys_DPrintf ("Could not load `%s', using builtin defaults\n",
fs_dirconf->string);
goto no_config;
}
len = Qfilesize (f);
buf = malloc (len + 3); // +3 for { } and \0
Qread (f, buf + 1, len);
Qclose (f);
// convert the config file to a plist dictionary
buf[0] = '{';
buf[len + 1] = '}';
buf[len + 2] = 0;
qfs_gd_plist = PL_GetPropertyList (buf);
free (buf);
if (qfs_gd_plist && qfs_gd_plist->type == QFDictionary)
return; // done
Sys_Printf ("not a dictionary\n");
no_config:
qfs_gd_plist = PL_GetPropertyList (qfs_default_dirconf);
}
static void
qfs_process_path (const char *path, const char *gamedir)
{
const char *e = path + strlen (path);
const char *s = e;
dstring_t *dir = dstring_new ();
while (s >= path) {
while (s != path && s[-1] !=':')
s--;
if (s != e) {
dsprintf (dir, "%.*s", e - s, s);
if (strequal (dir->str, "$gamedir"))
dsprintf (dir, "%s", gamedir);
COM_AddGameDirectory (dir->str);
}
e = --s;
}
dstring_delete (dir);
}
void void
COM_FileBase (const char *in, char *out) COM_FileBase (const char *in, char *out)
@ -159,8 +344,6 @@ COM_Path_f (void)
Sys_Printf ("Current search path:\n"); Sys_Printf ("Current search path:\n");
for (s = com_searchpaths; s; s = s->next) { for (s = com_searchpaths; s; s = s->next) {
if (s == com_base_searchpaths)
Sys_Printf ("----------\n");
if (s->pack) if (s->pack)
Sys_Printf ("%s (%i files)\n", s->pack->filename, Sys_Printf ("%s (%i files)\n", s->pack->filename,
s->pack->numfiles); s->pack->numfiles);
@ -723,6 +906,8 @@ COM_AddDirectory (const char *dir)
static void static void
COM_AddGameDirectory (const char *dir) COM_AddGameDirectory (const char *dir)
{ {
if (!*dir)
return;
Sys_DPrintf ("COM_AddGameDirectory (\"%s/%s\")\n", Sys_DPrintf ("COM_AddGameDirectory (\"%s/%s\")\n",
fs_sharepath->string, dir); fs_sharepath->string, dir);
@ -739,20 +924,19 @@ COM_AddGameDirectory (const char *dir)
void void
COM_Gamedir (const char *dir) COM_Gamedir (const char *dir)
{ {
searchpath_t *next; if (qfs_gamedir) {
if (qfs_gamedir->name)
if (strstr (dir, "..") || strstr (dir, "/") free ((char *)qfs_gamedir->name);
|| strstr (dir, "\\") || strstr (dir, ":")) { if (qfs_gamedir->path)
Sys_Printf ("Gamedir should be a single filename, not a path\n"); free ((char *)qfs_gamedir->path);
return; if (qfs_gamedir->gamecode)
free ((char *)qfs_gamedir->gamecode);
free (qfs_gamedir);
} }
if (strcmp (gamedirfile, dir) == 0) while (com_searchpaths) {
return; // still the same searchpath_t *next;
strcpy (gamedirfile, dir);
// free up any current game dir info
while (com_searchpaths != com_base_searchpaths) {
if (com_searchpaths->pack) { if (com_searchpaths->pack) {
Qclose (com_searchpaths->pack->handle); Qclose (com_searchpaths->pack->handle);
free (com_searchpaths->pack->files); free (com_searchpaths->pack->files);
@ -763,13 +947,16 @@ COM_Gamedir (const char *dir)
com_searchpaths = next; com_searchpaths = next;
} }
qfs_gamedir = qfs_get_gamedir (va ("%s:%s", qfs_game, dir));
if (qfs_gamedir) {
Sys_DPrintf ("%s\n", qfs_gamedir->name);
Sys_DPrintf (" %s\n", qfs_gamedir->path);
Sys_DPrintf (" %s\n", qfs_gamedir->gamecode);
qfs_process_path (qfs_gamedir->path, dir);
}
// flush all data, so it will be forced to reload // flush all data, so it will be forced to reload
Cache_Flush (); Cache_Flush ();
if (fs_skinbase && strcmp (dir, fs_skinbase->string) == 0)
return;
COM_AddGameDirectory (dir);
} }
void void
@ -781,44 +968,21 @@ COM_CreateGameDirectory (const char *gamename)
} }
void void
COM_Filesystem_Init (void) QFS_Init (const char *game)
{
int i;
// start up with basegame->string by default
COM_CreateGameDirectory (fs_basegame->string);
// If we're dealing with id1, use qw too
if (fs_skinbase && !strequal (fs_basegame->string, fs_skinbase->string)) {
COM_CreateGameDirectory (fs_skinbase->string);
}
if ((i = COM_CheckParm ("-game")) && i < com_argc - 1) {
char *gamedirs = NULL;
char *where;
gamedirs = strdup (com_argv[i + 1]);
where = strtok (gamedirs, ",");
while (where) {
COM_CreateGameDirectory (where);
where = strtok (NULL, ",");
}
free (gamedirs);
}
// any set gamedirs will be freed up to here
com_base_searchpaths = com_searchpaths;
}
void
COM_Filesystem_Init_Cvars (void)
{ {
fs_sharepath = Cvar_Get ("fs_sharepath", FS_SHAREPATH, CVAR_ROM, NULL, fs_sharepath = Cvar_Get ("fs_sharepath", FS_SHAREPATH, CVAR_ROM, NULL,
"location of shared (read only) game " "location of shared (read only) game "
"directories"); "directories");
fs_userpath = Cvar_Get ("fs_userpath", FS_USERPATH, CVAR_ROM, NULL, fs_userpath = Cvar_Get ("fs_userpath", FS_USERPATH, CVAR_ROM, NULL,
"location of your game directories"); "location of your game directories");
fs_basegame = Cvar_Get ("fs_basegame", "id1", CVAR_ROM, NULL, fs_dirconf = Cvar_Get ("fs_dirconf", "", CVAR_ROM, NULL,
"game to use by default"); "full path to gamedir.conf FIXME");
qfs_load_config ();
qfs_game = game;
COM_Gamedir ("");
} }
const char * const char *

View file

@ -85,18 +85,7 @@ W_LoadWadFile (const char *filename)
wad_base = COM_LoadHunkFile (filename); wad_base = COM_LoadHunkFile (filename);
if (!wad_base) if (!wad_base)
{
Sys_Printf ("\n The following error is somewhat misleading. Most "
"likely you don't\n have a file by that name on your "
"system because it's stored in a pak\n file. The real "
"problem is that it's not where we expect it to be.\n\n"
" Game data should be installed into fs_sharepath or "
"fs_userpath, in a\n subdirectory named %s.\n\n",
fs_basegame->string);
Sys_Printf (" fs_sharepath is %s\n", fs_sharepath->string);
Sys_Printf (" fs_userpath is %s\n\n", fs_userpath->string);
Sys_Error ("W_LoadWadFile: unable to load %s", filename); Sys_Error ("W_LoadWadFile: unable to load %s", filename);
}
header = (wadinfo_t *) wad_base; header = (wadinfo_t *) wad_base;

View file

@ -899,11 +899,11 @@ Host_Init (void)
pr_gametype = "netquake"; pr_gametype = "netquake";
QFS_Init ("nq");
PI_Init (); PI_Init ();
Chase_Init_Cvars (); Chase_Init_Cvars ();
CL_InitCvars (); CL_InitCvars ();
COM_Filesystem_Init_Cvars ();
IN_Init_Cvars (); IN_Init_Cvars ();
VID_Init_Cvars (); VID_Init_Cvars ();
S_Init_Cvars (); S_Init_Cvars ();
@ -921,7 +921,6 @@ Host_Init (void)
BI_Init (); BI_Init ();
V_Init (); V_Init ();
COM_Filesystem_Init ();
Game_Init (); Game_Init ();
COM_Init (); COM_Init ();

View file

@ -40,6 +40,7 @@ static const char rcsid[] =
#include "QF/cmd.h" #include "QF/cmd.h"
#include "QF/console.h" #include "QF/console.h"
#include "QF/cvar.h" #include "QF/cvar.h"
#include "QF/quakefs.h"
#include "host.h" #include "host.h"
#include "server.h" #include "server.h"
@ -136,11 +137,17 @@ SV_LoadProgs (void)
{ {
ddef_t *def; ddef_t *def;
dfunction_t *f; dfunction_t *f;
const char *progs_name = "progs.dat";
PR_LoadProgs (&sv_pr_state, sv_progs->string, sv.max_edicts, if (qfs_gamedir->gamecode && *qfs_gamedir->gamecode)
progs_name = qfs_gamedir->gamecode;
if (*sv_progs->string)
progs_name = sv_progs->string;
PR_LoadProgs (&sv_pr_state, progs_name, sv.max_edicts,
sv_progs_zone->int_val * 1024); sv_progs_zone->int_val * 1024);
if (!sv_pr_state.progs) if (!sv_pr_state.progs)
Host_Error ("SV_LoadProgs: couldn't load %s", sv_progs->string); Host_Error ("SV_LoadProgs: couldn't load %s", progs_name);
// progs engine needs these globals anyway // progs engine needs these globals anyway
sv_globals.self = sv_pr_state.globals.self; sv_globals.self = sv_pr_state.globals.self;
sv_globals.time = sv_pr_state.globals.time; sv_globals.time = sv_pr_state.globals.time;
@ -348,9 +355,8 @@ SV_Progs_Init (void)
void void
SV_Progs_Init_Cvars (void) SV_Progs_Init_Cvars (void)
{ {
sv_progs = Cvar_Get ("sv_progs", "progs.dat", CVAR_ROM, NULL, sv_progs = Cvar_Get ("sv_progs", "", CVAR_ROM, NULL,
"Allows selectable game progs if you have several " "Override the default game progs.");
"of them in the gamedir");
sv_progs_zone = Cvar_Get ("sv_progs_zone", "256", CVAR_NONE, NULL, sv_progs_zone = Cvar_Get ("sv_progs_zone", "256", CVAR_NONE, NULL,
"size of the zone for progs in kb"); "size of the zone for progs in kb");
pr_checkextensions = Cvar_Get ("pr_checkextensions", "1", CVAR_ROM, NULL, pr_checkextensions = Cvar_Get ("pr_checkextensions", "1", CVAR_ROM, NULL,

View file

@ -1710,6 +1710,7 @@ Host_Init (void)
cls.userinfo = Info_ParseString ("", MAX_INFO_STRING); cls.userinfo = Info_ParseString ("", MAX_INFO_STRING);
cl.serverinfo = Info_ParseString ("", MAX_INFO_STRING); cl.serverinfo = Info_ParseString ("", MAX_INFO_STRING);
QFS_Init ("qw");
PI_Init (); PI_Init ();
CL_Cam_Init_Cvars (); CL_Cam_Init_Cvars ();
@ -1719,7 +1720,6 @@ Host_Init (void)
CL_Prediction_Init_Cvars (); CL_Prediction_Init_Cvars ();
COM_Init_Cvars (); COM_Init_Cvars ();
Con_Init_Cvars (); Con_Init_Cvars ();
COM_Filesystem_Init_Cvars ();
Game_Init_Cvars (); Game_Init_Cvars ();
IN_Init_Cvars (); IN_Init_Cvars ();
Key_Init_Cvars (); Key_Init_Cvars ();
@ -1739,7 +1739,6 @@ Host_Init (void)
CL_Cmd_Init (); CL_Cmd_Init ();
V_Init (); V_Init ();
COM_Filesystem_Init ();
Game_Init (); Game_Init ();
COM_Init (); COM_Init ();

View file

@ -488,12 +488,13 @@ CL_ParseDownload (void)
} }
// open the file if not opened yet // open the file if not opened yet
if (!cls.download) { if (!cls.download) {
if (strncmp (cls.downloadtempname, "skins/", 6)) //XXX QFS
//if (strncmp (cls.downloadtempname, "skins/", 6))
snprintf (name, sizeof (name), "%s/%s", com_gamedir, snprintf (name, sizeof (name), "%s/%s", com_gamedir,
cls.downloadtempname); cls.downloadtempname);
else //else
snprintf (name, sizeof (name), "%s/%s/%s", fs_userpath->string, // snprintf (name, sizeof (name), "%s/%s/%s", fs_userpath->string,
fs_skinbase->string, cls.downloadtempname); // fs_skinbase->string, cls.downloadtempname);
COM_CreatePath (name); COM_CreatePath (name);
@ -529,17 +530,18 @@ CL_ParseDownload (void)
// rename the temp file to it's final name // rename the temp file to it's final name
if (strcmp (cls.downloadtempname, cls.downloadname)) { if (strcmp (cls.downloadtempname, cls.downloadname)) {
if (strncmp (cls.downloadtempname, "skins/", 6)) { //XXX QFS
//if (strncmp (cls.downloadtempname, "skins/", 6)) {
snprintf (oldn, sizeof (oldn), "%s/%s", com_gamedir, snprintf (oldn, sizeof (oldn), "%s/%s", com_gamedir,
cls.downloadtempname); cls.downloadtempname);
snprintf (newn, sizeof (newn), "%s/%s", com_gamedir, snprintf (newn, sizeof (newn), "%s/%s", com_gamedir,
cls.downloadname); cls.downloadname);
} else { //} else {
snprintf (oldn, sizeof (oldn), "%s/%s/%s", fs_userpath->string, // snprintf (oldn, sizeof (oldn), "%s/%s/%s", fs_userpath->string,
fs_skinbase->string, cls.downloadtempname); // fs_skinbase->string, cls.downloadtempname);
snprintf (newn, sizeof (newn), "%s/%s/%s", fs_userpath->string, // snprintf (newn, sizeof (newn), "%s/%s/%s", fs_userpath->string,
fs_skinbase->string, cls.downloadname); // fs_skinbase->string, cls.downloadname);
} //}
r = Qrename (oldn, newn); r = Qrename (oldn, newn);
if (r) if (r)
Con_Printf ("failed to rename, %s.\n", strerror (errno)); Con_Printf ("failed to rename, %s.\n", strerror (errno));

View file

@ -96,6 +96,4 @@ Game_Init (void)
void void
Game_Init_Cvars (void) Game_Init_Cvars (void)
{ {
fs_skinbase = Cvar_Get ("fs_skinbase", "qw", CVAR_ROM, NULL,
"location of skins dir for downloads");
} }

View file

@ -2452,8 +2452,6 @@ void
SV_Init (void) SV_Init (void)
{ {
COM_InitArgv (host_parms.argc, (const char**)host_parms.argv); COM_InitArgv (host_parms.argc, (const char**)host_parms.argv);
// COM_AddParm ("-game");
// COM_AddParm ("qw");
sv_cbuf = Cbuf_New (&id_interp); sv_cbuf = Cbuf_New (&id_interp);
sv_args = Cbuf_ArgsNew (); sv_args = Cbuf_ArgsNew ();
@ -2505,6 +2503,7 @@ SV_Init (void)
localinfo = Info_ParseString ("", 0); // unlimited localinfo = Info_ParseString ("", 0); // unlimited
SV_InitOperatorCommands (); SV_InitOperatorCommands ();
QFS_Init ("qw");
PI_Init (); PI_Init ();
sv_console_plugin = Cvar_Get ("sv_console_plugin", "server", sv_console_plugin = Cvar_Get ("sv_console_plugin", "server",
@ -2517,7 +2516,6 @@ SV_Init (void)
Sys_SetStdPrintf (SV_Print); Sys_SetStdPrintf (SV_Print);
Sys_SetErrPrintf (SV_Error); Sys_SetErrPrintf (SV_Error);
COM_Filesystem_Init_Cvars ();
Game_Init_Cvars (); Game_Init_Cvars ();
COM_Init_Cvars (); COM_Init_Cvars ();
Mod_Init_Cvars (); Mod_Init_Cvars ();
@ -2530,7 +2528,6 @@ SV_Init (void)
Cmd_StuffCmds (sv_cbuf); Cmd_StuffCmds (sv_cbuf);
Cbuf_Execute_Sets (sv_cbuf); Cbuf_Execute_Sets (sv_cbuf);
COM_Filesystem_Init ();
Game_Init (); Game_Init ();
COM_Init (); COM_Init ();

View file

@ -40,6 +40,7 @@ static const char rcsid[] =
#include "QF/cmd.h" #include "QF/cmd.h"
#include "QF/csqc.h" //FIXME d'oh, dumb name after all #include "QF/csqc.h" //FIXME d'oh, dumb name after all
#include "QF/cvar.h" #include "QF/cvar.h"
#include "QF/quakefs.h"
#include "QF/sys.h" #include "QF/sys.h"
#include "compat.h" #include "compat.h"
@ -169,11 +170,17 @@ SV_LoadProgs (void)
{ {
ddef_t *def; ddef_t *def;
dfunction_t *f; dfunction_t *f;
const char *progs_name = "qwprogs.dat";
PR_LoadProgs (&sv_pr_state, sv_progs->string, MAX_EDICTS, if (qfs_gamedir->gamecode && *qfs_gamedir->gamecode)
progs_name = qfs_gamedir->gamecode;
if (*sv_progs->string)
progs_name = sv_progs->string;
PR_LoadProgs (&sv_pr_state, progs_name, MAX_EDICTS,
sv_progs_zone->int_val * 1024); sv_progs_zone->int_val * 1024);
if (!sv_pr_state.progs || !PR_RelocateBuiltins (&sv_pr_state)) if (!sv_pr_state.progs || !PR_RelocateBuiltins (&sv_pr_state))
Sys_Error ("SV_LoadProgs: couldn't load %s", sv_progs->string); Sys_Error ("SV_LoadProgs: couldn't load %s", progs_name);
// progs engine needs these globals anyway // progs engine needs these globals anyway
sv_globals.self = sv_pr_state.globals.self; sv_globals.self = sv_pr_state.globals.self;
sv_globals.time = sv_pr_state.globals.time; sv_globals.time = sv_pr_state.globals.time;
@ -377,9 +384,8 @@ SV_Progs_Init_Cvars (void)
{ {
r_skyname = Cvar_Get ("r_skyname", "", CVAR_SERVERINFO, Cvar_Info, r_skyname = Cvar_Get ("r_skyname", "", CVAR_SERVERINFO, Cvar_Info,
"name of skybox"); "name of skybox");
sv_progs = Cvar_Get ("sv_progs", "qwprogs.dat", CVAR_NONE, NULL, sv_progs = Cvar_Get ("sv_progs", "", CVAR_NONE, NULL,
"Allows selectable game progs if you have several " "Override the default game progs.");
"of them in the gamedir");
sv_progs_zone = Cvar_Get ("sv_progs_zone", "256", CVAR_NONE, NULL, sv_progs_zone = Cvar_Get ("sv_progs_zone", "256", CVAR_NONE, NULL,
"size of the zone for progs in kb"); "size of the zone for progs in kb");
pr_checkextensions = Cvar_Get ("pr_checkextensions", "1", CVAR_ROM, NULL, pr_checkextensions = Cvar_Get ("pr_checkextensions", "1", CVAR_ROM, NULL,