Implement getgamedirinfo builtin.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5366 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2018-12-11 00:12:47 +00:00
parent 4d6bd82a2f
commit 0884126e56
1 changed files with 110 additions and 8 deletions

View File

@ -399,11 +399,23 @@ void QCBUILTIN PF_cl_findkeysforcommandex (pubprogfuncs_t *prinst, struct global
void QCBUILTIN PF_cl_getkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int keymap = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0;
int bindmap = (prinst->callargc > 1)?G_FLOAT(OFS_PARM1):0;
int modifier = (prinst->callargc > 2)?G_FLOAT(OFS_PARM2):0;
char *binding = Key_GetBinding(MP_TranslateQCtoFTECodes(G_FLOAT(OFS_PARM0)), keymap, modifier);
char *binding = Key_GetBinding(MP_TranslateQCtoFTECodes(G_FLOAT(OFS_PARM0)), bindmap, modifier);
RETURN_TSTRING(binding);
}
void QCBUILTIN PF_cl_setkeybind (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int keynum = MP_TranslateQCtoFTECodes(G_FLOAT(OFS_PARM0));
const char *binding = PR_GetStringOfs(prinst, OFS_PARM1);
int bindmap = (prinst->callargc > 2)?G_FLOAT(OFS_PARM2):0;
int modifier = (prinst->callargc > 3)?G_FLOAT(OFS_PARM3):~0;
if (bindmap > 0 && bindmap <= KEY_MODIFIER_ALTBINDMAP)
modifier = (bindmap-1) | KEY_MODIFIER_ALTBINDMAP; //ignore the modifier if we're setting into a bindmap...
Key_SetBinding(keynum, modifier, binding, RESTRICT_INSECURE);
}
void QCBUILTIN PF_cl_stringtokeynum(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -965,14 +977,104 @@ void QCBUILTIN PF_cl_localsound(pubprogfuncs_t *prinst, struct globalvars_s *pr_
S_LocalSound2(s, chan, vol);
}
void QCBUILTIN PF_cl_getgamedirinfo(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{ //IMPLEMENTME
// int diridx = G_FLOAT(OFS_PARM0);
// int propidx = G_FLOAT(OFS_PARM1);
//propidx 0 == name
//propidx 1 == description (contents of modinfo.txt)
#include "fs.h"
static struct modlist_s
{
ftemanifest_t *manifest;
char *gamedir;
char *description;
} *modlist;
static size_t nummods;
static qboolean modsinited;
static qboolean Mods_AddManifest(void *usr, ftemanifest_t *man)
{
int i = nummods;
modlist = BZ_Realloc(modlist, (i+1) * sizeof(*modlist));
modlist[i].manifest = man;
modlist[i].gamedir = man->updatefile;
modlist[i].description = man->formalname;
nummods = i+1;
return true;
}
static int QDECL Mods_AddGamedir(const char *fname, qofs_t fsize, time_t mtime, void *usr, searchpathfuncs_t *spath)
{
char *f;
size_t l = strlen(fname);
int i, p;
char gamedir[MAX_QPATH];
if (l && fname[l-1] == '/' && l < countof(gamedir))
{
l--;
memcpy(gamedir, fname, l);
gamedir[l] = 0;
for (i = 0; i < nummods; i++)
{
//don't add dupes (can happen from basedir+homedir)
//if the gamedir was already included in one of the manifests, don't bother including it again.
//this generally removes id1.
if (modlist[i].manifest)
{
for (p = 0; p < countof(fs_manifest->gamepath); p++)
if (modlist[i].manifest->gamepath[p].path)
if (!Q_strcasecmp(modlist[i].manifest->gamepath[p].path, gamedir))
return true;
}
else if (modlist[i].gamedir)
{
if (!Q_strcasecmp(modlist[i].gamedir, gamedir))
return true;
}
}
f = FS_MallocFile(va("%s%s/modinfo.txt", usr, gamedir), FS_SYSTEM, NULL);
if (f)
{
modlist = BZ_Realloc(modlist, (i+1) * sizeof(*modlist));
modlist[i].manifest = NULL;
modlist[i].gamedir = Z_StrDup(gamedir);
modlist[i].description = f;
nummods = i+1;
}
}
return true;
}
static void Mods_InitModList (void)
{
extern qboolean com_homepathenabled;
FS_EnumerateKnownGames(Mods_AddManifest, NULL);
if (com_homepathenabled)
Sys_EnumerateFiles(com_homepath, "*", Mods_AddGamedir, com_homepath, NULL);
Sys_EnumerateFiles(com_gamepath, "*", Mods_AddGamedir, com_gamepath, NULL);
}
void QCBUILTIN PF_cl_getgamedirinfo(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
size_t diridx = G_FLOAT(OFS_PARM0);
int propidx = G_FLOAT(OFS_PARM1);
if (!modsinited)
{
modsinited = true;
Mods_InitModList();
}
G_INT(OFS_RETURN) = 0;
if (diridx < nummods)
{
switch(propidx)
{
case 1: //description (contents of modinfo.txt)
if (modlist[diridx].description)
RETURN_TSTRING(modlist[diridx].description);
//fallthrough
case 0: //name
RETURN_TSTRING(modlist[diridx].gamedir);
break;
}
}
}
//This is consistent with vanilla quakeworld's 'packet' console command.