mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-22 12:01:25 +00:00
fix typo with menus.
fix a couple of obscure bugs. rework qw/q2 skins. qwskin command now exists in .skin support. add support for mod_external_vis, to load vis patches. made the included http server a little more verbose with peer addresses. preliminary support for using accessors in fteextensions.qc, will wait a while until fteqcc's support is robust before its enabled by default. preliminary webgl drag+drop. still lots of work to do before giving it a pak1.pak is trivial. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4748 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
0fb5e2bc25
commit
b328df6936
40 changed files with 956 additions and 475 deletions
|
@ -1802,7 +1802,7 @@ void CL_QTVPoll (void)
|
|||
int len;
|
||||
qboolean streamavailable = false;
|
||||
qboolean saidheader = false;
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
menu_t *sourcesmenu = NULL;
|
||||
#endif
|
||||
int sourcenum = 0;
|
||||
|
@ -1971,7 +1971,7 @@ void CL_QTVPoll (void)
|
|||
{
|
||||
streamid = atoi(colon);
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
//now put it on a menu
|
||||
if (!sourcesmenu)
|
||||
{
|
||||
|
|
|
@ -3908,6 +3908,8 @@ void Host_BeginFileDownload(struct dl_download *dl, char *mimetype)
|
|||
f->flags |= HRF_QTVINFO;
|
||||
else if (!strcmp(mimetype, "text/x-quaketvident"))
|
||||
f->flags |= HRF_QTVINFO;
|
||||
else if (!strcmp(mimetype, "application/x-fteplugin"))
|
||||
f->flags |= HRF_MANIFEST;
|
||||
else if (!strcmp(mimetype, "application/x-ftemanifest"))
|
||||
f->flags |= HRF_MANIFEST;
|
||||
else if (!strcmp(mimetype, "application/x-multiviewdemo"))
|
||||
|
@ -3916,6 +3918,9 @@ void Host_BeginFileDownload(struct dl_download *dl, char *mimetype)
|
|||
// f->flags |= HRF_BSP;
|
||||
// else if (!strcmp(mimetype, "application/x-ftepackage"))
|
||||
// f->flags |= HRF_PACKAGE;
|
||||
|
||||
if (f->flags & HRF_MANIFEST)
|
||||
waitingformanifest++;
|
||||
}
|
||||
|
||||
if (!(f->flags & HRF_FILETYPES))
|
||||
|
@ -4001,7 +4006,7 @@ static qboolean isurl(char *url)
|
|||
#ifdef FTE_TARGET_WEB
|
||||
return true; //assume EVERYTHING is a url, because the local filesystem is pointless.
|
||||
#endif
|
||||
return !strncmp(url, "http://", 7) || !strncmp(url, "https://", 8);
|
||||
return /*!strncmp(url, "data:", 5) || */!strncmp(url, "http://", 7) || !strncmp(url, "https://", 8);
|
||||
}
|
||||
|
||||
void Host_DoRunFile(hrf_t *f)
|
||||
|
@ -4041,13 +4046,17 @@ void Host_DoRunFile(hrf_t *f)
|
|||
if (!(f->flags & HRF_OPENED))
|
||||
{
|
||||
struct dl_download *dl;
|
||||
f->flags |= HRF_OPENED|HRF_DOWNLOADED|HRF_WAITING;
|
||||
f->flags |= HRF_OPENED;
|
||||
dl = HTTP_CL_Get(f->fname, NULL, Host_RunFileDownloaded);
|
||||
dl->notifystarted = Host_BeginFileDownload;
|
||||
dl->user_ctx = f;
|
||||
if (dl)
|
||||
{
|
||||
f->flags |= HRF_WAITING|HRF_DOWNLOADED;
|
||||
dl->notifystarted = Host_BeginFileDownload;
|
||||
dl->user_ctx = f;
|
||||
|
||||
waitingformanifest++;
|
||||
return;
|
||||
waitingformanifest++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -4169,9 +4178,12 @@ void Host_DoRunFile(hrf_t *f)
|
|||
if (isurl(f->fname))
|
||||
{
|
||||
struct dl_download *dl = HTTP_CL_Get(f->fname, NULL, Host_RunFileDownloaded);
|
||||
dl->notifystarted = Host_BeginFileDownload;
|
||||
dl->user_ctx = f;
|
||||
return;
|
||||
if (dl)
|
||||
{
|
||||
dl->notifystarted = Host_BeginFileDownload;
|
||||
dl->user_ctx = f;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
f->srcfile = VFSOS_Open(f->fname, "rb"); //input file is a system path, or something.
|
||||
|
@ -4733,7 +4745,7 @@ void CL_StartCinematicOrMenu(void)
|
|||
{
|
||||
if (qrenderer > QR_NONE && !m_state)
|
||||
{
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
if (!cls.state && !m_state && !*FS_GetGamedir(false))
|
||||
M_Menu_Mods_f();
|
||||
#endif
|
||||
|
|
|
@ -4341,7 +4341,7 @@ CL_NewTranslation
|
|||
void CL_NewTranslation (int slot)
|
||||
{
|
||||
int top, bottom;
|
||||
int local;
|
||||
int local;
|
||||
|
||||
char *s;
|
||||
player_info_t *player;
|
||||
|
@ -4351,10 +4351,33 @@ void CL_NewTranslation (int slot)
|
|||
|
||||
player = &cl.players[slot];
|
||||
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
char *mod, *skin;
|
||||
player->qwskin = NULL;
|
||||
player->skinid = 0;
|
||||
player->model = NULL;
|
||||
player->ttopcolor = TOP_DEFAULT;
|
||||
player->tbottomcolor = BOTTOM_DEFAULT;
|
||||
|
||||
mod = Info_ValueForKey(player->userinfo, "skin");
|
||||
skin = strchr(mod, '/');
|
||||
if (skin)
|
||||
*skin++ = 0;
|
||||
|
||||
player->model = Mod_ForName(va("players/%s/tris.md2", mod), 0);
|
||||
player->skinid = Mod_RegisterSkinFile(va("players/%s/%s.skin", mod,skin));
|
||||
if (!player->skinid)
|
||||
player->skinid = Mod_ReadSkinFile(va("players/%s/%s.skin", mod,skin), va("replace \"\" \"players/%s/%s.pcx\"", mod,skin));
|
||||
return;
|
||||
}
|
||||
|
||||
s = Skin_FindName (player);
|
||||
COM_StripExtension(s, s, MAX_QPATH);
|
||||
if (player->skin && !stricmp(s, player->skin->name))
|
||||
player->skin = NULL;
|
||||
if (player->qwskin && !stricmp(s, player->qwskin->name))
|
||||
player->qwskin = NULL;
|
||||
player->skinid = 0;
|
||||
player->model = NULL;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ void SCR_ScreenShot_f (void);
|
|||
void SCR_RSShot_f (void);
|
||||
void SCR_CPrint_f(void);
|
||||
|
||||
cvar_t con_stayhidden = CVARFD("con_stayhidden", "1", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
|
||||
cvar_t con_stayhidden = CVARFD("con_stayhidden", "0", CVAR_NOTFROMSERVER, "0: allow console to pounce on the user\n1: console stays hidden unless explicitly invoked\n2:toggleconsole command no longer works\n3: shift+escape key no longer works");
|
||||
cvar_t show_fps = SCVARF("show_fps", "0", CVAR_ARCHIVE);
|
||||
cvar_t show_fps_x = SCVAR("show_fps_x", "-1");
|
||||
cvar_t show_fps_y = SCVAR("show_fps_y", "-1");
|
||||
|
|
|
@ -21,7 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
#include "particles.h"
|
||||
|
||||
typedef struct
|
||||
typedef struct qwskin_s
|
||||
{
|
||||
char name[64];
|
||||
int width;
|
||||
|
@ -32,7 +32,7 @@ typedef struct
|
|||
|
||||
qboolean failedload; // the name isn't a valid skin
|
||||
void *skindata;
|
||||
} skin_t;
|
||||
} qwskin_t;
|
||||
|
||||
// player_state_t is the information needed by a player entity
|
||||
// to do move prediction and to generate a drawable entity
|
||||
|
@ -168,8 +168,9 @@ typedef struct player_info_s
|
|||
unsigned int ttopcolor; //team, according to colour forcing
|
||||
unsigned int tbottomcolor;
|
||||
|
||||
int spectator;
|
||||
skin_t *skin;
|
||||
int spectator;
|
||||
qwskin_t *qwskin;
|
||||
skinid_t skinid;
|
||||
|
||||
struct model_s *model;
|
||||
|
||||
|
@ -1314,10 +1315,10 @@ typedef struct
|
|||
qbyte *ReadPCXData(qbyte *buf, int length, int width, int height, qbyte *result);
|
||||
|
||||
|
||||
qwskin_t *Skin_Lookup (char *fullname);
|
||||
char *Skin_FindName (player_info_t *sc);
|
||||
void Skin_Find (player_info_t *sc);
|
||||
qbyte *Skin_Cache8 (skin_t *skin);
|
||||
qbyte *Skin_Cache32 (skin_t *skin);
|
||||
qbyte *Skin_Cache8 (qwskin_t *skin);
|
||||
void Skin_Skins_f (void);
|
||||
void Skin_FlushSkin(char *name);
|
||||
void Skin_AllSkins_f (void);
|
||||
|
|
|
@ -1228,6 +1228,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
ent.bottomcolour = 1;
|
||||
ent.h2playerclass = 0;
|
||||
ent.playerindex = -1;
|
||||
ent.customskin = 0;
|
||||
|
||||
// set frame
|
||||
if (effects & Q2EF_ANIM01)
|
||||
|
@ -1315,11 +1316,14 @@ void CLQ2_AddPacketEntities (q2frame_t *frame)
|
|||
ent.model = player->model;
|
||||
if (!ent.model || ent.model->needload) //we need to do better than this
|
||||
{
|
||||
if (!ent.model || ent.model->needload)
|
||||
ent.model = Mod_ForName("players/male/tris.md2", MLV_SILENT);
|
||||
ent.model = Mod_ForName("players/male/tris.md2", MLV_SILENT);
|
||||
ent.customskin = Mod_RegisterSkinFile("players/male/grunt.skin");
|
||||
if (!ent.customskin)
|
||||
ent.customskin = Mod_ReadSkinFile("players/male/grunt.skin", "replace \"\" \"players/male/grunt.pcx\"");
|
||||
}
|
||||
else
|
||||
ent.customskin = player->skinid;
|
||||
ent.playerindex = (s1->skinnum&0xff)%cl.allocated_client_slots;
|
||||
player->model = ent.model;
|
||||
/* ci = &cl.clientinfo[s1->skinnum & 0xff];
|
||||
// ent.skin = ci->skin;
|
||||
ent.model = ci->model;
|
||||
|
@ -1813,6 +1817,8 @@ void CLQ2_AddViewWeapon (q2player_state_t *ps, q2player_state_t *ops)
|
|||
else
|
||||
gun.framestate.g[FS_REG].frame[1] = ops->gunframe;
|
||||
|
||||
gun.playerindex = -1;
|
||||
|
||||
gun.flags = Q2RF_MINLIGHT | RF_DEPTHHACK | RF_WEAPONMODEL;
|
||||
gun.framestate.g[FS_REG].lerpfrac = 1-cl.lerpfrac;
|
||||
VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all
|
||||
|
@ -1926,6 +1932,7 @@ Emits all entities, particles, and lights to the refresh
|
|||
*/
|
||||
void CLQ2_AddEntities (void)
|
||||
{
|
||||
extern cvar_t chase_active, chase_back, chase_up;
|
||||
if (cls.state != ca_active)
|
||||
return;
|
||||
|
||||
|
@ -1952,6 +1959,22 @@ void CLQ2_AddEntities (void)
|
|||
CLQ2_AddProjectiles ();
|
||||
#endif
|
||||
CL_UpdateTEnts ();
|
||||
|
||||
|
||||
if (chase_active.ival)
|
||||
{
|
||||
playerview_t *pv = &cl.playerview[0];
|
||||
vec3_t axis[3];
|
||||
vec3_t camorg;
|
||||
trace_t tr;
|
||||
AngleVectors(r_refdef.viewangles, axis[0], axis[1], axis[2]);
|
||||
VectorMA(r_refdef.vieworg, -chase_back.value, axis[0], camorg);
|
||||
VectorMA(camorg, -chase_up.value, pv->gravitydir, camorg);
|
||||
// if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, r_refdef.vieworg, camorg, vec3_origin, vec3_origin, MASK_WORLDSOLID, &tr))
|
||||
VectorCopy(camorg, r_refdef.vieworg);
|
||||
|
||||
CL_EditExternalModels(0, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void CL_GetNumberedEntityInfo (int num, float *org, float *ang)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#if defined(WEBCLIENT) && !defined(NOBUITINMENUS)
|
||||
#if defined(WEBCLIENT) && !defined(NOBUILTINMENUS)
|
||||
#define DOWNLOADMENU
|
||||
#endif
|
||||
|
||||
|
|
|
@ -76,7 +76,7 @@ void Draw_TextBox (int x, int y, int width, int lines)
|
|||
R2D_ScalePic (cx, cy+8, 8, 8, p);
|
||||
}
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
|
||||
int omousex;
|
||||
int omousey;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "quakedef.h"
|
||||
|
||||
#if defined(CL_MASTER) && !defined(NOBUITINMENUS)
|
||||
#if defined(CL_MASTER) && !defined(NOBUILTINMENUS)
|
||||
#include "cl_master.h"
|
||||
|
||||
//filtering
|
||||
|
|
|
@ -743,7 +743,7 @@ void M_Media_Key (int key)
|
|||
int dir;
|
||||
if (key == K_ESCAPE)
|
||||
{
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
M_Menu_Main_f();
|
||||
#else
|
||||
m_state = m_none;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include "winquake.h"
|
||||
#include "shader.h"
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
|
||||
extern cvar_t maxclients;
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ qboolean M_Vid_GetMode(int num, int *w, int *h)
|
|||
|
||||
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
|
||||
extern qboolean forcesaveprompt;
|
||||
extern cvar_t pr_debugger;
|
||||
|
@ -712,6 +712,7 @@ const char *presetexec[] =
|
|||
"gl_texturemode2d n;" //yeah, 2d too.
|
||||
"r_part_classic_square 1;" //blocky baby!
|
||||
"r_part_classic_expgrav 1;" //vanillaery
|
||||
"r_particlesystem script;" //q2 or hexen2 particle effects need to be loadable
|
||||
"cl_sbar 1;" //its a style thing
|
||||
"sv_nqplayerphysics 1;" //gb wanted this
|
||||
"cl_demoreel 1;" //yup, arcadey
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include "quakedef.h"
|
||||
#include "shader.h"
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
|
||||
int selectitem;
|
||||
menu_t *menu_script;
|
||||
|
|
|
@ -154,7 +154,7 @@ void M_FindKeysForCommand (int pnum, const char *command, int *twokeys)
|
|||
M_FindKeysForBind(va("%s%s", prefix, command), twokeys, 2);
|
||||
}
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
|
||||
void M_Menu_Audio_f (void);
|
||||
void M_Menu_Demos_f (void);
|
||||
|
@ -1270,7 +1270,7 @@ void M_Draw (int uimenu)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
if (m_state != m_complex)
|
||||
{
|
||||
M_RemoveAllMenus();
|
||||
|
@ -1286,7 +1286,7 @@ void M_Draw (int uimenu)
|
|||
if (m_state == m_none || m_state == m_menu_dat)
|
||||
return;
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
if ((!menu_script || scr_con_current) && !m_recursiveDraw)
|
||||
{
|
||||
extern menu_t *firstmenu;
|
||||
|
@ -1308,7 +1308,7 @@ void M_Draw (int uimenu)
|
|||
case m_none:
|
||||
break;
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
case m_help:
|
||||
M_Help_Draw ();
|
||||
break;
|
||||
|
@ -1345,7 +1345,7 @@ void M_Keydown (int key, int unicode)
|
|||
case m_none:
|
||||
Key_Dest_Remove(kdm_menu);
|
||||
return;
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
case m_help:
|
||||
M_Help_Key (key);
|
||||
return;
|
||||
|
@ -1380,7 +1380,7 @@ void M_Keyup (int key, int unicode)
|
|||
{
|
||||
switch (m_state)
|
||||
{
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
case m_complex:
|
||||
if (key == K_MOUSE1)
|
||||
M_Complex_Key (key, unicode);
|
||||
|
|
|
@ -102,7 +102,7 @@ void M_DrawTextBox (int x, int y, int width, int lines);
|
|||
|
||||
#define NOMEDIAMENU
|
||||
|
||||
#ifndef NOBUITINMENUS
|
||||
#ifndef NOBUILTINMENUS
|
||||
|
||||
//
|
||||
// menus
|
||||
|
|
|
@ -148,6 +148,8 @@ typedef struct
|
|||
int nummappings;
|
||||
int maxmappings;
|
||||
qbyte geomset[MAX_GEOMSETS]; //allows selecting a single set of geometry from alternatives. this might be a can of worms.
|
||||
char qwskinname[MAX_QPATH];
|
||||
struct qwskin_s *qwskin;
|
||||
struct
|
||||
{
|
||||
char surface[MAX_QPATH];
|
||||
|
@ -266,7 +268,7 @@ extern entity_t r_worldentity;
|
|||
void BE_GenModelBatches(struct batch_s **batches, const struct dlight_s *dl, unsigned int bemode); //if dl, filters based upon the dlight.
|
||||
|
||||
//gl_alias.c
|
||||
void GL_GAliasFlushSkinCache(void);
|
||||
void R_GAliasFlushSkinCache(qboolean final);
|
||||
void R_GAlias_DrawBatch(struct batch_s *batch);
|
||||
void R_GAlias_GenerateBatches(entity_t *e, struct batch_s **batches);
|
||||
void R_LightArraysByte_BGR(const entity_t *entity, vecV_t *coords, byte_vec4_t *colours, int vertcount, vec3_t *normals);
|
||||
|
|
|
@ -411,7 +411,7 @@ void Sbar_ExecuteLayoutString (char *s)
|
|||
Draw_FunString (x+32, y+16, va("Ping: %i", ping));
|
||||
Draw_FunString (x+32, y+24, va("Time: %i", time));
|
||||
|
||||
p = R2D_SafeCachePic(va("players/%s_i.pcx", cl.players[value].skin->name));
|
||||
p = R2D_SafeCachePic(va("players/%s_i.pcx", cl.players[value].qwskin->name));
|
||||
if (!p) //display a default if the icon couldn't be found.
|
||||
p = R2D_SafeCachePic("players/male/grunt_i.pcx");
|
||||
R2D_ScalePic (x, y, 32, 32, p);
|
||||
|
|
|
@ -30,8 +30,8 @@ extern cvar_t cl_enemyskin;
|
|||
extern cvar_t r_fb_models;
|
||||
|
||||
char allskins[128];
|
||||
#define MAX_CACHED_SKINS 128
|
||||
skin_t skins[MAX_CACHED_SKINS];
|
||||
#define MAX_CACHED_SKINS 256 //max_clients is 255. hopefully this will not be reached, but hey.
|
||||
qwskin_t skins[MAX_CACHED_SKINS];
|
||||
int numskins;
|
||||
|
||||
//returns the name
|
||||
|
@ -108,6 +108,37 @@ char *Skin_FindName (player_info_t *sc)
|
|||
return name;
|
||||
}
|
||||
|
||||
qwskin_t *Skin_Lookup (char *fullname)
|
||||
{
|
||||
int i;
|
||||
qwskin_t *skin;
|
||||
char cleanname[sizeof(skin->name)];
|
||||
COM_StripExtension (fullname, cleanname, sizeof(cleanname));
|
||||
|
||||
for (i=0 ; i<numskins ; i++)
|
||||
{
|
||||
if (!strcmp (cleanname, skins[i].name))
|
||||
{
|
||||
skin = &skins[i];
|
||||
Skin_Cache8 (skin);
|
||||
return skin;
|
||||
}
|
||||
}
|
||||
|
||||
//FIXME: this is stupid.
|
||||
if (numskins == MAX_CACHED_SKINS)
|
||||
{ // ran out of spots, so flush everything
|
||||
Skin_Skins_f ();
|
||||
}
|
||||
|
||||
skin = &skins[numskins];
|
||||
numskins++;
|
||||
|
||||
memset (skin, 0, sizeof(*skin));
|
||||
Q_strncpyz(skin->name, cleanname, sizeof(skin->name));
|
||||
Skin_Cache8 (skin);
|
||||
return skin;
|
||||
}
|
||||
/*
|
||||
================
|
||||
Skin_Find
|
||||
|
@ -119,52 +150,35 @@ Skin_Find
|
|||
*/
|
||||
void Skin_Find (player_info_t *sc)
|
||||
{
|
||||
skin_t *skin;
|
||||
qwskin_t *skin;
|
||||
int i;
|
||||
char name[128], *s;
|
||||
model_t *model;
|
||||
|
||||
if (allskins[0])
|
||||
s = allskins;
|
||||
else
|
||||
s = Info_ValueForKey (sc->userinfo, "skin");
|
||||
|
||||
sc->model = NULL;
|
||||
sc->skinid = 0;
|
||||
sc->qwskin = NULL;
|
||||
|
||||
if (!*s)
|
||||
s = baseskin.string;
|
||||
if (!*s)
|
||||
s = "default";
|
||||
return;
|
||||
// s = "default";
|
||||
|
||||
s = Skin_FindName(sc);
|
||||
COM_StripExtension (s, name, sizeof(name));
|
||||
|
||||
s = strchr(name, '/');
|
||||
if (s)
|
||||
{
|
||||
*s = '\0';
|
||||
#ifdef Q2CLIENT
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
model = Mod_ForName(va("players/%s/tris.md2", name), MLV_SILENT);
|
||||
else
|
||||
#endif
|
||||
model = NULL;//Mod_ForName(va("models/players/%s.mdl", name), false);
|
||||
if (model && model->type == mod_dummy)
|
||||
model = NULL;
|
||||
*s = '/';
|
||||
}
|
||||
else
|
||||
model = NULL;
|
||||
|
||||
sc->model = model;
|
||||
|
||||
for (i=0 ; i<numskins ; i++)
|
||||
{
|
||||
if (!strcmp (name, skins[i].name))
|
||||
{
|
||||
sc->skin = &skins[i];
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
Skin_Cache32 (sc->skin);
|
||||
else
|
||||
Skin_Cache8 (sc->skin);
|
||||
sc->qwskin = &skins[i];
|
||||
Skin_Cache8 (sc->qwskin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +190,7 @@ void Skin_Find (player_info_t *sc)
|
|||
}
|
||||
|
||||
skin = &skins[numskins];
|
||||
sc->skin = skin;
|
||||
sc->qwskin = skin;
|
||||
numskins++;
|
||||
|
||||
memset (skin, 0, sizeof(*skin));
|
||||
|
@ -191,7 +205,7 @@ Skin_Cache
|
|||
Returns a pointer to the skin bitmap, or NULL to use the default
|
||||
==========
|
||||
*/
|
||||
qbyte *Skin_Cache8 (skin_t *skin)
|
||||
qbyte *Skin_Cache8 (qwskin_t *skin)
|
||||
{
|
||||
char name[1024];
|
||||
qbyte *raw;
|
||||
|
@ -251,12 +265,7 @@ qbyte *Skin_Cache8 (skin_t *skin)
|
|||
return out;
|
||||
}
|
||||
|
||||
#ifdef Q2CLIENT
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
skinpath = "players";
|
||||
else
|
||||
#endif
|
||||
skinpath = "skins";
|
||||
skinpath = "skins";
|
||||
|
||||
//favour 24bit+recoloured skins if gl_load24bit is enabled.
|
||||
Q_snprintfz (name, sizeof(name), "%s_shirt", skin->name);
|
||||
|
@ -431,106 +440,6 @@ qbyte *Skin_Cache8 (skin_t *skin)
|
|||
return out;
|
||||
}
|
||||
|
||||
qbyte *Skin_Cache32 (skin_t *skin)
|
||||
{
|
||||
char name[1024];
|
||||
qbyte *raw;
|
||||
qbyte *out, *pix;
|
||||
char *path;
|
||||
qboolean hasalpha;
|
||||
|
||||
if (noskins.value==1) // JACK: So NOSKINS > 1 will show skins, but
|
||||
return NULL; // not download new ones.
|
||||
|
||||
if (skin->failedload)
|
||||
return NULL;
|
||||
|
||||
out = skin->skindata;
|
||||
if (out)
|
||||
return out;
|
||||
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
path = "players/";
|
||||
else
|
||||
path = "skins/";
|
||||
|
||||
//
|
||||
// load the pic from disk
|
||||
//
|
||||
Q_snprintfz (name, sizeof(name), "%s%s.tga", path, skin->name);
|
||||
raw = COM_LoadTempFile (name);
|
||||
if (raw)
|
||||
{
|
||||
pix = ReadTargaFile(raw, com_filesize, &skin->width, &skin->height, &hasalpha, false);
|
||||
if (pix)
|
||||
{
|
||||
skin->skindata = out = BZ_Malloc(skin->width*skin->height*4);
|
||||
memcpy(out, pix, skin->width*skin->height*4);
|
||||
BZ_Free(pix);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
Q_snprintfz (name, sizeof(name), "%s%s.pcx", path, skin->name);
|
||||
raw = COM_LoadTempFile (name);
|
||||
if (raw)
|
||||
{
|
||||
pix = ReadPCXFile(raw, com_filesize, &skin->width, &skin->height);
|
||||
if (pix)
|
||||
{
|
||||
skin->skindata = out = BZ_Malloc(skin->width*skin->height*4);
|
||||
memcpy(out, pix, skin->width*skin->height*4);
|
||||
BZ_Free(pix);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
#ifdef AVAIL_PNGLIB
|
||||
Q_snprintfz (name, sizeof(name), "%s%s.png", path, skin->name);
|
||||
raw = COM_LoadTempFile (name);
|
||||
if (raw)
|
||||
{
|
||||
pix = ReadPNGFile(raw, com_filesize, &skin->width, &skin->height, name);
|
||||
if (pix)
|
||||
{
|
||||
skin->skindata = out = BZ_Malloc(skin->width*skin->height*4);
|
||||
memcpy(out, pix, skin->width*skin->height*4);
|
||||
BZ_Free(pix);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef AVAIL_JPEGLIB
|
||||
Q_snprintfz (name, sizeof(name), "%s%s.jpeg", path, skin->name);
|
||||
raw = COM_LoadTempFile (name);
|
||||
if (raw)
|
||||
{
|
||||
pix = ReadJPEGFile(raw, com_filesize, &skin->width, &skin->height);
|
||||
if (pix)
|
||||
{
|
||||
skin->skindata = out = BZ_Malloc(skin->width*skin->height*4);
|
||||
memcpy(out, pix, skin->width*skin->height*4);
|
||||
BZ_Free(pix);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
Q_snprintfz (name, sizeof(name), "%s%s.jpg", path, skin->name); //jpegs are gready with 2 extensions...
|
||||
raw = COM_LoadTempFile (name);
|
||||
if (raw)
|
||||
{
|
||||
pix = ReadJPEGFile(raw, com_filesize, &skin->width, &skin->height);
|
||||
if (pix)
|
||||
{
|
||||
skin->skindata = out = BZ_Malloc(skin->width*skin->height*4);
|
||||
memcpy(out, pix, skin->width*skin->height*4);
|
||||
BZ_Free(pix);
|
||||
return out;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
skin->failedload = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Skin_NextDownload
|
||||
|
@ -542,62 +451,61 @@ void Skin_NextDownload (void)
|
|||
int i;
|
||||
|
||||
//Con_Printf ("Checking skins...\n");
|
||||
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
int j;
|
||||
char *slash;
|
||||
char *skinname;
|
||||
for (i = 0; i != MAX_CLIENTS; i++)
|
||||
{
|
||||
sc = &cl.players[i];
|
||||
if (!sc->name[0])
|
||||
continue;
|
||||
skinname = Info_ValueForKey(sc->userinfo, "skin");
|
||||
slash = strchr(skinname, '/');
|
||||
if (slash)
|
||||
{
|
||||
*slash = 0;
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/tris.md2", skinname), NULL, 0);
|
||||
for (j = 0; j < MAX_MODELS; j++)
|
||||
{
|
||||
if (cl.model_name[j][0] == '#')
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/%s", skinname, cl.model_name[j]+1), NULL, 0);
|
||||
}
|
||||
for (j = 0; j < MAX_SOUNDS; j++)
|
||||
{
|
||||
if (cl.sound_name[j][0] == '*')
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/%s", skinname, cl.sound_name[j]+1), NULL, 0);
|
||||
}
|
||||
*slash = '/';
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s.pcx", skinname), NULL, 0);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
for (i = 0; i != MAX_CLIENTS; i++)
|
||||
{
|
||||
sc = &cl.players[i];
|
||||
if (!sc->name[0])
|
||||
continue;
|
||||
Skin_Find (sc);
|
||||
if (noskins.ival)
|
||||
if (noskins.ival || !sc->qwskin)
|
||||
continue;
|
||||
|
||||
if (strchr(sc->skin->name, ' ')) //skip over skins using a space
|
||||
if (strchr(sc->qwskin->name, ' ')) //skip over skins using a space
|
||||
continue;
|
||||
|
||||
if (!*sc->skin->name)
|
||||
if (!*sc->qwskin->name)
|
||||
continue;
|
||||
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
{
|
||||
int j;
|
||||
char *slash;
|
||||
slash = strchr(sc->skin->name, '/');
|
||||
if (slash)
|
||||
{
|
||||
*slash = 0;
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/tris.md2", sc->skin->name), NULL, 0);
|
||||
for (j = 0; j < MAX_MODELS; j++)
|
||||
{
|
||||
if (cl.model_name[j][0] == '#')
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/%s", sc->skin->name, cl.model_name[j]+1), NULL, 0);
|
||||
}
|
||||
for (j = 0; j < MAX_SOUNDS; j++)
|
||||
{
|
||||
if (cl.sound_name[j][0] == '*')
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s/%s", sc->skin->name, cl.sound_name[j]+1), NULL, 0);
|
||||
}
|
||||
*slash = '/';
|
||||
CL_CheckOrEnqueDownloadFile(va("players/%s.pcx", sc->skin->name), NULL, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
CL_CheckOrEnqueDownloadFile(va("skins/%s.pcx", sc->skin->name), NULL, 0);
|
||||
CL_CheckOrEnqueDownloadFile(va("skins/%s.pcx", sc->qwskin->name), NULL, 0);
|
||||
}
|
||||
|
||||
// now load them in for real
|
||||
for (i=0 ; i<MAX_CLIENTS ; i++)
|
||||
{
|
||||
sc = &cl.players[i];
|
||||
if (!sc->name[0])
|
||||
if (!sc->name[0] || !sc->qwskin)
|
||||
continue;
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
Skin_Cache32(sc->skin);
|
||||
else
|
||||
Skin_Cache8 (sc->skin);
|
||||
#ifdef GLQUAKE
|
||||
sc->skin = NULL;
|
||||
#endif
|
||||
Skin_Cache8 (sc->qwskin);
|
||||
//sc->qwskin = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -607,7 +515,7 @@ void Skin_FlushPlayers(void)
|
|||
{ //wipe the skin info
|
||||
int i;
|
||||
for (i = 0; i < cl.allocated_client_slots; i++)
|
||||
cl.players[i].skin = NULL;
|
||||
cl.players[i].qwskin = NULL;
|
||||
|
||||
for (i = 0; i < cl.allocated_client_slots; i++)
|
||||
CL_NewTranslation(i);
|
||||
|
@ -643,7 +551,7 @@ void Skin_Skins_f (void)
|
|||
return;
|
||||
}
|
||||
|
||||
GL_GAliasFlushSkinCache();
|
||||
R_GAliasFlushSkinCache(false);
|
||||
for (i=0 ; i<numskins ; i++)
|
||||
{
|
||||
if (skins[i].skindata)
|
||||
|
|
|
@ -95,6 +95,10 @@ cvar_t v_projectionmode = SCVAR("v_projectionmode", "0");
|
|||
|
||||
cvar_t scr_autoid = SCVAR("scr_autoid", "1");
|
||||
|
||||
cvar_t chase_active = CVAR("chase_active", "0");
|
||||
cvar_t chase_back = CVAR("chase_back", "48");
|
||||
cvar_t chase_up = CVAR("chase_up", "24");
|
||||
|
||||
|
||||
extern cvar_t cl_chasecam;
|
||||
|
||||
|
@ -1295,13 +1299,24 @@ void V_CalcRefdef (playerview_t *pv)
|
|||
|
||||
r_refdef.time = cl.servertime;
|
||||
|
||||
// smooth out stair step ups
|
||||
|
||||
|
||||
{
|
||||
extern model_t *loadmodel;
|
||||
loadmodel = cl.worldmodel;
|
||||
}
|
||||
|
||||
if (chase_active.ival)
|
||||
{
|
||||
vec3_t axis[3];
|
||||
vec3_t camorg;
|
||||
trace_t tr;
|
||||
AngleVectors(r_refdef.viewangles, axis[0], axis[1], axis[2]);
|
||||
VectorMA(r_refdef.vieworg, -chase_back.value, axis[0], camorg);
|
||||
VectorMA(camorg, -chase_up.value, pv->gravitydir, camorg);
|
||||
// if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace(cl.worldmodel, 0, 0, NULL, r_refdef.vieworg, camorg, vec3_origin, vec3_origin, MASK_WORLDSOLID, &tr))
|
||||
VectorCopy(camorg, r_refdef.vieworg);
|
||||
|
||||
CL_EditExternalModels(0, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1471,6 +1486,11 @@ void V_RenderPlayerViews(playerview_t *pv)
|
|||
DropPunchAngle (pv);
|
||||
|
||||
Cam_SelfTrack(pv);
|
||||
|
||||
oldnuments = cl_numvisedicts;
|
||||
oldstris = cl_numstris;
|
||||
CL_LinkViewModel ();
|
||||
|
||||
if (cl.intermission)
|
||||
{ // intermission / finale rendering
|
||||
V_CalcIntermissionRefdef (pv);
|
||||
|
@ -1482,10 +1502,6 @@ void V_RenderPlayerViews(playerview_t *pv)
|
|||
}
|
||||
V_ApplyRefdef();
|
||||
|
||||
oldnuments = cl_numvisedicts;
|
||||
oldstris = cl_numstris;
|
||||
CL_LinkViewModel ();
|
||||
|
||||
R_RenderView ();
|
||||
R2D_PolyBlend ();
|
||||
R_DrawNameTags();
|
||||
|
@ -1758,4 +1774,8 @@ void V_Init (void)
|
|||
Cvar_Register (&v_gamma, VIEWVARS);
|
||||
Cvar_Register (&v_contrast, VIEWVARS);
|
||||
Cvar_Register (&v_brightness, VIEWVARS);
|
||||
|
||||
// Cvar_Register (&chase_active, VIEWVARS);
|
||||
// Cvar_Register (&chase_back, VIEWVARS);
|
||||
// Cvar_Register (&chase_up, VIEWVARS);
|
||||
}
|
||||
|
|
|
@ -270,7 +270,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
#ifdef QUAKETC
|
||||
#define NOBUITINMENUS //kill engine menus (should be replaced with ewither csqc or menuqc)
|
||||
#define NOBUILTINMENUS //kill engine menus (should be replaced with ewither csqc or menuqc)
|
||||
#undef Q2CLIENT //not useful
|
||||
#undef Q2SERVER //not useful
|
||||
#undef Q3CLIENT //not useful
|
||||
|
|
|
@ -1281,7 +1281,17 @@ pf_hashtab_t pf_reverthashtab; //pf_peristanthashtab as it was at map start, fo
|
|||
static pf_hashtab_t *PF_hash_findtab(pubprogfuncs_t *prinst, int idx)
|
||||
{
|
||||
if (!idx)
|
||||
{
|
||||
if (!pf_peristanthashtab.tab.numbuckets)
|
||||
{
|
||||
int numbuckets = 256;
|
||||
pf_peristanthashtab.defaulttype = ev_string;
|
||||
pf_peristanthashtab.prinst = NULL;
|
||||
pf_peristanthashtab.bucketmem = Z_Malloc(Hash_BytesForBuckets(numbuckets));
|
||||
Hash_InitTable(&pf_peristanthashtab.tab, numbuckets, pf_peristanthashtab.bucketmem);
|
||||
}
|
||||
return &pf_peristanthashtab;
|
||||
}
|
||||
idx -= 1;
|
||||
if (idx >= 0 && idx < MAX_QC_HASHTABLES && pf_hashtab[idx].prinst)
|
||||
return &pf_hashtab[idx];
|
||||
|
@ -1331,7 +1341,7 @@ void QCBUILTIN PF_hash_get (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
{
|
||||
pf_hashtab_t *tab = PF_hash_findtab(prinst, G_FLOAT(OFS_PARM0));
|
||||
const char *name = PR_GetStringOfs(prinst, OFS_PARM1);
|
||||
void *dflt = G_VECTOR(OFS_PARM2);
|
||||
void *dflt = (prinst->callargc>2)?G_VECTOR(OFS_PARM2):vec3_origin;
|
||||
int type = (prinst->callargc>3)?G_FLOAT(OFS_PARM3):0;
|
||||
int index = (prinst->callargc>4)?G_FLOAT(OFS_PARM4):0;
|
||||
pf_hashentry_t *ent = NULL;
|
||||
|
@ -1386,19 +1396,26 @@ void QCBUILTIN PF_hash_add (pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
const char *name = PR_GetStringOfs(prinst, OFS_PARM1);
|
||||
void *data = G_VECTOR(OFS_PARM2);
|
||||
int flags = (prinst->callargc>3)?G_FLOAT(OFS_PARM3):0;
|
||||
int type = (prinst->callargc>4)?G_FLOAT(OFS_PARM4):0;
|
||||
int type = flags & 0xff;
|
||||
pf_hashentry_t *ent = NULL;
|
||||
if (tab)
|
||||
{
|
||||
if (!type)
|
||||
type = tab->defaulttype;
|
||||
if (flags & 1)
|
||||
Hash_Remove(&tab->tab, name);
|
||||
if (flags & 256)
|
||||
{
|
||||
ent = Hash_Get(&tab->tab, name);
|
||||
if (ent)
|
||||
{
|
||||
Hash_RemoveData(&tab->tab, name, ent);
|
||||
BZ_Free(ent);
|
||||
}
|
||||
}
|
||||
if (type == ev_string)
|
||||
{ //strings copy their value out.
|
||||
const char *value = PR_GetStringOfs(prinst, OFS_PARM2);
|
||||
int nlen = strlen(name);
|
||||
int vlen = strlen(data);
|
||||
int vlen = strlen(value);
|
||||
ent = BZ_Malloc(sizeof(*ent) + nlen+1 + vlen+1);
|
||||
ent->name = (char*)(ent+1);
|
||||
ent->type = ev_string;
|
||||
|
@ -4452,7 +4469,7 @@ void QCBUILTIN PF_externcall (pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
|
|||
prinst->pr_trace++; //continue debugging
|
||||
PR_ExecuteProgram(prinst, f);
|
||||
}
|
||||
else if (!f)
|
||||
else
|
||||
{
|
||||
f = PR_FindFunction(prinst, "MissingFunc", progsnum);
|
||||
if (!f)
|
||||
|
|
|
@ -1380,7 +1380,9 @@
|
|||
AdditionalIncludeDirectories="../libs/speex,..\client,../libs/freetype2/include,../common,../server,../gl,../sw,../qclib,../libs,../libs/dxsdk7/include,../d3d,../d3d9,../libs/dxsdk9/include"
|
||||
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;SERVERONLY;MULTITHREAD"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
FloatingPointModel="2"
|
||||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="quakedef.h"
|
||||
|
@ -27238,13 +27240,6 @@
|
|||
<File
|
||||
RelativePath="..\common\net_ssl_winsspi.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="MinGLRelease|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\common\net_wins.c"
|
||||
|
|
|
@ -69,6 +69,17 @@ struct cctx_s
|
|||
int width;
|
||||
int height;
|
||||
};
|
||||
void Mod_FlushSkin(skinid_t id)
|
||||
{
|
||||
skinfile_t *sk;
|
||||
id--;
|
||||
if (id >= numregisteredskins)
|
||||
return; //invalid!
|
||||
sk = registeredskins[id];
|
||||
if (!sk)
|
||||
return;
|
||||
sk->qwskin = NULL;
|
||||
}
|
||||
void Mod_WipeSkin(skinid_t id)
|
||||
{
|
||||
skinfile_t *sk;
|
||||
|
@ -89,14 +100,22 @@ void Mod_WipeSkin(skinid_t id)
|
|||
Z_Free(registeredskins[id]);
|
||||
registeredskins[id] = NULL;
|
||||
}
|
||||
static void Mod_WipeAllSkins(void)
|
||||
static void Mod_WipeAllSkins(qboolean final)
|
||||
{
|
||||
skinid_t id;
|
||||
for (id = 0; id < numregisteredskins; )
|
||||
Mod_WipeSkin(++id);
|
||||
Z_Free(registeredskins);
|
||||
registeredskins = NULL;
|
||||
numregisteredskins = 0;
|
||||
if (final)
|
||||
{
|
||||
for (id = 0; id < numregisteredskins; )
|
||||
Mod_WipeSkin(++id);
|
||||
Z_Free(registeredskins);
|
||||
registeredskins = NULL;
|
||||
numregisteredskins = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (id = 0; id < numregisteredskins; )
|
||||
Mod_FlushSkin(++id);
|
||||
}
|
||||
}
|
||||
skinfile_t *Mod_LookupSkin(skinid_t id)
|
||||
{
|
||||
|
@ -295,6 +314,11 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
|
|||
{
|
||||
//ignore it. matches q3.
|
||||
}
|
||||
else if (!strcmp(com_token, "qwskin"))
|
||||
{
|
||||
skintext = COM_ParseToken(skintext, NULL);
|
||||
Q_strncpyz(skin->qwskinname, com_token, sizeof(skin->qwskinname));
|
||||
}
|
||||
else
|
||||
{
|
||||
while(*skintext == ' ' || *skintext == '\t')
|
||||
|
@ -467,7 +491,10 @@ void GL_GAliasFlushOneSkin(char *skinname)
|
|||
}
|
||||
}
|
||||
}*/
|
||||
void GL_GAliasFlushSkinCache(void)
|
||||
|
||||
//final is set when the renderer is going down.
|
||||
//if not set, this is mid-map, and everything should be regeneratable.
|
||||
void R_GAliasFlushSkinCache(qboolean final)
|
||||
{
|
||||
int i;
|
||||
bucket_t *b;
|
||||
|
@ -494,14 +521,14 @@ void GL_GAliasFlushSkinCache(void)
|
|||
numFacing = 0;
|
||||
#endif
|
||||
|
||||
Mod_WipeAllSkins();
|
||||
Mod_WipeAllSkins(final);
|
||||
}
|
||||
|
||||
static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, entity_t *e, texnums_t **forcedtex)
|
||||
{
|
||||
galiasskin_t *skins;
|
||||
shader_t *shader;
|
||||
skin_t *plskin;
|
||||
qwskin_t *plskin = NULL;
|
||||
int frame;
|
||||
unsigned int subframe;
|
||||
extern int cl_playerindex; //so I don't have to strcmp
|
||||
|
@ -528,6 +555,9 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
return sk->mappings[i].shader;
|
||||
}
|
||||
}
|
||||
if (!sk->qwskin && *sk->qwskinname)
|
||||
sk->qwskin = Skin_Lookup(sk->qwskinname);
|
||||
plskin = sk->qwskin;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -552,14 +582,23 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
|
||||
if (!gl_nocolors.ival || forced)
|
||||
{
|
||||
if (e->playerindex >= 0 && e->playerindex <= MAX_CLIENTS)
|
||||
if (!plskin || plskin->failedload)
|
||||
{
|
||||
if (!cl.players[e->playerindex].skin)
|
||||
Skin_Find(&cl.players[e->playerindex]);
|
||||
plskin = cl.players[e->playerindex].skin;
|
||||
if (e->playerindex >= 0 && e->playerindex <= MAX_CLIENTS)
|
||||
{
|
||||
//heads don't get skinned, only players (and weaponless players), they do still get recoloured.
|
||||
if (model==cl.model_precache[cl_playerindex] || model==cl.model_precache_vwep[0])
|
||||
{
|
||||
if (!cl.players[e->playerindex].qwskin)
|
||||
Skin_Find(&cl.players[e->playerindex]);
|
||||
plskin = cl.players[e->playerindex].qwskin;
|
||||
}
|
||||
else
|
||||
plskin = NULL;
|
||||
}
|
||||
else
|
||||
plskin = NULL;
|
||||
}
|
||||
else
|
||||
plskin = NULL;
|
||||
tc = e->topcolour;
|
||||
bc = e->bottomcolour;
|
||||
pc = e->h2playerclass;
|
||||
|
@ -667,27 +706,13 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
|
||||
if (plskin)
|
||||
{
|
||||
if (cls.protocol == CP_QUAKE2)
|
||||
original = Skin_Cache8(plskin);
|
||||
if (original)
|
||||
{
|
||||
original = Skin_Cache32(plskin);
|
||||
if (original)
|
||||
{
|
||||
inwidth = plskin->width;
|
||||
inheight = plskin->height;
|
||||
cm->texnum.base = R_LoadTexture32(plskin->name, inwidth, inheight, (unsigned int*)original, IF_NOALPHA|IF_NOGAMMA);
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
original = Skin_Cache8(plskin);
|
||||
if (original)
|
||||
{
|
||||
inwidth = plskin->width;
|
||||
inheight = plskin->height;
|
||||
cm->texnum.base = R_LoadTexture8(plskin->name, inwidth, inheight, original, IF_NOALPHA|IF_NOGAMMA, 1);
|
||||
return shader;
|
||||
}
|
||||
inwidth = plskin->width;
|
||||
inheight = plskin->height;
|
||||
cm->texnum.base = R_LoadTexture8(plskin->name, inwidth, inheight, original, IF_NOALPHA|IF_NOGAMMA, 1);
|
||||
return shader;
|
||||
}
|
||||
|
||||
if (TEXVALID(plskin->textures.base))
|
||||
|
@ -707,7 +732,7 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
|
|||
}
|
||||
|
||||
cm->texnum.bump = shader->defaulttextures.bump; //can't colour bumpmapping
|
||||
if (cls.protocol != CP_QUAKE2 && ((model==cl.model_precache[cl_playerindex] || model==cl.model_precache_vwep[0]) && plskin))
|
||||
if (plskin)
|
||||
{
|
||||
/*q1 only reskins the player model, not gibbed heads (which have the same colourmap)*/
|
||||
original = Skin_Cache8(plskin);
|
||||
|
|
|
@ -543,7 +543,7 @@ void GLDraw_DeInit (void)
|
|||
|
||||
R2D_Shutdown();
|
||||
|
||||
GL_GAliasFlushSkinCache();
|
||||
R_GAliasFlushSkinCache(true);
|
||||
|
||||
draw_disc = NULL;
|
||||
GL_ShutdownPostProcessing();
|
||||
|
|
|
@ -32,7 +32,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
extern cvar_t r_shadow_bumpscale_basetexture;
|
||||
extern cvar_t r_replacemodels;
|
||||
extern cvar_t gl_lightmap_average;
|
||||
|
||||
cvar_t mod_external_vis = CVARD("mod_external_vis", "1", "Attempt to load .vis patches for quake maps, allowing transparent water to work properly.");
|
||||
#ifdef SERVERONLY
|
||||
cvar_t gl_overbright, gl_specular, gl_load24bit, r_replacemodels, gl_miptexLevel, r_fb_bmodels; //all of these can/should default to 0
|
||||
cvar_t r_noframegrouplerp = CVARF ("r_noframegrouplerp", "0", CVAR_ARCHIVE);
|
||||
|
@ -529,6 +529,8 @@ void Mod_Init (qboolean initial)
|
|||
Cmd_AddCommand("mod_usetexture", Mod_BlockTextureColour_f);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
Cvar_Register(&mod_external_vis, "Graphical Nicaties");
|
||||
|
||||
if (initial)
|
||||
{
|
||||
|
@ -2065,15 +2067,20 @@ void Mod_LoadLighting (lump_t *l)
|
|||
Mod_LoadVisibility
|
||||
=================
|
||||
*/
|
||||
void Mod_LoadVisibility (lump_t *l)
|
||||
void Mod_LoadVisibility (lump_t *l, qbyte *ptr, size_t len)
|
||||
{
|
||||
if (!l->filelen)
|
||||
if (!ptr)
|
||||
{
|
||||
ptr = mod_base + l->fileofs;
|
||||
len = l->filelen;
|
||||
}
|
||||
if (!len)
|
||||
{
|
||||
loadmodel->visdata = NULL;
|
||||
return;
|
||||
}
|
||||
loadmodel->visdata = ZG_Malloc(&loadmodel->memgroup, l->filelen);
|
||||
memcpy (loadmodel->visdata, mod_base + l->fileofs, l->filelen);
|
||||
loadmodel->visdata = ZG_Malloc(&loadmodel->memgroup, len);
|
||||
memcpy (loadmodel->visdata, ptr, len);
|
||||
}
|
||||
|
||||
|
||||
|
@ -3321,21 +3328,27 @@ qboolean Mod_LoadNodes (lump_t *l, int lm)
|
|||
Mod_LoadLeafs
|
||||
=================
|
||||
*/
|
||||
qboolean Mod_LoadLeafs (lump_t *l, int lm)
|
||||
qboolean Mod_LoadLeafs (lump_t *l, int lm, qbyte *ptr, size_t len)
|
||||
{
|
||||
mleaf_t *out;
|
||||
int i, j, count, p;
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
ptr = mod_base + l->fileofs;
|
||||
len = l->filelen;
|
||||
}
|
||||
|
||||
if (lm==2)
|
||||
{
|
||||
dl2leaf_t *in;
|
||||
in = (void *)(mod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
in = (void *)ptr;
|
||||
if (len % sizeof(*in))
|
||||
{
|
||||
Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name);
|
||||
return false;
|
||||
}
|
||||
count = l->filelen / sizeof(*in);
|
||||
count = len / sizeof(*in);
|
||||
if (count > MAX_MAP_LEAFS)
|
||||
{
|
||||
Con_Printf (CON_ERROR "Mod_LoadLeafs: %s has more than %i leafs\n",loadmodel->name, MAX_MAP_LEAFS);
|
||||
|
@ -3392,13 +3405,13 @@ qboolean Mod_LoadLeafs (lump_t *l, int lm)
|
|||
else if (lm)
|
||||
{
|
||||
dl1leaf_t *in;
|
||||
in = (void *)(mod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
in = (void *)(ptr);
|
||||
if (len % sizeof(*in))
|
||||
{
|
||||
Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name);
|
||||
return false;
|
||||
}
|
||||
count = l->filelen / sizeof(*in);
|
||||
count = len / sizeof(*in);
|
||||
if (count > MAX_MAP_LEAFS)
|
||||
{
|
||||
Con_Printf (CON_ERROR "Mod_LoadLeafs: %s has more than %i leafs\n",loadmodel->name, MAX_MAP_LEAFS);
|
||||
|
@ -3455,13 +3468,13 @@ qboolean Mod_LoadLeafs (lump_t *l, int lm)
|
|||
else
|
||||
{
|
||||
dsleaf_t *in;
|
||||
in = (void *)(mod_base + l->fileofs);
|
||||
if (l->filelen % sizeof(*in))
|
||||
in = (void *)(ptr);
|
||||
if (len % sizeof(*in))
|
||||
{
|
||||
Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size in %s\n",loadmodel->name);
|
||||
return false;
|
||||
}
|
||||
count = l->filelen / sizeof(*in);
|
||||
count = len / sizeof(*in);
|
||||
if (count > MAX_MAP_LEAFS)
|
||||
{
|
||||
Con_Printf (CON_ERROR "Mod_LoadLeafs: %s has more than %i leafs\n",loadmodel->name, MAX_MAP_LEAFS);
|
||||
|
@ -4195,6 +4208,79 @@ static void Mod_FixupMinsMaxs(void)
|
|||
Mod_FixupNodeMinsMaxs (loadmodel->nodes, NULL); // sets nodes and leafs
|
||||
}
|
||||
|
||||
struct vispatch_s
|
||||
{
|
||||
void *fileptr;
|
||||
size_t filelen;
|
||||
|
||||
void *visptr;
|
||||
int vislen;
|
||||
|
||||
void *leafptr;
|
||||
int leaflen;
|
||||
};
|
||||
|
||||
void Mod_FindVisPatch(struct vispatch_s *patch, model_t *mod, size_t leaflumpsize)
|
||||
{
|
||||
char patchname[MAX_QPATH];
|
||||
int *lenptr, len;
|
||||
int ofs;
|
||||
qbyte *file;
|
||||
memset(patch, 0, sizeof(*patch));
|
||||
|
||||
if (!mod_external_vis.ival)
|
||||
return;
|
||||
|
||||
COM_StripExtension(mod->name, patchname, sizeof(patchname));
|
||||
Q_strncatz(patchname, ".vis", sizeof(patchname));
|
||||
|
||||
//ignore the patch file if its in a different gamedir.
|
||||
//this file format sucks too much for other verification.
|
||||
if (FS_FLocateFile(mod->name,FSLFRT_DEPTH_OSONLY, NULL) != FS_FLocateFile(patchname,FSLFRT_DEPTH_OSONLY, NULL))
|
||||
return;
|
||||
|
||||
patch->filelen = FS_LoadFile(patchname, &patch->fileptr);
|
||||
if (!patch->fileptr)
|
||||
return;
|
||||
ofs = 0;
|
||||
while (ofs+36 <= patch->filelen)
|
||||
{
|
||||
file = patch->fileptr;
|
||||
file += ofs;
|
||||
memcpy(patchname, file, 32);
|
||||
patchname[32] = 0;
|
||||
file += 32;
|
||||
lenptr = (int*)file;
|
||||
file += sizeof(int);
|
||||
len = LittleLong(*lenptr);
|
||||
if (ofs+36+len > patch->filelen)
|
||||
break;
|
||||
|
||||
// if (!Q_strcasecmp(patchname, "foo"))
|
||||
{
|
||||
lenptr = (int*)file;
|
||||
patch->vislen = LittleLong(*lenptr);
|
||||
file += sizeof(int);
|
||||
patch->visptr = file;
|
||||
file += patch->vislen;
|
||||
|
||||
lenptr = (int*)file;
|
||||
patch->leaflen = LittleLong(*lenptr);
|
||||
file += sizeof(int);
|
||||
patch->leafptr = file;
|
||||
file += patch->leaflen;
|
||||
|
||||
if (sizeof(int)*2 + patch->vislen + patch->leaflen != len || patch->leaflen != leaflumpsize)
|
||||
{
|
||||
Con_Printf("Vis patch is unsuitable\n");
|
||||
patch->visptr = NULL;
|
||||
patch->leafptr = NULL;
|
||||
}
|
||||
}
|
||||
ofs += 36+len;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Mod_LoadBrushModel
|
||||
|
@ -4202,6 +4288,7 @@ Mod_LoadBrushModel
|
|||
*/
|
||||
qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
|
||||
{
|
||||
struct vispatch_s vispatch;
|
||||
int i, j;
|
||||
dheader_t *header;
|
||||
mmodel_t *bm;
|
||||
|
@ -4306,6 +4393,8 @@ qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
|
|||
|
||||
crouchhullfile = NULL;
|
||||
|
||||
Mod_FindVisPatch(&vispatch, loadmodel, header->lumps[LUMP_LEAFS].filelen);
|
||||
|
||||
TRACE(("Loading info\n"));
|
||||
#ifndef SERVERONLY
|
||||
if (!isnotmap)
|
||||
|
@ -4354,9 +4443,9 @@ qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
|
|||
if (noerrors)
|
||||
{
|
||||
TRACE(("Loading Vis\n"));
|
||||
Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
|
||||
Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY], vispatch.visptr, vispatch.vislen);
|
||||
}
|
||||
noerrors = noerrors && Mod_LoadLeafs (&header->lumps[LUMP_LEAFS], longm);
|
||||
noerrors = noerrors && Mod_LoadLeafs (&header->lumps[LUMP_LEAFS], longm, vispatch.leafptr, vispatch.leaflen);
|
||||
TRACE(("Loading Nodes\n"));
|
||||
noerrors = noerrors && Mod_LoadNodes (&header->lumps[LUMP_NODES], longm);
|
||||
TRACE(("Loading Clipnodes\n"));
|
||||
|
@ -4379,6 +4468,8 @@ qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsize)
|
|||
crouchhullfile=NULL;
|
||||
}
|
||||
|
||||
BZ_Free(vispatch.fileptr);
|
||||
|
||||
if (!noerrors)
|
||||
{
|
||||
return false;
|
||||
|
|
|
@ -9,7 +9,7 @@ model meshes are interpolated multiple times per frame
|
|||
//#define DBG_COLOURNOTDEPTH
|
||||
|
||||
|
||||
#ifdef RTLIGHTS
|
||||
#if defined(RTLIGHTS) && !defined(SERVERONLY)
|
||||
|
||||
#include "glquake.h"
|
||||
#include "shader.h"
|
||||
|
@ -3506,7 +3506,7 @@ void Sh_DrawLights(qbyte *vis)
|
|||
//so this little function is used to check if its needed or not.
|
||||
qboolean Sh_StencilShadowsActive(void)
|
||||
{
|
||||
#ifdef RTLIGHTS
|
||||
#if defined(RTLIGHTS) && !defined(SERVERONLY)
|
||||
//if shadowmapping is forced on all lights then we don't need special depth stuff
|
||||
// if (r_shadow_shadowmapping.ival)
|
||||
// return false;
|
||||
|
@ -3521,7 +3521,7 @@ qboolean Sh_StencilShadowsActive(void)
|
|||
|
||||
void Sh_RegisterCvars(void)
|
||||
{
|
||||
#ifdef RTLIGHTS
|
||||
#if defined(RTLIGHTS) && !defined(SERVERONLY)
|
||||
#define REALTIMELIGHTING "Realtime Lighting"
|
||||
Cvar_Register (&r_shadow_scissor, REALTIMELIGHTING);
|
||||
Cvar_Register (&r_shadow_realtime_world, REALTIMELIGHTING);
|
||||
|
|
|
@ -134,9 +134,6 @@ void GL_InitFogTexture(void);
|
|||
#define GL_BeginRendering()
|
||||
#define GL_EndRendering()
|
||||
|
||||
void GL_FlushSkinCache(void);
|
||||
void GL_GAliasFlushSkinCache(void);
|
||||
|
||||
// Function prototypes for the Texture Object Extension routines
|
||||
typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *,
|
||||
const GLboolean *);
|
||||
|
|
|
@ -814,12 +814,190 @@ qboolean HTTPDL_Poll(struct dl_download *dl)
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
//decode a base64 byte to a 0-63 value. Cannot cope with =.
|
||||
static unsigned int Base64_DecodeByte(char byt)
|
||||
{
|
||||
if (byt >= 'A' && byt <= 'Z')
|
||||
return (byt-'A') + 0;
|
||||
if (byt >= 'a' && byt <= 'z')
|
||||
return (byt-'a') + 26;
|
||||
if (byt >= '0' && byt <= '9')
|
||||
return (byt-'0') + 52;
|
||||
if (byt == '+')
|
||||
return 62;
|
||||
if (byt == '/')
|
||||
return 63;
|
||||
return -1;
|
||||
}
|
||||
//FIXME: we should be able to skip whitespace.
|
||||
static int Base64_Decode(char *out, int outlen, char **srcout, int *srclenout)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned int result;
|
||||
|
||||
char *src = *srcout;
|
||||
int srclen = *srclenout;
|
||||
|
||||
//4 input chars give 3 output chars
|
||||
while(srclen >= 4)
|
||||
{
|
||||
if (len+3 > outlen)
|
||||
{
|
||||
//ran out of space in the output buffer
|
||||
*srcout = src;
|
||||
*srclenout = srclen;
|
||||
return len;
|
||||
}
|
||||
result = Base64_DecodeByte(src[0])<<18;
|
||||
result |= Base64_DecodeByte(src[1])<<12;
|
||||
out[len++] = (result>>16)&0xff;
|
||||
if (src[2] != '=')
|
||||
{
|
||||
result |= Base64_DecodeByte(src[2])<<6;
|
||||
out[len++] = (result>>8)&0xff;
|
||||
if (src[3] != '=')
|
||||
{
|
||||
result |= Base64_DecodeByte(src[3])<<0;
|
||||
out[len++] = (result>>0)&0xff;
|
||||
}
|
||||
}
|
||||
if (result & 0xff000000)
|
||||
return 0; //some kind of invalid char
|
||||
|
||||
src += 4;
|
||||
srclen -= 4;
|
||||
}
|
||||
|
||||
//end of string
|
||||
*srcout = src;
|
||||
*srclenout = srclen;
|
||||
|
||||
//some kind of error
|
||||
if (srclen)
|
||||
{
|
||||
if (srclen != 1 || *src)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
qboolean DataScheme_Decode(struct dl_download *dl)
|
||||
{
|
||||
char block[8192];
|
||||
int remaining, blocksize;
|
||||
char mimetype[256];
|
||||
char baseval[256];
|
||||
char charsetval[256];
|
||||
char *url;
|
||||
char *data;
|
||||
char *charset;
|
||||
char *base;
|
||||
//failed previously
|
||||
if (dl->status == DL_FAILED)
|
||||
return false;
|
||||
|
||||
//data:[<MIME-type>][;charset=<encoding>][;base64],<data>
|
||||
|
||||
*mimetype = 0;
|
||||
*baseval = 0;
|
||||
*charsetval = 0;
|
||||
|
||||
url = dl->url;
|
||||
if (!strncmp(url, "data:", 5))
|
||||
url+=5; //should always match
|
||||
data = strchr(url, ',');
|
||||
if (!data)
|
||||
return false;
|
||||
charset = memchr(url, ';', data-url);
|
||||
if (charset)
|
||||
{
|
||||
base = memchr(charset+1, ';', data-charset);
|
||||
if (base)
|
||||
{
|
||||
if (data-(base+1) >= sizeof(baseval))
|
||||
return false;
|
||||
memcpy(baseval, base+1, data-(base+1));
|
||||
baseval[data-(base+1)] = 0;
|
||||
}
|
||||
else
|
||||
base = data;
|
||||
if (base-(charset+1) >= sizeof(charsetval))
|
||||
return false;
|
||||
memcpy(charsetval, charset+1, base-(charset+1));
|
||||
charsetval[base-(charset+1)] = 0;
|
||||
|
||||
if (!strchr(charsetval, '='))
|
||||
{
|
||||
strcpy(baseval, charsetval);
|
||||
*charsetval = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
charset = data;
|
||||
if (charset-(url) >= sizeof(charsetval))
|
||||
return false;
|
||||
memcpy(mimetype, url, charset-(url));
|
||||
mimetype[charset-(url)] = 0;
|
||||
|
||||
if (!*mimetype)
|
||||
Q_strncpyz(mimetype, "text/plain", sizeof(mimetype));
|
||||
if (!*charsetval)
|
||||
Q_strncpyz(charsetval, "charset=US-ASCII", sizeof(charsetval));
|
||||
|
||||
if (dl->notifystarted)
|
||||
dl->notifystarted(dl, *mimetype?mimetype:NULL);
|
||||
|
||||
if (!dl->file)
|
||||
{
|
||||
#ifndef NPFTE
|
||||
if (*dl->localname)
|
||||
{
|
||||
FS_CreatePath(dl->localname, FS_GAME);
|
||||
dl->file = FS_OpenVFS(dl->localname, "w+b", FS_GAME);
|
||||
}
|
||||
else
|
||||
dl->file = FS_OpenTemp();
|
||||
#endif
|
||||
if (!dl->file)
|
||||
{
|
||||
if (*dl->localname)
|
||||
Con_Printf("HTTP: Couldn't open file \"%s\"\n", dl->localname);
|
||||
else
|
||||
Con_Printf("HTTP: Couldn't open temporary file\n");
|
||||
dl->status = DL_FAILED;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
data++;
|
||||
remaining = strlen(data);
|
||||
while(remaining > 0)
|
||||
{
|
||||
blocksize = Base64_Decode(block, sizeof(block), &data, &remaining);
|
||||
if (!blocksize)
|
||||
{
|
||||
dl->status = DL_FAILED;
|
||||
return false;
|
||||
}
|
||||
VFS_WRITE(dl->file, block, blocksize);
|
||||
}
|
||||
|
||||
dl->status = DL_FINISHED;
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
qboolean DL_Decide(struct dl_download *dl)
|
||||
{
|
||||
const char *url = dl->redir;
|
||||
if (!*url)
|
||||
url = dl->url;
|
||||
|
||||
/*if (!strnicmp(url, "data:", 5))
|
||||
dl->poll = DataScheme_Decode;
|
||||
else*/
|
||||
if (!strnicmp(url, "http://", 7))
|
||||
dl->poll = HTTPDL_Poll;
|
||||
else
|
||||
|
@ -883,11 +1061,12 @@ qboolean DL_CreateThread(struct dl_download *dl, vfsfile_t *file, void (*NotifyF
|
|||
struct dl_download *DL_Create(const char *url)
|
||||
{
|
||||
struct dl_download *newdl;
|
||||
newdl = malloc(sizeof(*newdl));
|
||||
newdl = malloc(sizeof(*newdl) + strlen(url)+1);
|
||||
if (!newdl)
|
||||
return NULL;
|
||||
memset(newdl, 0, sizeof(*newdl));
|
||||
Q_strncpyz(newdl->url, url, sizeof(newdl->url));
|
||||
newdl->url = (char*)(newdl+1);
|
||||
strcpy(newdl->url, url);
|
||||
newdl->poll = DL_Decide;
|
||||
|
||||
if (!newdl->poll(newdl))
|
||||
|
@ -995,10 +1174,10 @@ void HTTP_CL_Think(void)
|
|||
cls.download = &dl->qdownload;
|
||||
dl->qdownload.method = DL_HTTP;
|
||||
if (*dl->localname)
|
||||
strcpy(dl->qdownload.localname, dl->localname);
|
||||
Q_strncpyz(dl->qdownload.localname, dl->localname, sizeof(dl->qdownload.localname));
|
||||
else
|
||||
strcpy(dl->qdownload.localname, dl->url);
|
||||
strcpy(dl->qdownload.remotename, dl->url);
|
||||
Q_strncpyz(dl->qdownload.localname, dl->url, sizeof(dl->qdownload.localname));
|
||||
Q_strncpyz(dl->qdownload.remotename, dl->url, sizeof(dl->qdownload.remotename));
|
||||
dl->qdownload.starttime = Sys_DoubleTime();
|
||||
}
|
||||
|
||||
|
|
|
@ -189,6 +189,7 @@ void HTTP_ServerShutdown(void)
|
|||
|
||||
typedef struct HTTP_active_connections_s {
|
||||
SOCKET datasock;
|
||||
char peername[256];
|
||||
vfsfile_t *file;
|
||||
struct HTTP_active_connections_s *next;
|
||||
|
||||
|
@ -242,6 +243,7 @@ void HTTP_RunExisting (void)
|
|||
char *msg, *nl;
|
||||
char buf2[2560]; //short lived temp buffer.
|
||||
char resource[2560];
|
||||
char host[256];
|
||||
char mode[80];
|
||||
qboolean hostspecified;
|
||||
unsigned int contentlen;
|
||||
|
@ -260,7 +262,7 @@ void HTTP_RunExisting (void)
|
|||
|
||||
if (cl->closereason)
|
||||
{
|
||||
IWebPrintf("Closing connection: %s\n", cl->closereason);
|
||||
IWebPrintf("%s: Closing connection: %s\n", cl->peername, cl->closereason);
|
||||
|
||||
*link = cl->next;
|
||||
closesocket(cl->datasock);
|
||||
|
@ -342,6 +344,9 @@ cont:
|
|||
continue;
|
||||
}
|
||||
|
||||
host[0] = '?';
|
||||
host[1] = 0;
|
||||
|
||||
hostspecified = false;
|
||||
if (!strnicmp(resource, "http://", 7))
|
||||
{ //groan... 1.1 compliance requires parsing this correctly, without the client ever specifiying it.
|
||||
|
@ -351,7 +356,14 @@ cont:
|
|||
if (!slash)
|
||||
strcpy(resource, "/");
|
||||
else
|
||||
{
|
||||
int hlen = slash-(resource+7);
|
||||
if (hlen > sizeof(host)-1)
|
||||
hlen = sizeof(host)-1;
|
||||
memcpy(host, resource+7, hlen);
|
||||
host[hlen] = 0;
|
||||
memmove(resource, slash, strlen(slash+1)); //just get rid of the http:// stuff.
|
||||
}
|
||||
}
|
||||
|
||||
if (!strcmp(resource, "/"))
|
||||
|
@ -397,7 +409,16 @@ cont:
|
|||
msg++;
|
||||
|
||||
if (!strnicmp(msg, "Host: ", 6)) //parse needed header fields
|
||||
{
|
||||
int l = 0;
|
||||
msg += 6;
|
||||
while (*msg == ' ' || *msg == '\t')
|
||||
msg++;
|
||||
while (*msg != '\r' && *msg != '\n' && l < sizeof(host)-1)
|
||||
host[l++] = *msg++;
|
||||
host[l] = 0;
|
||||
hostspecified = true;
|
||||
}
|
||||
else if (!strnicmp(msg, "Content-Length: ", 16)) //parse needed header fields
|
||||
contentlen = strtoul(msg+16, NULL, 0);
|
||||
else if (!strnicmp(msg, "Accept-Encoding:", 16)) //parse needed header fields
|
||||
|
@ -491,7 +512,7 @@ cont:
|
|||
resource[0] = '/';
|
||||
resource[1] = 0; //I'm lazy, they need to comply
|
||||
}
|
||||
IWebPrintf("Download request for \"%s\"\n", resource+1);
|
||||
IWebPrintf("%s: Download request for \"http://%s/%s\"\n", cl->peername, host, resource+1);
|
||||
|
||||
if (!strnicmp(mode, "P", 1)) //when stuff is posted, data is provided. Give an error message if we couldn't do anything with that data.
|
||||
cl->file = IWebGenerateFile(resource+1, content, contentlen);
|
||||
|
@ -519,7 +540,7 @@ cont:
|
|||
}
|
||||
if (!cl->file)
|
||||
{
|
||||
IWebPrintf("Download rejected\n");
|
||||
IWebPrintf("%s: Download rejected\n", cl->peername);
|
||||
|
||||
if (HTTPmarkup >= 3)
|
||||
msg = "HTTP/1.1 404 Not Found\r\n" "Content-Type: text/plain\r\n" "Content-Length: 15\r\n" "Server: "FULLENGINENAME"/0\r\n" "\r\n" "404 Bad address";
|
||||
|
@ -611,7 +632,7 @@ notimplemented:
|
|||
VFS_CLOSE(cl->file);
|
||||
cl->file = NULL;
|
||||
|
||||
IWebPrintf("Download complete\n");
|
||||
IWebPrintf("%s: Download complete\n", cl->peername);
|
||||
}
|
||||
else
|
||||
cl->outbufferused+=ammount;
|
||||
|
@ -663,14 +684,24 @@ notimplemented:
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef WEBSVONLY
|
||||
void VARGS Q_snprintfz (char *dest, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, fmt);
|
||||
vsnprintf (dest, size-1, fmt, args);
|
||||
va_end (args);
|
||||
//make sure its terminated.
|
||||
dest[size-1] = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while true
|
||||
{
|
||||
struct sockaddr_qstorage from;
|
||||
int fromlen;
|
||||
int clientsock;
|
||||
int _true = true;
|
||||
char buf[128];
|
||||
netadr_t na;
|
||||
|
||||
HTTP_active_connections_t *cl;
|
||||
|
||||
|
@ -712,7 +743,7 @@ qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while tr
|
|||
}
|
||||
|
||||
|
||||
Con_Printf ("NET_GetPacket: %s\n", strerror(e));
|
||||
IWebPrintf ("NET_GetPacket: %s\n", strerror(e));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -723,15 +754,19 @@ qboolean HTTP_ServerPoll(qboolean httpserverwanted, int portnum) //loop while tr
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifndef WEBSVONLY
|
||||
SockadrToNetadr(&from, &na);
|
||||
IWebPrintf("New http connection from %s\n", NET_AdrToString(buf, sizeof(buf), &na));
|
||||
#else
|
||||
IWebPrintf("New http connection from %s\n", inet_ntoa(((struct sockaddr_in*)&from)->sin_addr));
|
||||
#endif
|
||||
|
||||
cl = IWebMalloc(sizeof(HTTP_active_connections_t));
|
||||
|
||||
#ifndef WEBSVONLY
|
||||
{
|
||||
netadr_t na;
|
||||
SockadrToNetadr(&from, &na);
|
||||
NET_AdrToString(cl->peername, sizeof(cl->peername), &na);
|
||||
}
|
||||
#else
|
||||
Q_snprintfz(cl->peername, sizeof(cl->peername), "%s:%i", inet_ntoa(((struct sockaddr_in*)&from)->sin_addr), ntohs(((struct sockaddr_in*)&from)->sin_port));
|
||||
#endif
|
||||
IWebPrintf("%s: New http connection\n", cl->peername);
|
||||
|
||||
cl->datasock = clientsock;
|
||||
|
||||
cl->next = HTTP_ServerConnections;
|
||||
|
|
|
@ -106,7 +106,7 @@ struct dl_download
|
|||
qdownload_t qdownload;
|
||||
|
||||
/*stream config*/
|
||||
char url[MAX_OSPATH]; /*original url*/
|
||||
char *url; /*original url*/
|
||||
char redir[MAX_OSPATH]; /*current redirected url*/
|
||||
char localname[MAX_OSPATH]; /*leave empty for a temp file*/
|
||||
struct vfsfile_s *file; /*downloaded to, if not already set when starting will open localname or a temp file*/
|
||||
|
|
|
@ -10,7 +10,7 @@ qboolean SV_AllowDownload (const char *name)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
char com_token[1024];
|
||||
char com_token[sizeof(com_token)];
|
||||
com_tokentype_t com_tokentype;
|
||||
int com_argc;
|
||||
const char **com_argv;
|
||||
|
@ -103,7 +103,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
|
||||
void COM_EnumerateFiles (const char *match, int (*func)(const char *, int, void *, searchpathfuncs_t *f), void *parm)
|
||||
void COM_EnumerateFiles (const char *match, int (*func)(const char *, qofs_t, void *, searchpathfuncs_t *f), void *parm)
|
||||
{
|
||||
HANDLE r;
|
||||
WIN32_FIND_DATA fd;
|
||||
|
|
|
@ -1017,6 +1017,7 @@ void PR_Decompile_f(void)
|
|||
}
|
||||
void PR_Compile_f(void)
|
||||
{
|
||||
qboolean killondone = false;
|
||||
int argc=3;
|
||||
double time = Sys_DoubleTime();
|
||||
char *argv[64] = {"", "-src", pr_sourcedir.string, "-srcfile", "progs.src"};
|
||||
|
@ -1054,10 +1055,16 @@ void PR_Compile_f(void)
|
|||
}
|
||||
|
||||
if (!svprogfuncs)
|
||||
{
|
||||
Q_SetProgsParms(true);
|
||||
killondone = true;
|
||||
}
|
||||
if (PR_StartCompile(svprogfuncs, argc, argv))
|
||||
while(PR_ContinueCompile(svprogfuncs));
|
||||
|
||||
if (killondone)
|
||||
PR_Deinit();
|
||||
|
||||
time = Sys_DoubleTime() - time;
|
||||
|
||||
Con_TPrintf("Compile took %f secs\n", time);
|
||||
|
@ -8904,7 +8911,7 @@ static void QCBUILTIN PF_clusterevent(pubprogfuncs_t *prinst, struct globalvars_
|
|||
const char *dest = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
const char *src = PR_GetStringOfs(prinst, OFS_PARM1);
|
||||
const char *cmd = PR_GetStringOfs(prinst, OFS_PARM2);
|
||||
const char *info = PF_VarString(prinst, 13, pr_globals);
|
||||
const char *info = PF_VarString(prinst, 3, pr_globals);
|
||||
SSV_Send(dest, src, cmd, info);
|
||||
#endif
|
||||
}
|
||||
|
@ -8973,10 +8980,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"bound", PF_Fixme, 0, 0, 0, 45, "float(float min,float value,float max)"},
|
||||
{"pow", PF_Fixme, 0, 0, 0, 46, "float(float,float)"},
|
||||
{"copyentity", PF_Fixme, 0, 0, 0, 47, "void(entity src, entity dst)"},
|
||||
{"fopen", PF_Fixme, 0, 0, 0, 48, "float(string filename, float mode)"},
|
||||
{"fclose", PF_Fixme, 0, 0, 0, 49, "void(float fhandle)"},
|
||||
{"fgets", PF_Fixme, 0, 0, 0, 50, "string(float fhandle)"},
|
||||
{"fputs", PF_Fixme, 0, 0, 0, 51, "void(float fhandle, string s)"},
|
||||
{"fopen", PF_Fixme, 0, 0, 0, 48, "filestream(string filename, float mode)"},
|
||||
{"fclose", PF_Fixme, 0, 0, 0, 49, "void(filestream fhandle)"},
|
||||
{"fgets", PF_Fixme, 0, 0, 0, 50, "string(filestream fhandle)"},
|
||||
{"fputs", PF_Fixme, 0, 0, 0, 51, "void(filestream fhandle, string s)"},
|
||||
{"strlen", PF_Fixme, 0, 0, 0, 52, "float(string)"},
|
||||
{"strcat", PF_Fixme, 0, 0, 0, 53, "string(string, optional string, optional string, optional string, optional string, optional string, optional string, optional string)"},
|
||||
{"substring", PF_Fixme, 0, 0, 0, 54, "string(string s, float start, float length)"},
|
||||
|
@ -8999,10 +9006,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"cvar_string", PF_Fixme, 0, 0, 0, 71, "string(string name)"},
|
||||
{"crash", PF_Fixme, 0, 0, 0, 72, "void()"},
|
||||
{"stackdump", PF_Fixme, 0, 0, 0, 73, "void()"},
|
||||
{"search_begin", PF_Fixme, 0, 0, 0, 74, "float(string pattern, float caseinsensitive, float quiet)"},
|
||||
{"search_end", PF_Fixme, 0, 0, 0, 75, "void(float handle)"},
|
||||
{"search_getsize", PF_Fixme, 0, 0, 0, 76, "float(float handle)"},
|
||||
{"search_getfilename",PF_Fixme, 0, 0, 0, 77, "string(float handle, float num)"},
|
||||
{"search_begin", PF_Fixme, 0, 0, 0, 74, "searchhandle(string pattern, float caseinsensitive, float quiet)"},
|
||||
{"search_end", PF_Fixme, 0, 0, 0, 75, "void(searchhandle handle)"},
|
||||
{"search_getsize", PF_Fixme, 0, 0, 0, 76, "float(searchhandle handle)"},
|
||||
{"search_getfilename",PF_Fixme, 0, 0, 0, 77, "string(searchhandle handle, float num)"},
|
||||
{"etof", PF_Fixme, 0, 0, 0, 79, "float(entity)"},
|
||||
{"ftoe", PF_Fixme, 0, 0, 0, 80, "entity(float)"},
|
||||
{"validstring", PF_Fixme, 0, 0, 0, 81, "float(string)"},
|
||||
|
@ -9161,10 +9168,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
// Tomaz - QuakeC String Manipulation End
|
||||
|
||||
// Tomaz - QuakeC File System Begin (new mods use frik_file instead)
|
||||
{"tq_fopen", PF_fopen, 0, 0, 0, 86, D("float(string filename, float mode)",NULL), true},// (QSG_FILE)
|
||||
{"tq_fclose", PF_fclose, 0, 0, 0, 87, D("void(float fhandle)",NULL), true},// (QSG_FILE)
|
||||
{"tq_fgets", PF_fgets, 0, 0, 0, 88, D("string(float fhandle)",NULL), true},// (QSG_FILE)
|
||||
{"tq_fputs", PF_fputs, 0, 0, 0, 89, D("void(float fhandle, string s)",NULL), true},// (QSG_FILE)
|
||||
{"tq_fopen", PF_fopen, 0, 0, 0, 86, D("filestream(string filename, float mode)",NULL), true},// (QSG_FILE)
|
||||
{"tq_fclose", PF_fclose, 0, 0, 0, 87, D("void(filestream fhandle)",NULL), true},// (QSG_FILE)
|
||||
{"tq_fgets", PF_fgets, 0, 0, 0, 88, D("string(filestream fhandle)",NULL), true},// (QSG_FILE)
|
||||
{"tq_fputs", PF_fputs, 0, 0, 0, 89, D("void(filestream fhandle, string s)",NULL), true},// (QSG_FILE)
|
||||
// Tomaz - QuakeC File System End
|
||||
|
||||
{"rain_go", PF_h2rain_go, 0, 0, 80, 0}, //80
|
||||
|
@ -9260,10 +9267,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
//End TEU_SHOWLMP2
|
||||
|
||||
//frik file
|
||||
{"fopen", PF_fopen, 0, 0, 0, 110, "float(string filename, float mode, optional float mmapminsize)"}, // (FRIK_FILE)
|
||||
{"fclose", PF_fclose, 0, 0, 0, 111, "void(float fhandle)"}, // (FRIK_FILE)
|
||||
{"fgets", PF_fgets, 0, 0, 0, 112, "string(float fhandle)"}, // (FRIK_FILE)
|
||||
{"fputs", PF_fputs, 0, 0, 0, 113, "void(float fhandle, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)"}, // (FRIK_FILE)
|
||||
{"fopen", PF_fopen, 0, 0, 0, 110, "filestream(string filename, float mode, optional float mmapminsize)"}, // (FRIK_FILE)
|
||||
{"fclose", PF_fclose, 0, 0, 0, 111, "void(filestream fhandle)"}, // (FRIK_FILE)
|
||||
{"fgets", PF_fgets, 0, 0, 0, 112, "string(filestream fhandle)"}, // (FRIK_FILE)
|
||||
{"fputs", PF_fputs, 0, 0, 0, 113, "void(filestream fhandle, string s, optional string s2, optional string s3, optional string s4, optional string s5, optional string s6, optional string s7)"}, // (FRIK_FILE)
|
||||
{"strlen", PF_strlen, 0, 0, 0, 114, "float(string s)"}, // (FRIK_FILE)
|
||||
{"strcat", PF_strcat, 0, 0, 0, 115, "string(string s1, optional string s2, ...)"}, // (FRIK_FILE)
|
||||
{"substring", PF_substring, 0, 0, 0, 116, "string(string s, float start, float length)"}, // (FRIK_FILE)
|
||||
|
@ -9284,7 +9291,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"externvalue", PF_externvalue, 0, 0, 0, 203, D("__variant(float prnum, string varname)", "Reads a global in the named progs by the name of that global.\nprnum=0 is the 'default' or 'main' progs.\nprnum=-1 means current progs.\nprnum=-2 will scan through the active progs and will use the first it finds.")},
|
||||
{"externset", PF_externset, 0, 0, 0, 204, D("void(float prnum, __variant newval, string varname)", "Sets a global in the named progs by name.\nprnum=0 is the 'default' or 'main' progs.\nprnum=-1 means current progs.\nprnum=-2 will scan through the active progs and will use the first it finds.")},
|
||||
{"externrefcall", PF_externrefcall, 0, 0, 0, 205, D("__variant(float prnum, void() func, ...)","Calls a function between progs by its reference. No longer needed as direct function calls now switch progs context automatically, and have done for a long time. There is no remaining merit for this function."), true},
|
||||
{"instr", PF_instr, 0, 0, 0, 206, D("float(string input, string token)", "Returns substring(input, strstrpot(input, token), -1), or the null string if token was not found in input. You're probably better off using strstrpos.")},
|
||||
{"instr", PF_instr, 0, 0, 0, 206, D("float(string input, string token)", "Returns substring(input, strstrpos(input, token), -1), or the null string if token was not found in input. You're probably better off using strstrpos.")},
|
||||
#if defined(Q2BSPS) || defined(Q3BSPS)
|
||||
{"openportal", PF_OpenPortal, 0, 0, 0, 207, D("void(entity portal, float state)", "Opens or closes the portals associated with a door or some such on q2 or q3 maps. On Q2BSPs, the entity should be the 'func_areaportal' entity - its style field will say which portal to open. On Q3BSPs, the entity is the door itself, the portal will be determined by the two areas found from a preceding setorigin call.")},
|
||||
#endif
|
||||
|
@ -9317,8 +9324,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"chr2str", PF_chr2str, 0, 0, 0, 223, D("string(float chr, ...)", "The input floats are considered character values, and are concatenated.")},
|
||||
{"strconv", PF_strconv, 0, 0, 0, 224, D("string(float ccase, float redalpha, float redchars, string str, ...)", "Converts quake chars in the input string amongst different representations.\nccase specifies the new case for letters.\n 0: not changed.\n 1: forced to lower case.\n 2: forced to upper case.\nredalpha and redchars switch between colour ranges.\n 0: no change.\n 1: Forced white.\n 2: Forced red.\n 3: Forced gold(low) (numbers only).\n 4: Forced gold (high) (numbers only).\n 5+6: Forced to white and red alternately.\nYou should not use this builtin in combination with UTF-8.")},
|
||||
{"strpad", PF_strpad, 0, 0, 0, 225, D("string(float pad, string str1, ...)", "Pads the string with spaces, to ensure its a specific length (so long as a fixed-width font is used, anyway). If pad is negative, the spaces are added on the left. If positive the padding is on the right.")}, //will be moved
|
||||
{"infoadd", PF_infoadd, 0, 0, 0, 226, D("string(string old, string key, string value)", "Returns a new tempstring infostring with the named value changed (or added if it was previously unspecified). Key and value may not contain the \\ character.")},
|
||||
{"infoget", PF_infoget, 0, 0, 0, 227, D("string(string info, string key)", "Reads a named value from an infostring. The returned value is a tempstring")},
|
||||
{"infoadd", PF_infoadd, 0, 0, 0, 226, D("string(infostring old, string key, string value)", "Returns a new tempstring infostring with the named value changed (or added if it was previously unspecified). Key and value may not contain the \\ character.")},
|
||||
{"infoget", PF_infoget, 0, 0, 0, 227, D("string(infostring info, string key)", "Reads a named value from an infostring. The returned value is a tempstring")},
|
||||
// {"strcmp", PF_strncmp, 0, 0, 0, 228, D("float(string s1, string s2)", "Compares the two strings exactly. s1ofs allows you to treat s2 as a substring to compare against, or should be 0.\nReturns 0 if the two strings are equal, a negative value if s1 appears numerically lower, and positive if s1 appears numerically higher.")},
|
||||
{"strncmp", PF_strncmp, 0, 0, 0, 228, D("#define strcmp strncmp\nfloat(string s1, string s2, optional float len, optional float s1ofs, optional float s2ofs)", "Compares up to 'len' chars in the two strings. s1ofs allows you to treat s2 as a substring to compare against, or should be 0.\nReturns 0 if the two strings are equal, a negative value if s1 appears numerically lower, and positive if s1 appears numerically higher.")},
|
||||
{"strcasecmp", PF_strncasecmp, 0, 0, 0, 229, D("float(string s1, string s2)", "Compares the two strings without case sensitivity.\nReturns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon.")},
|
||||
|
@ -9393,13 +9400,13 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"frametoname", PF_frametoname, 0, 0, 0, 284, "string(float modidx, float framenum)"},
|
||||
{"skintoname", PF_skintoname, 0, 0, 0, 285, "string(float modidx, float skin)"},
|
||||
// {"cvar_setlatch", PF_cvar_setlatch, 0, 0, 0, 286, "void(string cvarname, optional string value)"},
|
||||
{"hash_createtab", PF_hash_createtab, 0, 0, 0, 287, D("float(float tabsize, optional float defaulttype)", "Creates a hash table object with at least 'tabsize' slots. hash table with index 0 is a game-persistant table and will NEVER be returned by this builtin (except as an error return).")},
|
||||
{"hash_destroytab", PF_hash_destroytab, 0, 0, 0, 288, D("void(float table)", "Destroys a hash table object.")},
|
||||
{"hash_add", PF_hash_add, 0, 0, 0, 289, D("void(float table, string name, __variant value, optional float flags, optional float type)", "Adds the given key with the given value to the table.\nIf flags&HASH_REPLACE, the old value will be removed, if not set then multiple values may be added for a single key, they won't overwrite.\nThe type argument describes how the value should be stored and saved to files. While you can claim that all variables are just vectors, being more precise can result in less issues with tempstrings or saved games.")},
|
||||
{"hash_get", PF_hash_get, 0, 0, 0, 290, D("__variant(float table, string name, __variant deflt, optional float requiretype, optional float index)", "looks up the specified key name in the hash table. returns deflt if key was not found. If stringsonly=1, the return value will be in the form of a tempstring, otherwise it'll be the original value argument exactly as it was. If requiretype is specified, then values not of the specified type will be ignored. Hurrah for multiple types with the same name.")},
|
||||
{"hash_delete", PF_hash_delete, 0, 0, 0, 291, D("__variant(float table, string name)", "removes the named key. returns the value of the object that was destroyed, or 0 on error.")},
|
||||
{"hash_getkey", PF_hash_getkey, 0, 0, 0, 292, D("string(float table, float idx)", "gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all.")},
|
||||
{"hash_getcb", PF_hash_getcb, 0, 0, 0, 293, D("void(float table, void(string keyname, __variant val) callback, optional string name)", "For each item in the table that matches the name, call the callback. if name is omitted, will enumerate ALL keys."), true},
|
||||
{"hash_createtab", PF_hash_createtab, 0, 0, 0, 287, D("hashtable(float tabsize, optional float defaulttype)", "Creates a hash table object with at least 'tabsize' slots. hash table with index 0 is a game-persistant table and will NEVER be returned by this builtin (except as an error return).")},
|
||||
{"hash_destroytab", PF_hash_destroytab, 0, 0, 0, 288, D("void(hashtable table)", "Destroys a hash table object.")},
|
||||
{"hash_add", PF_hash_add, 0, 0, 0, 289, D("void(hashtable table, string name, __variant value, optional float typeandflags)", "Adds the given key with the given value to the table.\nIf flags&HASH_REPLACE, the old value will be removed, if not set then multiple values may be added for a single key, they won't overwrite.\nThe type argument describes how the value should be stored and saved to files. While you can claim that all variables are just vectors, being more precise can result in less issues with tempstrings or saved games.")},
|
||||
{"hash_get", PF_hash_get, 0, 0, 0, 290, D("__variant(hashtable table, string name, optional __variant deflt, optional float requiretype, optional float index)", "looks up the specified key name in the hash table. returns deflt if key was not found. If stringsonly=1, the return value will be in the form of a tempstring, otherwise it'll be the original value argument exactly as it was. If requiretype is specified, then values not of the specified type will be ignored. Hurrah for multiple types with the same name.")},
|
||||
{"hash_delete", PF_hash_delete, 0, 0, 0, 291, D("__variant(hashtable table, string name)", "removes the named key. returns the value of the object that was destroyed, or 0 on error.")},
|
||||
{"hash_getkey", PF_hash_getkey, 0, 0, 0, 292, D("string(hashtable table, float idx)", "gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all.")},
|
||||
{"hash_getcb", PF_hash_getcb, 0, 0, 0, 293, D("void(hashtable table, void(string keyname, __variant val) callback, optional string name)", "For each item in the table that matches the name, call the callback. if name is omitted, will enumerate ALL keys."), true},
|
||||
{"checkcommand", PF_checkcommand, 0, 0, 0, 294, D("float(string name)", "Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist.")},
|
||||
{"argescape", PF_argescape, 0, 0, 0, 295, D("string(string s)", "Marks up a string so that it can be reliably tokenized as a single argument later.")},
|
||||
{"clusterevent", PF_clusterevent, 0, 0, 0, 296, D("void(string dest, string from, string cmd, string info)", "Only functions in mapcluster mode. Sends an event to whichever server the named player is on. The destination server can then dispatch the event to the client or handle it itself via the SV_ParseClusterEvent entrypoint. If dest is empty, the event is broadcast to ALL servers. If the named player can't be found, the event will be returned to this server with the cmd prefixed with 'error:'.")},
|
||||
|
@ -9586,16 +9593,16 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
|
||||
#ifndef SERVERONLY
|
||||
//begin menu-only
|
||||
{"buf_create", PF_Fixme, 0, 0, 0, 440, "float()"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_del", PF_Fixme, 0, 0, 0, 441, "void(float bufhandle)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_getsize", PF_Fixme, 0, 0, 0, 442, "float(float bufhandle)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_copy", PF_Fixme, 0, 0, 0, 443, "void(float bufhandle_from, float bufhandle_to)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_sort", PF_Fixme, 0, 0, 0, 444, "void(float bufhandle, float sortprefixlen, float backward)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_implode", PF_Fixme, 0, 0, 0, 445, "string(float bufhandle, string glue)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_get", PF_Fixme, 0, 0, 0, 446, "string(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_set", PF_Fixme, 0, 0, 0, 447, "void(float bufhandle, float string_index, string str)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_add", PF_Fixme, 0, 0, 0, 448, "float(float bufhandle, string str, float order)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_free", PF_Fixme, 0, 0, 0, 449, "void(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_create", PF_Fixme, 0, 0, 0, 440, "strbuf()"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_del", PF_Fixme, 0, 0, 0, 441, "void(strbuf bufhandle)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_getsize", PF_Fixme, 0, 0, 0, 442, "float(strbuf bufhandle)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_copy", PF_Fixme, 0, 0, 0, 443, "void(strbuf bufhandle_from, float bufhandle_to)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_sort", PF_Fixme, 0, 0, 0, 444, "void(strbuf bufhandle, float sortprefixlen, float backward)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_implode", PF_Fixme, 0, 0, 0, 445, "string(strbuf bufhandle, string glue)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_get", PF_Fixme, 0, 0, 0, 446, "string(strbuf bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_set", PF_Fixme, 0, 0, 0, 447, "void(strbuf bufhandle, float string_index, string str)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_add", PF_Fixme, 0, 0, 0, 448, "float(strbuf bufhandle, string str, float order)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_free", PF_Fixme, 0, 0, 0, 449, "void(strbuf bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
{"iscachedpic", PF_Fixme, 0, 0, 0, 451, "float(string name)"},// (EXT_CSQC)
|
||||
{"precache_pic", PF_Fixme, 0, 0, 0, 452, "string(string name, optional float trywad)"},// (EXT_CSQC)
|
||||
{"freepic", PF_Fixme, 0, 0, 0, 453, "void(string name)"},// (EXT_CSQC)
|
||||
|
@ -9622,10 +9629,10 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"tokenize", PF_Tokenize, 0, 0, 0, 441, "float(string s)"},// (KRIMZON_SV_PARSECLIENTCOMMAND)
|
||||
{"argv", PF_ArgV, 0, 0, 0, 442, "string(float n)"},// (KRIMZON_SV_PARSECLIENTCOMMAND
|
||||
{"setattachment", PF_setattachment, 0, 0, 0, 443, "void(entity e, entity tagentity, string tagname)"},// (DP_GFX_QUAKE3MODELTAGS)
|
||||
{"search_begin", PF_search_begin, 0, 0, 0, 444, D("float(string pattern, float caseinsensitive, float quiet)", "initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle.")},
|
||||
{"search_end", PF_search_end, 0, 0, 0, 445, "void(float handle)"},
|
||||
{"search_getsize", PF_search_getsize, 0, 0, 0, 446, D("float(float handle)", "Retrieves the number of files that were found.")},
|
||||
{"search_getfilename", PF_search_getfilename,0, 0, 0, 447, D("string(float handle, float num)", "Retrieves name of one of the files that was found by the initial search.")},
|
||||
{"search_begin", PF_search_begin, 0, 0, 0, 444, D("searchhandle(string pattern, float caseinsensitive, float quiet)", "initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle.")},
|
||||
{"search_end", PF_search_end, 0, 0, 0, 445, "void(searchhandle handle)"},
|
||||
{"search_getsize", PF_search_getsize, 0, 0, 0, 446, D("float(searchhandle handle)", "Retrieves the number of files that were found.")},
|
||||
{"search_getfilename", PF_search_getfilename,0, 0, 0, 447, D("string(searchhandle handle, float num)", "Retrieves name of one of the files that was found by the initial search.")},
|
||||
{"cvar_string", PF_cvar_string, 0, 0, 0, 448, "string(string cvarname)"},//DP_QC_CVAR_STRING
|
||||
{"findflags", PF_FindFlags, 0, 0, 0, 449, "entity(entity start, .float fld, float match)"},//DP_QC_FINDFLAGS
|
||||
{"findchainflags", PF_sv_findchainflags,0, 0, 0, 450, "entity(.float fld, float match)"},//DP_QC_FINDCHAINFLAGS
|
||||
|
@ -9638,16 +9645,16 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
// {"te_flamejet", PF_te_flamejet, 0, 0, 0, 457, "void(vector org, vector vel, float howmany)"},//DP_TE_FLAMEJET
|
||||
// {"undefined", PF_Fixme, 0, 0, 0, 458, ""},
|
||||
{"edict_num", PF_edict_for_num, 0, 0, 0, 459, "entity(float entnum)"},//DP_QC_EDICT_NUM
|
||||
{"buf_create", PF_buf_create, 0, 0, 0, 460, "float()"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_del", PF_buf_del, 0, 0, 0, 461, "void(float bufhandle)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_getsize", PF_buf_getsize, 0, 0, 0, 462, "float(float bufhandle)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_copy", PF_buf_copy, 0, 0, 0, 463, "void(float bufhandle_from, float bufhandle_to)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_sort", PF_buf_sort, 0, 0, 0, 464, "void(float bufhandle, float sortprefixlen, float backward)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_implode", PF_buf_implode, 0, 0, 0, 465, "string(float bufhandle, string glue)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_get", PF_bufstr_get, 0, 0, 0, 466, "string(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_set", PF_bufstr_set, 0, 0, 0, 467, "void(float bufhandle, float string_index, string str)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_add", PF_bufstr_add, 0, 0, 0, 468, "float(float bufhandle, string str, float order)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_free", PF_bufstr_free, 0, 0, 0, 469, "void(float bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_create", PF_buf_create, 0, 0, 0, 460, "strbuf()"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_del", PF_buf_del, 0, 0, 0, 461, "void(strbuf bufhandle)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_getsize", PF_buf_getsize, 0, 0, 0, 462, "float(strbuf bufhandle)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_copy", PF_buf_copy, 0, 0, 0, 463, "void(strbuf bufhandle_from, strbuf bufhandle_to)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_sort", PF_buf_sort, 0, 0, 0, 464, "void(strbuf bufhandle, float sortprefixlen, float backward)"},//DP_QC_STRINGBUFFERS
|
||||
{"buf_implode", PF_buf_implode, 0, 0, 0, 465, "string(strbuf bufhandle, string glue)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_get", PF_bufstr_get, 0, 0, 0, 466, "string(strbuf bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_set", PF_bufstr_set, 0, 0, 0, 467, "void(strbuf bufhandle, float string_index, string str)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_add", PF_bufstr_add, 0, 0, 0, 468, "float(strbuf bufhandle, string str, float order)"},//DP_QC_STRINGBUFFERS
|
||||
{"bufstr_free", PF_bufstr_free, 0, 0, 0, 469, "void(strbuf bufhandle, float string_index)"},//DP_QC_STRINGBUFFERS
|
||||
//end non-menu
|
||||
|
||||
// {"undefined", PF_Fixme, 0, 0, 0, 470, ""},
|
||||
|
@ -9699,7 +9706,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"tokenize_console",PF_tokenize_console,0, 0, 0, 514, "float(string str)"},
|
||||
{"argv_start_index",PF_argv_start_index,0, 0, 0, 515, "float(float idx)"},
|
||||
{"argv_end_index", PF_argv_end_index, 0, 0, 0, 516, "float(float idx)"},
|
||||
{"buf_cvarlist", PF_buf_cvarlist, 0, 0, 0, 517, "void(float strbuf)"},
|
||||
{"buf_cvarlist", PF_buf_cvarlist, 0, 0, 0, 517, "void(strbuf strbuf)"},
|
||||
{"cvar_description",PF_cvar_description,0, 0, 0, 518, "string(string cvarname)"},
|
||||
{"gettime", PF_gettime, 0, 0, 0, 519, "float(optional float timetype)"},
|
||||
{"keynumtostring_omgwtf",PF_Fixme, 0, 0, 0, 520, "string(float keynum)"}, //excessive third version in dp's csqc.
|
||||
|
@ -9722,8 +9729,8 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
// {"log", PF_Fixme, 0, 0, 0, 532, "float(string mname)", true},
|
||||
{"getsoundtime", PF_Ignore, 0, 0, 0, 533, "float(entity e, float channel)"},
|
||||
{"soundlength", PF_Ignore, 0, 0, 0, 534, "float(string sample)"},
|
||||
{"buf_loadfile", PF_buf_loadfile, 0, 0, 0, 535, "float(string filename, float bufhandle)"},
|
||||
{"buf_writefile", PF_buf_writefile, 0, 0, 0, 536, "float(float filehandle, float bufhandle, optional float startpos, optional float numstrings)"},
|
||||
{"buf_loadfile", PF_buf_loadfile, 0, 0, 0, 535, "float(string filename, strbuf bufhandle)"},
|
||||
{"buf_writefile", PF_buf_writefile, 0, 0, 0, 536, "float(filestream filehandle, strbuf bufhandle, optional float startpos, optional float numstrings)"},
|
||||
// {"bufstr_find", PF_Fixme, 0, 0, 0, 537, "float(float bufhandle, string match, float matchrule, float startpos)"},
|
||||
// {"matchpattern", PF_Fixme, 0, 0, 0, 538, "float(string s, string pattern, float matchrule)"},
|
||||
// {"undefined", PF_Fixme, 0, 0, 0, 539, ""},
|
||||
|
@ -9739,7 +9746,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
|
|||
{"setmousetarget", PF_Fixme, 0, 0, 0, 603, "void(float trg)"},
|
||||
{"getmousetarget", PF_Fixme, 0, 0, 0, 604, "float()"},
|
||||
{"callfunction", PF_callfunction, 0, 0, 0, 605, D("void(.../*, string funcname*/)", "Invokes the named function. The function name is always passed as the last parameter and must always be present. The others are passed to the named function as-is")},
|
||||
{"writetofile", PF_writetofile, 0, 0, 0, 606, D("void(float fh, entity e)", "Writes an entity's fields to the named frik_file file handle.")},
|
||||
{"writetofile", PF_writetofile, 0, 0, 0, 606, D("void(filestream fh, entity e)", "Writes an entity's fields to the named frik_file file handle.")},
|
||||
{"isfunction", PF_isfunction, 0, 0, 0, 607, "float(string s)"},
|
||||
{"getresolution", PF_Fixme, 0, 0, 0, 608, "vector(float vidmode, optional float forfullscreen)"},
|
||||
{"keynumtostring_menu",PF_Fixme, 0, 0, 0, 609, "string(float keynum)"}, //third copy of this builtin in dp's csqc.
|
||||
|
@ -10133,6 +10140,7 @@ void PR_DumpPlatform_f(void)
|
|||
char dbgfname[MAX_OSPATH];
|
||||
unsigned int targ = 0;
|
||||
qboolean defines = false;
|
||||
qboolean accessors = false;
|
||||
char *comment;
|
||||
|
||||
/*this list is here to ensure that the file can be used as a valid initial qc file (ignoring precompiler options)*/
|
||||
|
@ -10369,7 +10377,7 @@ void PR_DumpPlatform_f(void)
|
|||
|
||||
{"TRUE", "const float", ALL, NULL, 1},
|
||||
{"FALSE", "const float", ALL, "File not found...", 0},
|
||||
{"M_PI", "const float", ALL, "File not found...", M_PI},
|
||||
{"M_PI", "const float", ALL, NULL, M_PI},
|
||||
|
||||
{"MOVETYPE_NONE", "const float", QW|NQ|CS, NULL, MOVETYPE_NONE},
|
||||
{"MOVETYPE_WALK", "const float", QW|NQ|CS, NULL, MOVETYPE_WALK},
|
||||
|
@ -10585,16 +10593,15 @@ void PR_DumpPlatform_f(void)
|
|||
{"EV_VECTOR", "const float", QW|NQ, NULL, ev_vector},
|
||||
{"EV_ENTITY", "const float", QW|NQ, NULL, ev_entity},
|
||||
// {"EV_FIELD", "const float", QW|NQ, NULL, ev_field},
|
||||
// {"EV_FUNCTION", "const float", QW|NQ, NULL, ev_function},
|
||||
// {"EV_POINTER", "const float", QW|NQ, NULL, ev_pointer},
|
||||
{"EV_FUNCTION", "const float", QW|NQ, NULL, ev_function},
|
||||
{"EV_POINTER", "const float", QW|NQ, NULL, ev_pointer},
|
||||
{"EV_INTEGER", "const float", QW|NQ, NULL, ev_integer},
|
||||
// {"EV_VARIANT", "const float", QW|NQ, NULL, ev_variant},
|
||||
{"EV_VARIANT", "const float", QW|NQ, NULL, ev_variant},
|
||||
// {"EV_STRUCT", "const float", QW|NQ, NULL, ev_struct},
|
||||
// {"EV_UNION", "const float", QW|NQ, NULL, ev_union},
|
||||
|
||||
{"HASHT_PERSISTANT", "const float", ALL, "Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted).", 0},
|
||||
{"HASH_REPLACE", "const float", ALL, "Used with hash_add. Attempts to remove the old value instead of adding two values for a single key.", 1},
|
||||
{"HASH_STRING", "const float", ALL, "Used with hash_add. Specifies that the contents of the string argument should be internally zoned.", 2},
|
||||
{"gamestate", "hashtable", ALL, "Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted).", 0},
|
||||
{"HASH_REPLACE", "const float", ALL, "Used with hash_add. Attempts to remove the old value instead of adding two values for a single key.", 256},
|
||||
|
||||
{"STAT_HEALTH", "const float", CS, NULL, STAT_HEALTH},
|
||||
{"STAT_WEAPON", "const float", CS, NULL, STAT_WEAPON},
|
||||
|
@ -10779,6 +10786,10 @@ void PR_DumpPlatform_f(void)
|
|||
defines = true;
|
||||
if (!stricmp(Cmd_Argv(i), "-Fnodefines"))
|
||||
defines = false;
|
||||
if (!stricmp(Cmd_Argv(i), "-Faccessors"))
|
||||
accessors = true;
|
||||
if (!stricmp(Cmd_Argv(i), "-Fnoaccessors"))
|
||||
accessors = false;
|
||||
if (!stricmp(Cmd_Argv(i), "-O"))
|
||||
fname = Cmd_Argv(++i);
|
||||
}
|
||||
|
@ -10808,6 +10819,7 @@ void PR_DumpPlatform_f(void)
|
|||
"-Tcs - dump specifically CSQC fields\n"
|
||||
"-Tmenu - dump specifically menuqc fields\n"
|
||||
"-Fdefines - generate #defines instead of constants\n"
|
||||
"-Faccessors - use accessors instead of basic types via defines\n"
|
||||
"-O - write to a different qc file\n"
|
||||
"*/\n"
|
||||
, FULLENGINENAME, FTE_VER_MAJOR, FTE_VER_MINOR, Cmd_Argv(0), Cmd_Args());
|
||||
|
@ -10877,6 +10889,25 @@ void PR_DumpPlatform_f(void)
|
|||
"#endif\n"
|
||||
);
|
||||
|
||||
|
||||
if (accessors)
|
||||
{
|
||||
VFS_PRINTF(f, "accessor strbuf : float;\n");
|
||||
VFS_PRINTF(f, "accessor searchhandle : float;\n");
|
||||
VFS_PRINTF(f, "accessor hashtable : float;\n");
|
||||
VFS_PRINTF(f, "accessor infostring : string;\n");
|
||||
VFS_PRINTF(f, "accessor filestream : float;\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
VFS_PRINTF(f, "#define strbuf float\n");
|
||||
VFS_PRINTF(f, "#define searchhandle float\n");
|
||||
VFS_PRINTF(f, "#define hashtable float\n");
|
||||
VFS_PRINTF(f, "#define infostring string\n");
|
||||
VFS_PRINTF(f, "#define filestream float\n");
|
||||
}
|
||||
|
||||
|
||||
for (i = 0; knowndefs[i].name; i++)
|
||||
{
|
||||
for (j = 0; j < i; j++)
|
||||
|
@ -10963,10 +10994,20 @@ void PR_DumpPlatform_f(void)
|
|||
comment = "";
|
||||
if (!strcmp(knowndefs[i].type, "const float"))
|
||||
{
|
||||
if (defines)
|
||||
VFS_PRINTF(f, "#define %s %g%s\n", knowndefs[i].name, knowndefs[i].value, comment);
|
||||
if (knowndefs[i].value >= (1<<23))
|
||||
{
|
||||
if (defines)
|
||||
VFS_PRINTF(f, "#define %s %i%s\n", knowndefs[i].name, (int)knowndefs[i].value, comment);
|
||||
else
|
||||
VFS_PRINTF(f, "%s %s = %i;%s\n", knowndefs[i].type, knowndefs[i].name, (int)knowndefs[i].value, comment);
|
||||
}
|
||||
else
|
||||
VFS_PRINTF(f, "%s %s = %g;%s\n", knowndefs[i].type, knowndefs[i].name, knowndefs[i].value, comment);
|
||||
{
|
||||
if (defines)
|
||||
VFS_PRINTF(f, "#define %s %g%s\n", knowndefs[i].name, knowndefs[i].value, comment);
|
||||
else
|
||||
VFS_PRINTF(f, "%s %s = %g;%s\n", knowndefs[i].type, knowndefs[i].name, knowndefs[i].value, comment);
|
||||
}
|
||||
}
|
||||
else if (!strcmp(knowndefs[i].type, "const string"))
|
||||
{
|
||||
|
@ -11198,6 +11239,42 @@ void PR_DumpPlatform_f(void)
|
|||
VFS_PRINTF(f, "#endif\n");
|
||||
}
|
||||
|
||||
if (accessors)
|
||||
{
|
||||
VFS_PRINTF(f,
|
||||
"accessor strbuf : float\n{\n"
|
||||
"\tget float asfloat[float idx] = {return stof(bufstr_get(this, idx));};\n"
|
||||
"\tset float asfloat[float idx] = {bufstr_set(this, idx, ftos(value));};\n"
|
||||
"\tget string[float] = bufstr_get;\n"
|
||||
"\tset string[float] = bufstr_set;\n"
|
||||
"\tget float length = buf_getsize;\n"
|
||||
"};\n");
|
||||
VFS_PRINTF(f,
|
||||
"accessor searchhandle : float\n{\n"
|
||||
"\tget string[float] = search_getfilename;\n"
|
||||
"\tget float length = search_getsize;\n"
|
||||
"};\n");
|
||||
VFS_PRINTF(f,
|
||||
"accessor hashtable : float\n{\n"
|
||||
"\tget vector v[string key] = {return hash_get(this, key, '0 0 0', EV_VECTOR);};\n"
|
||||
"\tset vector v[string key] = {hash_add(this, key, value, 1, EV_VECTOR);};\n"
|
||||
"\tget string s[string key] = {return hash_get(this, key, \"\", EV_STRING);};\n"
|
||||
"\tset string s[string key] = {hash_add(this, key, value, 1, EV_STRING);};\n"
|
||||
"\tget string f[string key] = {return hash_get(this, key, 0.0, EV_FLOAT);};\n"
|
||||
"\tset string f[string key] = {hash_add(this, key, value, 1, EV_FLOAT);};\n"
|
||||
"\tget __variant[string key] = {return hash_get(this, key, __NULL__);};\n"
|
||||
"\tset __variant[string key] = {hash_add(this, key, value, 1);};\n"
|
||||
"};\n");
|
||||
VFS_PRINTF(f,
|
||||
"accessor infostring : string\n{\n"
|
||||
"\tget string[string] = infoget;\n"
|
||||
"};\n");
|
||||
VFS_PRINTF(f,
|
||||
"accessor filestream : float\n{\n"
|
||||
"\tget string = fgets;\n"
|
||||
"\tset string = {fputs(this,value);};\n"
|
||||
"};\n");
|
||||
}
|
||||
|
||||
VFS_PRINTF(f, "#pragma noref 0\n");
|
||||
|
||||
|
|
|
@ -1022,6 +1022,7 @@ void SSV_InstructMaster(sizebuf_t *cmd);
|
|||
void SSV_PrintToMaster(char *s);
|
||||
void SSV_ReadFromControlServer(void);
|
||||
void SSV_SavePlayerStats(client_t *cl, int reason); //initial, periodic (in case of node crashes), part
|
||||
void SSV_RequestShutdown(void); //asks the cluster to not send us new players
|
||||
|
||||
void Sys_InstructSlave(pubsubserver_t *s, sizebuf_t *cmd);
|
||||
int Sys_SubServerRead(pubsubserver_t *s); //1: yes. 0: no. -1: error
|
||||
|
|
|
@ -569,6 +569,9 @@ void SV_Map_f (void)
|
|||
#ifndef SERVERONLY
|
||||
SCR_SetLoadingStage(LS_NONE);
|
||||
#endif
|
||||
|
||||
if (SSV_IsSubServer())
|
||||
Cbuf_AddText("\nquit\n", RESTRICT_LOCAL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,6 @@ void VARGS SV_RejectMessage(int protocol, char *format, ...);
|
|||
|
||||
void MSV_UpdatePlayerStats(unsigned int playerid, unsigned int serverid, int numstats, float *stats);
|
||||
|
||||
static char *knownmaps[] =
|
||||
{
|
||||
"",
|
||||
"start"
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
//fixme: hash tables
|
||||
unsigned int playerid;
|
||||
|
@ -93,11 +87,7 @@ pubsubserver_t *MSV_StartSubServer(unsigned int id, const char *mapname)
|
|||
if (s)
|
||||
{
|
||||
if (!id)
|
||||
{
|
||||
if (nextserverid < sizeof(knownmaps)/sizeof(knownmaps[0]))
|
||||
nextserverid = sizeof(knownmaps)/sizeof(knownmaps[0]);
|
||||
id = nextserverid++;
|
||||
}
|
||||
id = ++nextserverid;
|
||||
s->id = id;
|
||||
s->next = subservers;
|
||||
subservers = s;
|
||||
|
@ -125,33 +115,54 @@ pubsubserver_t *MSV_FindSubServer(unsigned int id)
|
|||
return s;
|
||||
}
|
||||
|
||||
if (!s && id >= 1 && id < sizeof(knownmaps)/sizeof(knownmaps[0]))
|
||||
s = MSV_StartSubServer(id, knownmaps[id]);
|
||||
|
||||
return s;
|
||||
return NULL;
|
||||
}
|
||||
pubsubserver_t *MSV_FindSubServerName(const char *mapname)
|
||||
|
||||
//"5" finds server 5 only
|
||||
//"5:dm4" finds server 5, and will start it if not known (even if a different node is running the same map)
|
||||
//"0:dm4" starts a new server running dm4, even if its already running
|
||||
//":dm4" finds any server running dm4. starts a new one if needed.
|
||||
pubsubserver_t *MSV_FindSubServerName(const char *servername)
|
||||
{
|
||||
pubsubserver_t *s;
|
||||
unsigned int to;
|
||||
for (to = 1; to < sizeof(knownmaps)/sizeof(knownmaps[0]); to++)
|
||||
{
|
||||
if (!strcmp(knownmaps[to], mapname))
|
||||
return MSV_FindSubServer(to);
|
||||
}
|
||||
unsigned int id;
|
||||
qboolean forcenew = false;
|
||||
char *mapname;
|
||||
|
||||
for (s = subservers; s; s = s->next)
|
||||
id = strtoul(servername, &mapname, 0);
|
||||
if (*mapname == ':')
|
||||
{
|
||||
if (!strcmp(s->name, mapname))
|
||||
if (!id && servername != mapname)
|
||||
forcenew = true;
|
||||
mapname++;
|
||||
}
|
||||
else
|
||||
mapname = "";
|
||||
|
||||
if (id)
|
||||
{
|
||||
s = MSV_FindSubServer(id);
|
||||
if (s)
|
||||
return s;
|
||||
}
|
||||
|
||||
return MSV_StartSubServer(0, mapname);
|
||||
}
|
||||
qboolean MSV_AddressForMap(netadr_t *ret, int natype, int serverid)
|
||||
{
|
||||
pubsubserver_t *s = MSV_FindSubServer(serverid);
|
||||
if (*mapname)
|
||||
{
|
||||
if (!forcenew)
|
||||
{
|
||||
for (s = subservers; s; s = s->next)
|
||||
{
|
||||
if (!strcmp(s->name, mapname))
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
return MSV_StartSubServer(id, mapname);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
qboolean MSV_AddressForServer(netadr_t *ret, int natype, pubsubserver_t *s)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
if (natype == s->addrv6.type)
|
||||
|
@ -458,7 +469,7 @@ void MSV_ReadFromSubServer(pubsubserver_t *s)
|
|||
send.cursize = 2;
|
||||
|
||||
NET_StringToAdr(claddr, 0, &cladr);
|
||||
MSV_AddressForMap(&svadr, cladr.type, s->id);
|
||||
MSV_AddressForServer(&svadr, cladr.type, s);
|
||||
if (!to)
|
||||
{
|
||||
if (svadr.type != NA_INVALID)
|
||||
|
@ -525,6 +536,13 @@ void MSV_ReadFromSubServer(pubsubserver_t *s)
|
|||
for (s = subservers; s; s = s->next)
|
||||
Sys_InstructSlave(s, &send);
|
||||
}
|
||||
else if (*dest == '\\')
|
||||
{
|
||||
//send to a specific server (backslashes should not be valid in infostrings, and thus not in names.
|
||||
//FIXME: broadcasting for now.
|
||||
for (s = subservers; s; s = s->next)
|
||||
Sys_InstructSlave(s, &send);
|
||||
}
|
||||
else
|
||||
{
|
||||
//send it to the server that the player is currently on.
|
||||
|
@ -940,15 +958,15 @@ qboolean MSV_ClusterLoginReply(netadr_t *legacyclientredirect, unsigned int serv
|
|||
{
|
||||
char tmpbuf[256];
|
||||
netadr_t serveraddr;
|
||||
pubsubserver_t *s = NULL;
|
||||
|
||||
if (!serverid)
|
||||
serverid = 1;
|
||||
if (!s)
|
||||
s = MSV_FindSubServerName(":start");
|
||||
|
||||
if (!MSV_AddressForMap(&serveraddr, clientaddr->type, serverid) && !MSV_AddressForMap(&serveraddr, clientaddr->type, serverid=1))
|
||||
if (!s || !MSV_AddressForServer(&serveraddr, clientaddr->type, s))
|
||||
SV_RejectMessage(SCP_QUAKEWORLD, "Unable to find lobby.\n");
|
||||
else
|
||||
{
|
||||
pubsubserver_t *s;
|
||||
sizebuf_t send;
|
||||
qbyte send_buf[MAX_QWMSGLEN];
|
||||
clusterplayer_t *pl;
|
||||
|
@ -963,7 +981,7 @@ qboolean MSV_ClusterLoginReply(netadr_t *legacyclientredirect, unsigned int serv
|
|||
NET_AdrToString(pl->address, sizeof(pl->address), clientaddr);
|
||||
pl->playerid = playerid;
|
||||
InsertLinkBefore(&pl->allplayers, &clusterplayers);
|
||||
pl->server = s = MSV_FindSubServer(serverid);
|
||||
pl->server = s;
|
||||
|
||||
MSG_WriteByte(&send, ccmd_takeplayer);
|
||||
MSG_WriteLong(&send, playerid);
|
||||
|
|
|
@ -3764,41 +3764,42 @@ void SV_SetInfo_f (void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (Cmd_Argv(1)[0] == '*')
|
||||
key = Cmd_Argv(1);
|
||||
|
||||
if (key[0] == '*')
|
||||
return; // don't set priveledged values
|
||||
|
||||
if (strstr(Cmd_Argv(1), "\\") || strstr(Cmd_Argv(2), "\\"))
|
||||
if (strstr(key, "\\") || strstr(Cmd_Argv(2), "\\"))
|
||||
return; // illegal char
|
||||
|
||||
Q_strncpyz(oldval, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)), sizeof(oldval));
|
||||
Q_strncpyz(oldval, Info_ValueForKey(host_client->userinfo, key), sizeof(oldval));
|
||||
|
||||
#ifdef VM_Q1
|
||||
if (Q1QVM_UserInfoChanged(sv_player))
|
||||
return;
|
||||
#endif
|
||||
|
||||
Info_SetValueForKey (host_client->userinfo, Cmd_Argv(1), Cmd_Argv(2), sizeof(host_client->userinfo));
|
||||
Info_SetValueForKey (host_client->userinfo, key, Cmd_Argv(2), sizeof(host_client->userinfo));
|
||||
// name is extracted below in ExtractFromUserInfo
|
||||
// strncpy (host_client->name, Info_ValueForKey (host_client->userinfo, "name")
|
||||
// , sizeof(host_client->name)-1);
|
||||
// SV_FullClientUpdate (host_client, &sv.reliable_datagram);
|
||||
// host_client->sendinfo = true;
|
||||
|
||||
if (!strcmp(Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)), oldval))
|
||||
if (!strcmp(Info_ValueForKey(host_client->userinfo, key), oldval))
|
||||
return; // key hasn't changed
|
||||
|
||||
// process any changed values
|
||||
SV_ExtractFromUserinfo (host_client, true);
|
||||
|
||||
if (progstype != PROG_QW && !strcmp(Cmd_Argv(1), "bottomcolor"))
|
||||
if (progstype != PROG_QW && !strcmp(key, "bottomcolor"))
|
||||
{ //team fortress has a nasty habit of booting people without this
|
||||
sv_player->v->team = atoi(Cmd_Argv(2))+1;
|
||||
}
|
||||
|
||||
if (*Cmd_Argv(1) != '_')
|
||||
if (*key != '_')
|
||||
{
|
||||
i = host_client - svs.clients;
|
||||
key = Cmd_Argv(1);
|
||||
val = Info_ValueForKey(host_client->userinfo, key);
|
||||
|
||||
basic = SV_UserInfoIsBasic(key);
|
||||
|
@ -3845,9 +3846,11 @@ void SV_SetInfo_f (void)
|
|||
}
|
||||
}
|
||||
|
||||
SV_LogPlayer(host_client, "userinfo changed");
|
||||
//doh't spam chat changes. they're not interesting, and just spammy.
|
||||
if (strcmp(key, "chat"))
|
||||
SV_LogPlayer(host_client, "userinfo changed");
|
||||
|
||||
PR_ClientUserInfoChanged(Cmd_Argv(1), oldval, Info_ValueForKey(host_client->userinfo, Cmd_Argv(1)));
|
||||
PR_ClientUserInfoChanged(key, oldval, Info_ValueForKey(host_client->userinfo, key));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -74,12 +74,10 @@ static qboolean QDECL VFSWEB_ClosePersist(vfsfile_t *file)
|
|||
return VFSWEB_Close(file);
|
||||
}
|
||||
|
||||
vfsfile_t *FSWEB_OpenTemp(void)
|
||||
vfsfile_t *FSWEB_OpenTempHandle(int f)
|
||||
{
|
||||
int f;
|
||||
vfswebfile_t *file;
|
||||
|
||||
f = emscriptenfte_buf_create();
|
||||
if (f == -1)
|
||||
{
|
||||
Con_Printf("FSWEB_OpenTemp failed\n");
|
||||
|
@ -102,6 +100,11 @@ vfsfile_t *FSWEB_OpenTemp(void)
|
|||
return &file->funcs;
|
||||
}
|
||||
|
||||
vfsfile_t *FSWEB_OpenTemp(void)
|
||||
{
|
||||
return FSWEB_OpenTempHandle(emscriptenfte_buf_create());
|
||||
}
|
||||
|
||||
vfsfile_t *VFSWEB_Open(const char *osname, const char *mode, qboolean *needsflush)
|
||||
{
|
||||
int f;
|
||||
|
|
|
@ -36,6 +36,6 @@ int emscriptenfte_setupcanvas(
|
|||
void(*Mouse)(int devid,int abs,float x,float y,float z,float size),
|
||||
void(*Button)(int devid, int down, int mbutton),
|
||||
int(*Keyboard)(int devid, int down, int keycode, int unicode),
|
||||
void(*Hash)(char *newhash)
|
||||
void(*LoadFile)(char *newhash, int filehandle)
|
||||
);
|
||||
|
||||
|
|
|
@ -29,6 +29,33 @@ mergeInto(LibraryManager.library,
|
|||
alert(msg);
|
||||
},
|
||||
|
||||
emscriptenfte_handle_alloc__deps : ['$FTEH'],
|
||||
emscriptenfte_handle_alloc : function(h)
|
||||
{
|
||||
for (var i = 0; FTEH.h.length; i+=1)
|
||||
{
|
||||
if (FTEH.h[i] == null)
|
||||
{
|
||||
FTEH.h[i] = h;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
i = FTEH.h.length;
|
||||
FTEH.h[i] = h;
|
||||
return i;
|
||||
},
|
||||
|
||||
//temp files
|
||||
emscriptenfte_buf_createfromarraybuf__deps : ['emscriptenfte_handle_alloc'],
|
||||
emscriptenfte_buf_createfromarraybuf : function(buf)
|
||||
{
|
||||
var len = buf.length;
|
||||
var b = {h:-1, r:1, l:len,m:len,d:new Uint8Array(buf), n:null};
|
||||
b.h = _emscriptenfte_handle_alloc(b);
|
||||
return b.h;
|
||||
},
|
||||
|
||||
$FTEC__deps : ['emscriptenfte_buf_createfromarraybuf'],
|
||||
$FTEC:
|
||||
{
|
||||
ctxwarned:0,
|
||||
|
@ -42,6 +69,20 @@ mergeInto(LibraryManager.library,
|
|||
key:0
|
||||
},
|
||||
|
||||
loadurl : function(url, arraybuf)
|
||||
{
|
||||
if (FTEC.evcb.loadfile != 0)
|
||||
{
|
||||
var handle = -1;
|
||||
if (arraybuf !== undefined)
|
||||
handle = _emscriptenfte_buf_createfromarraybuf(arraybuf);
|
||||
var ptr = _malloc(url.length);
|
||||
writeStringToMemory(url, ptr);
|
||||
Runtime.dynCall('vii', FTEC.evcb.loadfile, [ptr, handle]);
|
||||
_free(ptr);
|
||||
}
|
||||
},
|
||||
|
||||
handleevent : function(event)
|
||||
{
|
||||
switch(event.type)
|
||||
|
@ -138,28 +179,49 @@ mergeInto(LibraryManager.library,
|
|||
}
|
||||
event.preventDefault();
|
||||
break;
|
||||
case 'dragenter':
|
||||
case 'dragover':
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
break;
|
||||
case 'drop':
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
var files = event.dataTransfer.files;
|
||||
for (var i = 0; i < files.length; i++)
|
||||
{
|
||||
var file = files[i];
|
||||
var reader = new FileReader();
|
||||
reader.onload = function(evt)
|
||||
{
|
||||
FTEC.loadurl(file.name, evt.target.result);
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
console.log(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser'],
|
||||
emscriptenfte_setupcanvas : function(nw,nh,evresz,evm,evb,evk,evh)
|
||||
emscriptenfte_setupcanvas__deps: ['$FTEC', '$Browser', 'emscriptenfte_buf_createfromarraybuf'],
|
||||
emscriptenfte_setupcanvas : function(nw,nh,evresz,evm,evb,evk,evf)
|
||||
{
|
||||
FTEC.evcb.resize = evresz;
|
||||
FTEC.evcb.mouse = evm;
|
||||
FTEC.evcb.button = evb;
|
||||
FTEC.evcb.key = evk;
|
||||
FTEC.evcb.hashchange = evh;
|
||||
FTEC.evcb.loadfile = evf;
|
||||
if (!FTEC.donecb)
|
||||
{
|
||||
FTEC.donecb = 1;
|
||||
['mousedown', 'mouseup', 'mousemove', 'wheel', 'mousewheel', 'mouseout', 'keypress', 'keydown', 'keyup', 'touchstart', 'touchend', 'touchcancel', 'touchleave', 'touchmove'].forEach(function(event)
|
||||
var events = ['mousedown', 'mouseup', 'mousemove', 'wheel', 'mousewheel', 'mouseout', 'keypress', 'keydown', 'keyup', 'touchstart', 'touchend', 'touchcancel', 'touchleave', 'touchmove', 'dragenter', 'dragover', 'drop'];
|
||||
events.forEach(function(event)
|
||||
{
|
||||
Module['canvas'].addEventListener(event, FTEC.handleevent, true);
|
||||
});
|
||||
['keydown', 'keyup', 'keypress'].forEach(function(event)
|
||||
events.forEach(function(event)
|
||||
{
|
||||
document.addEventListener(event, FTEC.handleevent, true);
|
||||
});
|
||||
|
@ -172,7 +234,7 @@ mergeInto(LibraryManager.library,
|
|||
}
|
||||
if (Module.print === undefined)
|
||||
Module.print = function(msg){console.log(msg);};
|
||||
var ctx = Browser.createContext(Module['canvas'], true, true);
|
||||
var ctx = Browser.createContext(Module['canvas'], true, true);
|
||||
if (ctx == null)
|
||||
{
|
||||
var msg = "Unable to set up webgl context.\n\nPlease use a browser that supports it and has it enabled\nYour graphics drivers may also be blacklisted, so try updating those too. woo, might as well update your entire operating system while you're at it.\nIt'll be expensive, but hey, its YOUR money, not mine.\nYou can probably just disable the blacklist, but please don't moan at me when your computer blows up, seriously, make sure those drivers are not too buggy.\nI knew a guy once. True story. Boring, but true.\nYou're probably missing out on something right now. Don't you just hate it when that happens?\nMeh, its probably just tinkertoys, right?\n\nYou know, you could always try Internet Explorer, you never know, hell might have frozen over.\nDon't worry, I wasn't serious.\n\nTum te tum. Did you get it working yet?\nDude, fix it already.\n\nThis message was brought to you by Sleep Deprivation, sponsoring quake since I don't know when";
|
||||
|
@ -202,17 +264,12 @@ mergeInto(LibraryManager.library,
|
|||
window.onresize();
|
||||
|
||||
if (FTEC.evcb.hashchange)
|
||||
window.onhashchange = function()
|
||||
{
|
||||
if (FTEC.evcb.hashchange != 0)
|
||||
window.onhashchange = function()
|
||||
{
|
||||
var val = location.hash;
|
||||
var ptr = _malloc(val.length);
|
||||
writeStringToMemory(val, ptr);
|
||||
Runtime.dynCall('vi', FTEC.evcb.hashchange, [ptr]);
|
||||
_free(ptr);
|
||||
}
|
||||
};
|
||||
FTEC.loadurl(location.hash.substring(1));
|
||||
};
|
||||
}
|
||||
|
||||
return 1;
|
||||
},
|
||||
|
@ -228,23 +285,6 @@ mergeInto(LibraryManager.library,
|
|||
return Date.now();
|
||||
},
|
||||
|
||||
emscriptenfte_handle_alloc__deps : ['$FTEH'],
|
||||
emscriptenfte_handle_alloc : function(h)
|
||||
{
|
||||
for (var i = 0; FTEH.h.length; i+=1)
|
||||
{
|
||||
if (FTEH.h[i] == null)
|
||||
{
|
||||
FTEH.h[i] = h;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
i = FTEH.h.length;
|
||||
FTEH.h[i] = h;
|
||||
return i;
|
||||
},
|
||||
|
||||
//temp files
|
||||
emscriptenfte_buf_create__deps : ['emscriptenfte_handle_alloc'],
|
||||
emscriptenfte_buf_create : function()
|
||||
{
|
||||
|
@ -481,7 +521,7 @@ mergeInto(LibraryManager.library,
|
|||
|
||||
http.onload = function(e)
|
||||
{
|
||||
// console.log("onload: " + _url + " status " + http.status);
|
||||
console.log("onload: " + _url + " status " + http.status);
|
||||
if (http.status == 200)
|
||||
{
|
||||
var bar = new Uint8Array(http.response);
|
||||
|
@ -499,7 +539,7 @@ mergeInto(LibraryManager.library,
|
|||
|
||||
http.onerror = function(e)
|
||||
{
|
||||
// console.log("onerror: " + _url + " status " + http.status);
|
||||
console.log("onerror: " + _url + " status " + http.status);
|
||||
if (onerror)
|
||||
Runtime.dynCall('vii', onerror, [ctx, http.status]);
|
||||
};
|
||||
|
|
|
@ -151,15 +151,22 @@ static void DOM_ButtonEvent(int devid, int down, int button)
|
|||
IN_KeyEvent(devid, down, K_MOUSE1+button, 0);
|
||||
}
|
||||
}
|
||||
void DOM_HashChanged(char *loc)
|
||||
vfsfile_t *FSWEB_OpenTempHandle(int f);
|
||||
void DOM_LoadFile(char *loc, int handle)
|
||||
{
|
||||
vfsfile_t *file = NULL;
|
||||
Con_Printf("DOM_LoadFile: %s %i\n", loc, handle);
|
||||
if (handle != -1)
|
||||
file = FSWEB_OpenTempHandle(handle);
|
||||
//try and open it. generally downloading it from the server.
|
||||
Host_RunFile(loc+1, strlen(loc+1), NULL);
|
||||
if (!Host_RunFile(loc, strlen(loc), file))
|
||||
{
|
||||
if (file)
|
||||
VFS_CLOSE(file);
|
||||
}
|
||||
}
|
||||
qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
||||
{
|
||||
int flags;
|
||||
|
||||
vid_isfullscreen = true;
|
||||
|
||||
if (!emscriptenfte_setupcanvas(
|
||||
|
@ -169,7 +176,7 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette)
|
|||
IN_MouseMove,
|
||||
DOM_ButtonEvent,
|
||||
DOM_KeyEvent,
|
||||
DOM_HashChanged
|
||||
DOM_LoadFile
|
||||
))
|
||||
{
|
||||
Con_Printf("Couldn't set up canvas\n");
|
||||
|
|
Loading…
Reference in a new issue