playdemo should now play older protocol versions.
some more tweaks for xonotic rcon-over-xmpp, because I can. Server might see your rcon password, so watch out for that. qcc tweaks. updated q1qvm api stuff to api version 15. android port updated. egl now handled by native code, which means we now have proper control over everything and can default to gles2. requires android 2.0+. vulkan-on-android renderer added, but not tested. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5153 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
8e44dde063
commit
696c7e8260
50 changed files with 4017 additions and 1879 deletions
|
@ -591,7 +591,7 @@ qboolean CL_GetDemoMessage (void)
|
|||
|
||||
if (msglength > net_message.maxsize)
|
||||
{
|
||||
Con_Printf ("Demo message > MAX_MSGLEN");
|
||||
Con_Printf ("Demo message > MAX_MSGLEN\n");
|
||||
CL_StopPlayback ();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -4606,7 +4606,7 @@ void CL_ParsePlayerinfo (void)
|
|||
|
||||
if (flags & PF_COMMAND)
|
||||
{
|
||||
MSG_ReadDeltaUsercmd (&nullcmd, &state->command);
|
||||
MSG_ReadDeltaUsercmd (&nullcmd, &state->command, cl.protocol_qw);
|
||||
|
||||
state->viewangles[0] = state->command.angles[0] * (360.0/65536);
|
||||
state->viewangles[1] = state->command.angles[1] * (360.0/65536);
|
||||
|
|
|
@ -1613,6 +1613,7 @@ void CL_ClearState (void)
|
|||
CL_ResetFog(0);
|
||||
CL_ResetFog(1);
|
||||
|
||||
cl.protocol_qw = PROTOCOL_VERSION_QW; //until we get an svc_serverdata
|
||||
cl.allocated_client_slots = QWMAX_CLIENTS;
|
||||
#ifndef CLIENTONLY
|
||||
//FIXME: we should just set it to 0 to make sure its set up properly elsewhere.
|
||||
|
@ -5964,6 +5965,7 @@ void CL_ExecInitialConfigs(char *resetcommand)
|
|||
|
||||
void Host_FinishLoading(void)
|
||||
{
|
||||
extern qboolean r_forceheadless;
|
||||
extern int r_blockvidrestart;
|
||||
if (r_blockvidrestart == true)
|
||||
{
|
||||
|
@ -6016,12 +6018,9 @@ void Host_FinishLoading(void)
|
|||
if (PM_IsApplying(true))
|
||||
return;
|
||||
|
||||
#ifdef ANDROID
|
||||
//android needs to wait a bit longer before it's allowed to init its video properly.
|
||||
extern int sys_glesversion;
|
||||
if (!sys_glesversion)
|
||||
//android may find that it has no renderer at various points.
|
||||
if (r_forceheadless)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (r_blockvidrestart == 2)
|
||||
{ //2 is part of the initial startup
|
||||
|
|
|
@ -3101,6 +3101,7 @@ static void CLQW_ParseServerData (void)
|
|||
Stats_NewMap();
|
||||
#endif
|
||||
cl.servercount = svcnt;
|
||||
cl.protocol_qw = protover;
|
||||
|
||||
Cvar_ForceCallback(Cvar_FindVar("r_particlesdesc"));
|
||||
|
||||
|
@ -3216,17 +3217,33 @@ static void CLQW_ParseServerData (void)
|
|||
str = MSG_ReadString ();
|
||||
Q_strncpyz (cl.levelname, str, sizeof(cl.levelname));
|
||||
|
||||
// get the movevars
|
||||
movevars.gravity = MSG_ReadFloat();
|
||||
movevars.stopspeed = MSG_ReadFloat();
|
||||
maxspeed = MSG_ReadFloat();
|
||||
movevars.spectatormaxspeed = MSG_ReadFloat();
|
||||
movevars.accelerate = MSG_ReadFloat();
|
||||
movevars.airaccelerate = MSG_ReadFloat();
|
||||
movevars.wateraccelerate = MSG_ReadFloat();
|
||||
movevars.friction = MSG_ReadFloat();
|
||||
movevars.waterfriction = MSG_ReadFloat();
|
||||
entgrav = MSG_ReadFloat();
|
||||
if (cl.protocol_qw >= 25)
|
||||
{
|
||||
// get the movevars
|
||||
movevars.gravity = MSG_ReadFloat();
|
||||
movevars.stopspeed = MSG_ReadFloat();
|
||||
maxspeed = MSG_ReadFloat();
|
||||
movevars.spectatormaxspeed = MSG_ReadFloat();
|
||||
movevars.accelerate = MSG_ReadFloat();
|
||||
movevars.airaccelerate = MSG_ReadFloat();
|
||||
movevars.wateraccelerate = MSG_ReadFloat();
|
||||
movevars.friction = MSG_ReadFloat();
|
||||
movevars.waterfriction = MSG_ReadFloat();
|
||||
entgrav = MSG_ReadFloat();
|
||||
}
|
||||
else
|
||||
{
|
||||
movevars.gravity = 800;
|
||||
movevars.stopspeed = 100;
|
||||
maxspeed = 320;
|
||||
movevars.spectatormaxspeed = 500;
|
||||
movevars.accelerate = 10;
|
||||
movevars.airaccelerate = 0.7f;
|
||||
movevars.wateraccelerate = 10;
|
||||
movevars.friction = 6.0f;
|
||||
movevars.waterfriction = 1;
|
||||
entgrav = 1;
|
||||
}
|
||||
|
||||
for (clnum = 0; clnum < cl.splitclients; clnum++)
|
||||
{
|
||||
|
@ -3973,7 +3990,7 @@ static void CL_ParseSoundlist (qboolean lots)
|
|||
if (lots)
|
||||
numsounds = MSG_ReadShort();
|
||||
else
|
||||
numsounds = MSG_ReadByte();
|
||||
numsounds = (cl.protocol_qw>=26)?MSG_ReadByte():0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -3991,7 +4008,7 @@ static void CL_ParseSoundlist (qboolean lots)
|
|||
strcpy (cl.sound_name[numsounds], str);
|
||||
}
|
||||
|
||||
n = MSG_ReadByte();
|
||||
n = (cl.protocol_qw>=26)?MSG_ReadByte():0;
|
||||
|
||||
if (n)
|
||||
{
|
||||
|
@ -4047,7 +4064,7 @@ static void CL_ParseModellist (qboolean lots)
|
|||
if (lots)
|
||||
nummodels = MSG_ReadShort();
|
||||
else
|
||||
nummodels = MSG_ReadByte();
|
||||
nummodels = (cl.protocol_qw>=26)?MSG_ReadByte():0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
|
@ -4089,7 +4106,7 @@ static void CL_ParseModellist (qboolean lots)
|
|||
if (nummodels)
|
||||
SCR_ImageName(cl.model_name[1]);
|
||||
|
||||
n = MSG_ReadByte();
|
||||
n = (cl.protocol_qw>=26)?MSG_ReadByte():0;
|
||||
|
||||
if (n)
|
||||
{
|
||||
|
|
|
@ -2810,6 +2810,8 @@ static void SCR_ScreenShot_VR_f(void)
|
|||
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
|
||||
|
||||
//FIXME: it should be possible to do this more inteligently, and get both strips with a single render.
|
||||
//FIXME: we should render to a PBO instead, so that the gpu+cpu don't need to sync until the very end.
|
||||
//FIXME: we should be using scissoring to avoid redrawing the entire screen (also tweak cull planes)
|
||||
|
||||
ang = M_PI*2*(baseang[1]/360.0 + (lx+0.5*(rx-lx))/width);
|
||||
r_refdef.eyeoffset[0] = sin(ang) * r_stereo_separation.value * 0.5;
|
||||
|
|
|
@ -440,10 +440,10 @@ typedef struct
|
|||
|
||||
/*QuakeWorld protocol flags*/
|
||||
#ifdef PROTOCOLEXTENSIONS
|
||||
unsigned long fteprotocolextensions;
|
||||
unsigned long fteprotocolextensions2;
|
||||
unsigned int fteprotocolextensions;
|
||||
unsigned int fteprotocolextensions2;
|
||||
#endif
|
||||
unsigned long z_ext;
|
||||
unsigned int z_ext;
|
||||
|
||||
/*NQ Protocol flags*/
|
||||
enum
|
||||
|
@ -453,7 +453,7 @@ typedef struct
|
|||
CPNQ_BJP1, //16bit models, strict 8bit sounds (otherwise based on nehahra)
|
||||
CPNQ_BJP2, //16bit models, strict 16bit sounds
|
||||
CPNQ_BJP3, //16bit models, flagged 16bit sounds, 8bit static sounds.
|
||||
CPNQ_FITZ666, /*and rmqe999 protocol*/
|
||||
CPNQ_FITZ666, /*and rmqe999 protocol, which is a strict superset*/
|
||||
CPNQ_DP5,
|
||||
CPNQ_DP6,
|
||||
CPNQ_DP7
|
||||
|
@ -739,6 +739,8 @@ typedef struct
|
|||
int fpd;
|
||||
int servercount; // server identification for prespawns
|
||||
|
||||
int protocol_qw;
|
||||
|
||||
float gamespeed;
|
||||
qboolean csqcdebug;
|
||||
qboolean allowsendpacket;
|
||||
|
|
|
@ -980,6 +980,7 @@ extern redirect_t sv_redirected;
|
|||
extern char sv_redirected_buf[8000];
|
||||
void SV_FlushRedirect (void);
|
||||
#endif
|
||||
vfsfile_t *con_pipe;
|
||||
|
||||
#define MAXPRINTMSG 4096
|
||||
static void Con_PrintFromThread (void *ctx, void *data, size_t a, size_t b)
|
||||
|
@ -988,6 +989,18 @@ static void Con_PrintFromThread (void *ctx, void *data, size_t a, size_t b)
|
|||
BZ_Free(data);
|
||||
}
|
||||
|
||||
vfsfile_t *Con_POpen(char *conname)
|
||||
{
|
||||
if (!conname || !*conname)
|
||||
{
|
||||
if (con_pipe)
|
||||
VFS_CLOSE(con_pipe);
|
||||
con_pipe = VFSPIPE_Open(2, false);
|
||||
return con_pipe;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: make a buffer size safe vsprintf?
|
||||
void VARGS Con_Printf (const char *fmt, ...)
|
||||
{
|
||||
|
@ -1021,6 +1034,9 @@ void VARGS Con_Printf (const char *fmt, ...)
|
|||
// log all messages to file
|
||||
Con_Log (msg);
|
||||
|
||||
if (con_pipe)
|
||||
VFS_PUTS(con_pipe, msg);
|
||||
|
||||
if (!con_initialized)
|
||||
return;
|
||||
|
||||
|
@ -1029,7 +1045,7 @@ void VARGS Con_Printf (const char *fmt, ...)
|
|||
}
|
||||
|
||||
void VARGS Con_SafePrintf (const char *fmt, ...)
|
||||
{
|
||||
{ //obsolete version of the function
|
||||
va_list argptr;
|
||||
char msg[MAXPRINTMSG];
|
||||
|
||||
|
|
|
@ -1741,6 +1741,12 @@ static void QCBUILTIN PF_cs_project (pubprogfuncs_t *prinst, struct globalvars_s
|
|||
out[0] = out[0]*r_refdef.vrect.width + r_refdef.vrect.x;
|
||||
out[1] = out[1]*r_refdef.vrect.height + r_refdef.vrect.y;
|
||||
|
||||
if (csqc_isdarkplaces)
|
||||
{
|
||||
out[0] *= (float)vid.pixelwidth / vid.width;
|
||||
out[1] *= (float)vid.pixelheight / vid.height;
|
||||
}
|
||||
|
||||
if (tempv[3] < 0)
|
||||
out[2] *= -1;
|
||||
}
|
||||
|
@ -1753,12 +1759,18 @@ static void QCBUILTIN PF_cs_unproject (pubprogfuncs_t *prinst, struct globalvars
|
|||
{
|
||||
float *in = G_VECTOR(OFS_PARM0);
|
||||
float *out = G_VECTOR(OFS_RETURN);
|
||||
float tx, ty;
|
||||
float tx = in[0], ty = in[1];
|
||||
|
||||
float v[4], tempv[4];
|
||||
|
||||
tx = ((in[0]-r_refdef.vrect.x)/r_refdef.vrect.width);
|
||||
ty = ((in[1]-r_refdef.vrect.y)/r_refdef.vrect.height);
|
||||
if (csqc_isdarkplaces)
|
||||
{
|
||||
tx *= (float)vid.width / vid.pixelwidth;
|
||||
ty *= (float)vid.height / vid.pixelheight;
|
||||
}
|
||||
|
||||
tx = ((tx-r_refdef.vrect.x)/r_refdef.vrect.width);
|
||||
ty = ((ty-r_refdef.vrect.y)/r_refdef.vrect.height);
|
||||
ty = 1-ty;
|
||||
v[0] = tx*2-1;
|
||||
v[1] = ty*2-1;
|
||||
|
|
|
@ -16,6 +16,7 @@ vec3_t r_origin, vpn, vright, vup;
|
|||
entity_t r_worldentity;
|
||||
entity_t *currententity; //nnggh
|
||||
int r_framecount;
|
||||
qboolean r_forceheadless;
|
||||
struct texture_s *r_notexture_mip;
|
||||
|
||||
int r_blockvidrestart; //'block' is a bit of a misnomer. 0=filesystem, configs, cinematics, video are all okay as they are. 1=starting up, waiting for filesystem, will restart after. 2=configs execed, but still need cinematics. 3=video will be restarted without any other init needed
|
||||
|
@ -301,8 +302,11 @@ extern cvar_t r_novis;
|
|||
extern cvar_t r_speeds;
|
||||
extern cvar_t r_waterwarp;
|
||||
|
||||
cvar_t r_polygonoffset_submodel_factor = CVAR("r_polygonoffset_submodel_factor", "0");
|
||||
cvar_t r_polygonoffset_submodel_offset = CVAR("r_polygonoffset_submodel_offset", "0");
|
||||
#ifdef BEF_PUSHDEPTH
|
||||
cvar_t r_polygonoffset_submodel_factor = CVARD("r_polygonoffset_submodel_factor", "0", "z-fighting avoidance. Pushes submodel depth values slightly towards the camera depending on the slope of the surface.");
|
||||
cvar_t r_polygonoffset_submodel_offset = CVARD("r_polygonoffset_submodel_offset", "0", "z-fighting avoidance. Pushes submodel depth values slightly towards the camera by a consistent distance.");
|
||||
cvar_t r_polygonoffset_submodel_maps = CVARD("r_polygonoffset_submodel_map", "e?m? r?m? hip?m?", "List of maps on which z-fighting reduction should be used. wildcards accepted.");
|
||||
#endif
|
||||
cvar_t r_polygonoffset_shadowmap_offset = CVAR("r_polygonoffset_shadowmap_factor", "0.05");
|
||||
cvar_t r_polygonoffset_shadowmap_factor = CVAR("r_polygonoffset_shadowmap_offset", "0");
|
||||
|
||||
|
@ -329,7 +333,7 @@ cvar_t gl_ati_truform_type = CVAR ("gl_ati_truform_type", "1");
|
|||
cvar_t r_tessellation_level = CVAR ("r_tessellation_level", "5");
|
||||
cvar_t gl_blend2d = CVAR ("gl_blend2d", "1");
|
||||
cvar_t gl_blendsprites = CVARD ("gl_blendsprites", "0", "Blend sprites instead of alpha testing them");
|
||||
cvar_t r_deluxmapping_cvar = CVARAFD ("r_deluxmapping", "0", "r_deluxemapping", //fixme: rename to r_glsl_deluxmapping once configs catch up
|
||||
cvar_t r_deluxmapping_cvar = CVARAFD ("r_deluxemapping", "0", "r_glsl_deluxemapping",
|
||||
CVAR_ARCHIVE, "Enables bumpmapping based upon precomputed light directions.\n0=off\n1=use if available\n2=auto-generate (if possible)");
|
||||
qboolean r_deluxmapping;
|
||||
cvar_t r_shaderblobs = CVARD ("r_shaderblobs", "0", "If enabled, can massively accelerate vid restarts / loading (especially with the d3d renderer). Can cause issues when upgrading engine versions, so this is disabled by default.");
|
||||
|
@ -375,10 +379,11 @@ cvar_t gl_savecompressedtex = CVARD ("gl_savecompressedtex", "0", "Write ou
|
|||
//cvar_t gl_schematics = CVARD ("gl_schematics", "0", "Gimmick rendering mode that draws the length of various world edges.");
|
||||
cvar_t gl_skyboxdist = CVARD ("gl_skyboxdist", "0", "The distance of the skybox. If 0, the engine will determine it based upon the far clip plane distance."); //0 = guess.
|
||||
cvar_t gl_smoothcrosshair = CVAR ("gl_smoothcrosshair", "1");
|
||||
cvar_t gl_maxdist = CVARD ("gl_maxdist", "0", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
|
||||
cvar_t gl_maxdist = CVARAD ("gl_maxdist", "0", "gl_farclip", "The distance of the far clip plane. If set to 0, some fancy maths will be used to place it at an infinite distance.");
|
||||
|
||||
#ifdef SPECULAR
|
||||
cvar_t gl_specular = CVARF ("gl_specular", "0.3", CVAR_ARCHIVE);
|
||||
cvar_t gl_specular = CVARF ("gl_specular", "0.3", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
|
||||
cvar_t gl_specular_power = CVARF ("gl_specular_power", "32", CVAR_ARCHIVE|CVAR_SHADERSYSTEM);
|
||||
cvar_t gl_specular_fallback = CVARF ("gl_specular_fallback", "0.05", CVAR_ARCHIVE|CVAR_RENDERERLATCH);
|
||||
cvar_t gl_specular_fallbackexp = CVARF ("gl_specular_fallbackexp", "1", CVAR_ARCHIVE|CVAR_RENDERERLATCH);
|
||||
#endif
|
||||
|
@ -836,6 +841,7 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&r_flashblend, GRAPHICALNICETIES);
|
||||
Cvar_Register (&r_flashblendscale, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_specular, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_specular_power, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_specular_fallback, GRAPHICALNICETIES);
|
||||
Cvar_Register (&gl_specular_fallbackexp, GRAPHICALNICETIES);
|
||||
|
||||
|
@ -957,9 +963,10 @@ void Renderer_Init(void)
|
|||
Cvar_Register (&r_showbboxes, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_showfields, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_showshaders, GLRENDEREROPTIONS);
|
||||
#ifndef NOLEGACY
|
||||
#ifdef BEF_PUSHDEPTH
|
||||
Cvar_Register (&r_polygonoffset_submodel_factor, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_polygonoffset_submodel_offset, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_polygonoffset_submodel_maps, GLRENDEREROPTIONS);
|
||||
#endif
|
||||
Cvar_Register (&r_polygonoffset_shadowmap_factor, GLRENDEREROPTIONS);
|
||||
Cvar_Register (&r_polygonoffset_shadowmap_offset, GLRENDEREROPTIONS);
|
||||
|
@ -1132,7 +1139,7 @@ extern rendererinfo_t nvvkrendererinfo;
|
|||
extern rendererinfo_t headlessrenderer;
|
||||
#endif
|
||||
|
||||
rendererinfo_t *rendererinfo[] =
|
||||
rendererinfo_t *rendererinfo[16] =
|
||||
{
|
||||
#ifdef GLQUAKE
|
||||
#ifdef FTE_RPI
|
||||
|
@ -1174,6 +1181,24 @@ rendererinfo_t *rendererinfo[] =
|
|||
#endif
|
||||
};
|
||||
|
||||
void R_RegisterRenderer(rendererinfo_t *ri)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
{ //already registered
|
||||
if (rendererinfo[i] == ri)
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
{ //register it in the first empty slot
|
||||
if (!rendererinfo[i])
|
||||
{
|
||||
rendererinfo[i] = ri;
|
||||
return;
|
||||
}
|
||||
}
|
||||
Sys_Printf("unable to register renderer %s\n", ri->description);
|
||||
}
|
||||
|
||||
void R_SetRenderer(rendererinfo_t *ri)
|
||||
{
|
||||
|
@ -1353,7 +1378,8 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
|
|||
isDedicated = false;
|
||||
#endif
|
||||
if (newr)
|
||||
Con_TPrintf("Setting mode %i*%i*%i*%i %s\n", newr->width, newr->height, newr->bpp, newr->rate, newr->renderer->description);
|
||||
if (!r_forceheadless || newr->renderer->rtype != QR_HEADLESS)
|
||||
Con_TPrintf("Setting mode %i*%i*%i*%i %s\n", newr->width, newr->height, newr->bpp, newr->rate, newr->renderer->description);
|
||||
|
||||
vid.fullbright=0;
|
||||
|
||||
|
@ -1674,7 +1700,8 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n"));
|
|||
|
||||
if (newr && qrenderer != QR_NONE)
|
||||
{
|
||||
Con_TPrintf("%s renderer initialized\n", newr->renderer->description);
|
||||
if (!r_forceheadless || newr->renderer->rtype != QR_HEADLESS)
|
||||
Con_TPrintf("%s renderer initialized\n", newr->renderer->description);
|
||||
}
|
||||
|
||||
TRACE(("dbg: R_ApplyRenderer: done\n"));
|
||||
|
@ -1728,11 +1755,22 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
newr->renderer = NULL;
|
||||
|
||||
rendererstring = COM_Parse(rendererstring);
|
||||
if (!*com_token)
|
||||
if (r_forceheadless)
|
||||
{ //special hack so that android doesn't weird out when not focused.
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
{
|
||||
if (rendererinfo[i] && rendererinfo[i]->name[0] && !stricmp(rendererinfo[i]->name[0], "headless"))
|
||||
{
|
||||
newr->renderer = rendererinfo[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!*com_token)
|
||||
{
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
{
|
||||
if (rendererinfo[i]->name[0] && stricmp(rendererinfo[i]->name[0], "none"))
|
||||
if (rendererinfo[i] && rendererinfo[i]->name[0] && stricmp(rendererinfo[i]->name[0], "none"))
|
||||
{
|
||||
newr->renderer = rendererinfo[i];
|
||||
break;
|
||||
|
@ -1744,7 +1782,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
int count;
|
||||
for (i = 0, count = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
{
|
||||
if (!rendererinfo[i]->description)
|
||||
if (!rendererinfo[i] || !rendererinfo[i]->description)
|
||||
continue; //not valid in this build. :(
|
||||
if (rendererinfo[i]->rtype == QR_NONE || //dedicated servers are not useful
|
||||
rendererinfo[i]->rtype == QR_HEADLESS || //headless appears buggy
|
||||
|
@ -1755,7 +1793,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
count = rand()%count;
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
{
|
||||
if (!rendererinfo[i]->description)
|
||||
if (!rendererinfo[i] || !rendererinfo[i]->description)
|
||||
continue; //not valid in this build. :(
|
||||
if (rendererinfo[i]->rtype == QR_NONE ||
|
||||
rendererinfo[i]->rtype == QR_HEADLESS ||
|
||||
|
@ -1773,7 +1811,7 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
|
|||
{
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
{
|
||||
if (!rendererinfo[i]->description)
|
||||
if (!rendererinfo[i] || !rendererinfo[i]->description)
|
||||
continue; //not valid in this build. :(
|
||||
for (j = 4-1; j >= 0; j--)
|
||||
{
|
||||
|
@ -1954,7 +1992,7 @@ void R_SetRenderer_f (void)
|
|||
Con_Printf ("\nValid setrenderer parameters are:\n");
|
||||
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
|
||||
{
|
||||
if (rendererinfo[i]->description)
|
||||
if (rendererinfo[i] && rendererinfo[i]->description)
|
||||
Con_Printf("^[%s\\type\\/setrenderer %s^]^7: %s%s\n", rendererinfo[i]->name[0], rendererinfo[i]->name[0], rendererinfo[i]->description, (currentrendererstate.renderer == rendererinfo[i])?" ^2(current)":"");
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -162,7 +162,7 @@ fte_inline conchar_t *Font_Decode(conchar_t *start, unsigned int *codeflags, uns
|
|||
if (*start & CON_LONGCHAR)
|
||||
if (!(*start & CON_RICHFORECOLOUR))
|
||||
{
|
||||
*codeflags = start[1];
|
||||
*codeflags = start[1] & CON_FLAGSMASK;
|
||||
*codepoint = ((start[0] & CON_CHARMASK)<<16) | (start[1] & CON_CHARMASK);
|
||||
return start+2;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1790,7 +1790,7 @@ float MSG_ReadAngle (void)
|
|||
}
|
||||
}
|
||||
|
||||
void MSG_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move)
|
||||
void MSG_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move, int protover)
|
||||
{
|
||||
int bits;
|
||||
|
||||
|
@ -1798,31 +1798,61 @@ void MSG_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move)
|
|||
|
||||
bits = MSG_ReadByte ();
|
||||
|
||||
// read current angles
|
||||
if (bits & CM_ANGLE1)
|
||||
move->angles[0] = MSG_ReadShort ();
|
||||
if (bits & CM_ANGLE2)
|
||||
move->angles[1] = MSG_ReadShort ();
|
||||
if (bits & CM_ANGLE3)
|
||||
move->angles[2] = MSG_ReadShort ();
|
||||
if (protover <= 26)
|
||||
{
|
||||
if (bits & CM_ANGLE1)
|
||||
move->angles[0] = MSG_ReadShort();
|
||||
if (1)
|
||||
move->angles[1] = MSG_ReadShort();
|
||||
if (bits & CM_ANGLE3)
|
||||
move->angles[2] = MSG_ReadShort();
|
||||
|
||||
// read movement
|
||||
if (bits & CM_FORWARD)
|
||||
move->forwardmove = MSG_ReadShort ();
|
||||
if (bits & CM_SIDE)
|
||||
move->sidemove = MSG_ReadShort ();
|
||||
if (bits & CM_UP)
|
||||
move->upmove = MSG_ReadShort ();
|
||||
if (bits & CM_FORWARD)
|
||||
move->forwardmove = MSG_ReadByte()<<3;
|
||||
if (bits & CM_SIDE)
|
||||
move->sidemove = MSG_ReadByte()<<3;
|
||||
if (bits & CM_UP)
|
||||
move->upmove = MSG_ReadByte()<<3;
|
||||
|
||||
// read buttons
|
||||
if (bits & CM_BUTTONS)
|
||||
move->buttons = MSG_ReadByte ();
|
||||
// read buttons
|
||||
if (bits & CM_BUTTONS)
|
||||
move->buttons = MSG_ReadByte();
|
||||
|
||||
if (bits & CM_IMPULSE)
|
||||
move->impulse = MSG_ReadByte ();
|
||||
if (bits & CM_IMPULSE)
|
||||
move->impulse = MSG_ReadByte();
|
||||
|
||||
// read time to run command
|
||||
move->msec = MSG_ReadByte ();
|
||||
if (bits & CM_ANGLE2)
|
||||
move->msec = MSG_ReadByte();
|
||||
}
|
||||
else
|
||||
{
|
||||
// read current angles
|
||||
if (bits & CM_ANGLE1)
|
||||
move->angles[0] = MSG_ReadShort();
|
||||
if (bits & CM_ANGLE2)
|
||||
move->angles[1] = MSG_ReadShort();
|
||||
if (bits & CM_ANGLE3)
|
||||
move->angles[2] = MSG_ReadShort();
|
||||
|
||||
// read movement
|
||||
if (bits & CM_FORWARD)
|
||||
move->forwardmove = MSG_ReadShort();
|
||||
if (bits & CM_SIDE)
|
||||
move->sidemove = MSG_ReadShort();
|
||||
if (bits & CM_UP)
|
||||
move->upmove = MSG_ReadShort();
|
||||
|
||||
// read buttons
|
||||
if (bits & CM_BUTTONS)
|
||||
move->buttons = MSG_ReadByte();
|
||||
|
||||
if (bits & CM_IMPULSE)
|
||||
move->impulse = MSG_ReadByte();
|
||||
|
||||
// read time to run command
|
||||
move->msec = MSG_ReadByte();
|
||||
}
|
||||
}
|
||||
|
||||
void MSGQ2_ReadDeltaUsercmd (usercmd_t *from, usercmd_t *move)
|
||||
|
@ -3159,6 +3189,9 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
|||
|
||||
conchar_t ext;
|
||||
conchar_t *oldout = out;
|
||||
#ifndef NOLEGACY
|
||||
extern cvar_t dpcompat_console;
|
||||
#endif
|
||||
|
||||
if (flags & PFS_EZQUAKEMARKUP)
|
||||
{
|
||||
|
@ -3182,7 +3215,11 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
|||
return out;
|
||||
#endif
|
||||
|
||||
if (*str == 1 || *str == 2)
|
||||
if (*str == 1 || *str == 2
|
||||
#ifndef NOLEGACY
|
||||
|| (*str == 3 && dpcompat_console.ival)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
defaultflags ^= CON_2NDCHARSETTEXT;
|
||||
str++;
|
||||
|
@ -5833,6 +5870,316 @@ unsigned int COM_RemapMapChecksum(model_t *model, unsigned int checksum)
|
|||
return checksum;
|
||||
}
|
||||
|
||||
/*
|
||||
Info Buffers
|
||||
*/
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
struct infobuf_s
|
||||
{
|
||||
char *name;
|
||||
char *value;
|
||||
} *keys;
|
||||
size_t numkeys;
|
||||
qboolean nolegacy; //no \\ or \" limitations.
|
||||
} infobuf_t;
|
||||
char *InfoBuf_GetValue (infobuf_t *info, const char *key, char *outbuf, size_t outsize)
|
||||
{
|
||||
size_t k;
|
||||
for (k = 0; k < info->numkeys; k++)
|
||||
{
|
||||
if (!strcmp(info->keys[k].name, key))
|
||||
{
|
||||
Q_strncpyz(outbuf, info->keys[k].value, outsize);
|
||||
return outbuf;
|
||||
}
|
||||
}
|
||||
*outbuf = 0;
|
||||
return outbuf;
|
||||
}
|
||||
char *InfoBuf_GetValueTmp (infobuf_t *info, const char *key)
|
||||
{
|
||||
static char value[4][1024]; // use multiple buffers so compares work without stomping on each other
|
||||
static int valueindex;
|
||||
COM_AssertMainThread("InfoBuf_GetValue");
|
||||
valueindex = (valueindex+1)&3;
|
||||
return InfoBuf_GetValue(info, key, value[valueindex], sizeof(value[valueindex]));
|
||||
}
|
||||
qboolean InfoBuf_RemoveKey (infobuf_t *info, const char *key)
|
||||
{
|
||||
size_t k;
|
||||
for (k = 0; k < info->numkeys; k++)
|
||||
{
|
||||
if (!strcmp(info->keys[k].name, key))
|
||||
{
|
||||
Z_Free(info->keys[k].name);
|
||||
Z_Free(info->keys[k].value);
|
||||
info->numkeys--;
|
||||
memmove(info->keys+k+0, info->keys+k+1, sizeof(*info->keys) * (info->numkeys-k));
|
||||
return true; //only one entry per key, so we can give up here
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void InfoBuf_SetKey (infobuf_t *info, const char *key, const char *val, qboolean force)
|
||||
{
|
||||
qboolean removed;
|
||||
size_t k;
|
||||
|
||||
if (!val)
|
||||
val = "";
|
||||
|
||||
if (!info->nolegacy)
|
||||
{
|
||||
//block invalid keys
|
||||
//\\ makes parsing really really messy and isn't supported by most clients (although we could do it anyway)
|
||||
//\" requires string escapes, again compat issues.
|
||||
//0xff bugs out vanilla.
|
||||
if (strchr(key, '\\') || strchr(key, '\"') || strchr(key, 0xff))
|
||||
return;
|
||||
if (strchr(val, '\\') || strchr(val, '\"') || strchr(val, 0xff))
|
||||
return;
|
||||
|
||||
if (strlen(key) >= 64)
|
||||
return; //key length limits is a thing in vanilla qw.
|
||||
if (strlen(val) >= 512)
|
||||
return; //value length limits is a thing in vanilla qw.
|
||||
//note that qw reads values up to 512, but only sets them up to 64 bytes...
|
||||
//probably just so that people don't spot buffer overflows so easily.
|
||||
}
|
||||
|
||||
// *keys are meant to be secure (or rather unsettable by the user, preventing spoofing of stuff like *ip)
|
||||
// but note that this is pointless as a hacked client can send whatever initial *keys it wants (they are blocked mid-connection at least)
|
||||
// * userinfos are always sent even to clients that can't support large infokey blobs
|
||||
if (*key == '*' && !force)
|
||||
return;
|
||||
|
||||
removed = InfoBuf_RemoveKey(info, key);
|
||||
if (*val)
|
||||
{
|
||||
k = info->numkeys;
|
||||
if (removed)
|
||||
info->numkeys+=1; //the memory is still allocated, because we're too lazy to free it.
|
||||
else
|
||||
{
|
||||
if (!ZF_ReallocElements((void**)&info->keys, &info->numkeys, info->numkeys+1, sizeof(*info->keys)))
|
||||
return; //out of memory!
|
||||
}
|
||||
info->keys[k].name = Z_StrDup(key);
|
||||
info->keys[k].value = Z_StrDup(val);
|
||||
}
|
||||
}
|
||||
void InfoBuf_Clear(infobuf_t *info, qboolean all)
|
||||
{//if all is false, leaves *keys
|
||||
size_t k;
|
||||
for (k = info->numkeys-1; k >= 0; k--)
|
||||
{
|
||||
if (all || *info->keys[k].name != '*')
|
||||
{
|
||||
Z_Free(info->keys[k].name);
|
||||
Z_Free(info->keys[k].value);
|
||||
info->numkeys--;
|
||||
memmove(info->keys+k+0, info->keys+k+1, sizeof(*info->keys) * (info->numkeys-k));
|
||||
}
|
||||
}
|
||||
if (!info->numkeys)
|
||||
{
|
||||
Z_Free(info->keys);
|
||||
info->keys = NULL;
|
||||
}
|
||||
}
|
||||
void InfoBuf_FromString(infobuf_t *info, const char *infostring)
|
||||
{
|
||||
if (*infostring++ != '\\')
|
||||
return; //invalid... not an info string
|
||||
while (*infostring)
|
||||
{
|
||||
const char *keystart = infostring;
|
||||
const char *keyend;
|
||||
const char *valstart;
|
||||
const char *valend;
|
||||
char *key;
|
||||
char *val;
|
||||
char *o;
|
||||
while (*infostring)
|
||||
{
|
||||
if (*infostring == '\\')
|
||||
{
|
||||
if (infostring[1] == '\\')
|
||||
infostring += 2;
|
||||
break;
|
||||
}
|
||||
else infostring += 1;
|
||||
}
|
||||
keyend = infostring;
|
||||
if (*infostring++ != '\\')
|
||||
break; //missing value...
|
||||
valstart = infostring;
|
||||
while (*infostring)
|
||||
{
|
||||
if (*infostring == '\\')
|
||||
{
|
||||
if (infostring[1] == '\\')
|
||||
infostring += 2;
|
||||
break;
|
||||
}
|
||||
else infostring += 1;
|
||||
}
|
||||
valend = infostring;
|
||||
// *infostring might be '\\' or '\0'. doesn't really matter
|
||||
|
||||
if (!strncmp(keystart, " \\\\", 3))
|
||||
keystart += 3;
|
||||
if (!strncmp(valstart, " \\\\", 3))
|
||||
valstart += 3;
|
||||
|
||||
key = Z_Malloc(1+keyend-keystart);
|
||||
for (o = key; keystart < keyend; )
|
||||
{
|
||||
if (keystart[0] == '\\')
|
||||
keystart+=1;
|
||||
*o++ = *keystart++;
|
||||
}
|
||||
*o=0;
|
||||
val = Z_Malloc(1+valend-valstart);
|
||||
for (o = val; valstart < valend; )
|
||||
{
|
||||
if (valstart[0] == '\\')
|
||||
valstart+=1;
|
||||
*o++ = *valstart++;
|
||||
}
|
||||
*o=0;
|
||||
InfoBuf_SetKey(info, key, val, true);
|
||||
Z_Free(key);
|
||||
Z_Free(val);
|
||||
}
|
||||
}
|
||||
static size_t InfoBuf_ToStringToken(const char *n, char *out, char *end)
|
||||
{
|
||||
size_t r = 1;
|
||||
if (out < end)
|
||||
*out++ = '\\';
|
||||
if (*n == '\\' || (n[0] == ' ' && n[1] == '\\'))
|
||||
{ //" \\" prefix is stripped by the reader, and present to allow keys or values with a leading \\ in a well-defined-but-annoying way
|
||||
// (vanilla qw doesn't allow double-backslash anywhere in infostrings)
|
||||
r += 3;
|
||||
if (out < end)
|
||||
*out++ = ' ';
|
||||
if (out < end)
|
||||
*out++ = '\\';
|
||||
if (out < end)
|
||||
*out++ = '\\';
|
||||
}
|
||||
while (*n)
|
||||
{
|
||||
if (*n == '\\')
|
||||
{
|
||||
if (out < end)
|
||||
*out++ = '\\';
|
||||
}
|
||||
if (out < end)
|
||||
*out++ = *n;
|
||||
n++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
size_t InfoBuf_ToString(infobuf_t *info, char *infostring, size_t maxsize, const char **priority, const char **ignore, const char **exclusive)
|
||||
{
|
||||
//if infostring is null, returns the needed buffer size
|
||||
//\foo\\\bar is ambiguous. and interpreted as foo\ + bar
|
||||
//\foo\ \\\\bar is interpreted as foo + \bar - leading " \\" is ignored if present.
|
||||
|
||||
//FIXME: add a filter, for short/compated buffers. prioritisation or something
|
||||
size_t k, r = 1, l;
|
||||
char *o = infostring;
|
||||
char *e = infostring?infostring + maxsize-1:infostring;
|
||||
int pri, p;
|
||||
for (pri = 0; pri < 2; pri++)
|
||||
{
|
||||
for (k = 0; k < info->numkeys; k++)
|
||||
{
|
||||
if (exclusive)
|
||||
{
|
||||
for (l = 0; exclusive[l]; l++)
|
||||
if (!strcmp(exclusive[l], info->keys[k].name))
|
||||
break;
|
||||
if (!exclusive[l])
|
||||
continue; //ignore when not in the list
|
||||
}
|
||||
if (ignore)
|
||||
{
|
||||
for (l = 0; ignore[l]; l++)
|
||||
if (!strcmp(ignore[l], info->keys[k].name))
|
||||
break;
|
||||
if (ignore[l])
|
||||
continue; //ignore when in the list
|
||||
}
|
||||
if (priority)
|
||||
{
|
||||
for (l = 0; priority[l]; l++)
|
||||
if (!strcmp(priority[l], info->keys[k].name))
|
||||
break;
|
||||
if (priority[l])
|
||||
p = 0; //high priority
|
||||
else
|
||||
p = 1; //low priority
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*info->keys[k].name == '*')
|
||||
p = 0; //keys that cannot be changed always have the highest priority (fixme: useless stuff like version doesn't need to be in here
|
||||
else
|
||||
p = 1;
|
||||
}
|
||||
if (pri != p)
|
||||
continue;
|
||||
|
||||
l = InfoBuf_ToStringToken(info->keys[k].name, o, e);
|
||||
l += InfoBuf_ToStringToken(info->keys[k].value, o, e);
|
||||
r += l;
|
||||
if (o && o + l < e)
|
||||
o += l;
|
||||
}
|
||||
}
|
||||
*o = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void InfoBuf_WriteToFile(vfsfile_t *f, infobuf_t *info, const char *commandname, int cvarflags)
|
||||
{
|
||||
char buffer[1024];
|
||||
const char *key;
|
||||
const char *val;
|
||||
cvar_t *var;
|
||||
size_t k;
|
||||
|
||||
for (k = 0; k < info->numkeys; k++)
|
||||
{
|
||||
key = info->keys[k].name;
|
||||
val = info->keys[k].value;
|
||||
if (*key == '*') //unsettable, so don't write it for later setting.
|
||||
continue;
|
||||
|
||||
if (cvarflags)
|
||||
{
|
||||
var = Cvar_FindVar(key);
|
||||
if (var && var->flags & cvarflags)
|
||||
continue; //this is saved via a cvar.
|
||||
}
|
||||
|
||||
VFS_WRITE(f, commandname, strlen(commandname));
|
||||
VFS_WRITE(f, " ", 1);
|
||||
key = COM_QuotedString(key, buffer, sizeof(buffer), false);
|
||||
VFS_WRITE(f, key, strlen(key));
|
||||
VFS_WRITE(f, " ", 1);
|
||||
val = COM_QuotedString(val, buffer, sizeof(buffer), false);
|
||||
VFS_WRITE(f, val, strlen(val));
|
||||
VFS_WRITE(f, "\n", 1);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
=====================================================================
|
||||
|
||||
|
|
|
@ -37,11 +37,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include <stdint.h>
|
||||
#define qintptr_t intptr_t
|
||||
#define quintptr_t uintptr_t
|
||||
#define qint16_t int16_t
|
||||
#define quint16_t uint16_t
|
||||
#define qint32_t int32_t
|
||||
#define quint32_t uint32_t
|
||||
#define qint64_t int64_t
|
||||
#define quint64_t uint64_t
|
||||
#else
|
||||
#define qint16_t short
|
||||
#define quint16_t unsigned short
|
||||
#define qint32_t int
|
||||
#define quint32_t unsigned qint32_t
|
||||
#if defined(_WIN64)
|
||||
|
@ -289,7 +293,7 @@ float MSG_ReadCoord (void);
|
|||
void MSG_ReadPos (float *pos);
|
||||
float MSG_ReadAngle (void);
|
||||
float MSG_ReadAngle16 (void);
|
||||
void MSG_ReadDeltaUsercmd (struct usercmd_s *from, struct usercmd_s *cmd);
|
||||
void MSG_ReadDeltaUsercmd (struct usercmd_s *from, struct usercmd_s *cmd, int qwprotocolver);
|
||||
void MSGQ2_ReadDeltaUsercmd (struct usercmd_s *from, struct usercmd_s *move);
|
||||
void MSG_ReadData (void *data, int len);
|
||||
void MSG_ReadSkip (int len);
|
||||
|
@ -753,8 +757,9 @@ void T_FreeInfoStrings(void);
|
|||
char *T_GetInfoString(int num);
|
||||
|
||||
struct po_s;
|
||||
struct po_s *PO_Create(void);
|
||||
void PO_Merge(struct po_s *po, vfsfile_t *file);
|
||||
const char *PO_GetText(struct po_s *po, const char *msg);
|
||||
struct po_s *PO_Load(vfsfile_t *file);
|
||||
void PO_Close(struct po_s *po);
|
||||
|
||||
//
|
||||
|
|
|
@ -239,7 +239,7 @@ void Con_ToggleConsole_Force(void);
|
|||
int Con_ExecuteLine(console_t *con, char *line); //takes normal console commands
|
||||
int Con_Navigate(console_t *con, char *line); //special webbrowser hacks
|
||||
|
||||
|
||||
vfsfile_t *Con_POpen(char *conname);
|
||||
void Con_CycleConsole (void);
|
||||
int Con_IsActive (console_t *con);
|
||||
void Con_Destroy (console_t *con);
|
||||
|
|
|
@ -775,10 +775,11 @@ qboolean CertLog_ConnectOkay(const char *hostname, void *cert, size_t certsize)
|
|||
memcpy(ctx->cert, cert, certsize);
|
||||
strcpy(ctx->hostname, hostname);
|
||||
|
||||
//FIXME: display some sort of fingerprint
|
||||
if (!l)
|
||||
M_Menu_Prompt(CertLog_Add_Prompted, ctx, "Server certificate is new", "Trust", NULL, "Disconnect");
|
||||
M_Menu_Prompt(CertLog_Add_Prompted, ctx, va("%s\nServer certificate is\nself-signed", hostname), "Trust", NULL, "Disconnect");
|
||||
else
|
||||
M_Menu_Prompt(CertLog_Add_Prompted, ctx, "^1Server certificate HAS CHANGED\nZomg\nFlee in Terror", "ReTrust", NULL, "Disconnect");
|
||||
M_Menu_Prompt(CertLog_Add_Prompted, ctx, va("%s\n^1Server certificate HAS CHANGED\nZomg\n^bFlee in Terror", hostname), "ReTrust", NULL, "Disconnect");
|
||||
}
|
||||
return false; //can't connect yet...
|
||||
}
|
||||
|
|
|
@ -405,12 +405,14 @@ char *narrowen(char *out, size_t outlen, wchar_t *wide);
|
|||
static DWORD VerifyKnownCertificates(DWORD status, wchar_t *domain, qbyte *data, size_t datasize, qboolean datagram)
|
||||
{
|
||||
int i;
|
||||
#ifndef SERVERONLY
|
||||
char realdomain[256];
|
||||
#endif
|
||||
if (datagram)
|
||||
{
|
||||
if (status == CERT_E_UNTRUSTEDROOT || SUCCEEDED(status))
|
||||
{
|
||||
#ifndef SERVERONLY
|
||||
char realdomain[256];
|
||||
if (CertLog_ConnectOkay(narrowen(realdomain, sizeof(realdomain), domain), data, datasize))
|
||||
status = SEC_E_OK;
|
||||
else
|
||||
|
@ -455,6 +457,15 @@ static DWORD VerifyKnownCertificates(DWORD status, wchar_t *domain, qbyte *data,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SERVERONLY
|
||||
//self-signed and expired certs are understandable in many situations.
|
||||
//prompt and cache (although this connection attempt will fail).
|
||||
if (status == CERT_E_UNTRUSTEDROOT || status == CERT_E_UNTRUSTEDTESTROOT || status == CERT_E_EXPIRED)
|
||||
if (CertLog_ConnectOkay(narrowen(realdomain, sizeof(realdomain), domain), data, datasize))
|
||||
return SEC_E_OK;
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
|
|
@ -1155,6 +1155,17 @@ static void Plug_DownloadComplete(struct dl_download *dl)
|
|||
}
|
||||
#endif
|
||||
|
||||
static qintptr_t VARGS Plug_Con_POpen(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *conname = VM_POINTER(arg[0]);
|
||||
int handle;
|
||||
if (!currentplug)
|
||||
return -3; //streams depend upon current plugin context. which isn't valid in a thread.
|
||||
handle = Plug_NewStreamHandle(STREAM_VFS);
|
||||
pluginstreamarray[handle].vfs = Con_POpen(conname);
|
||||
return handle;
|
||||
}
|
||||
|
||||
qintptr_t VARGS Plug_FS_Open(void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
//modes:
|
||||
|
@ -1613,6 +1624,7 @@ void Plug_Initialise(qboolean fromgamedir)
|
|||
Plug_RegisterBuiltin("Plug_ExportNative", Plug_ExportNative, PLUG_BIF_DLLONLY);
|
||||
Plug_RegisterBuiltin("Plug_GetPluginName", Plug_GetPluginName, 0);
|
||||
Plug_RegisterBuiltin("Con_Print", Plug_Con_Print, 0); //printf is not possible - qvm floats are never doubles, vararg floats in a cdecl call are always converted to doubles.
|
||||
Plug_RegisterBuiltin("Con_POpen", Plug_Con_POpen, PLUG_BIF_DLLONLY);
|
||||
Plug_RegisterBuiltin("Sys_Error", Plug_Sys_Error, 0);
|
||||
Plug_RegisterBuiltin("Sys_Milliseconds", Plug_Sys_Milliseconds, 0);
|
||||
Plug_RegisterBuiltin("Com_Error", Plug_Sys_Error, 0); //make zquake programmers happy.
|
||||
|
|
|
@ -18,7 +18,7 @@ cvar_t sv_gameplayfix_nolinknonsolid = CVARD("sv_gameplayfix_nolinknonsolid", "1
|
|||
cvar_t sv_gameplayfix_blowupfallenzombies = CVARD("sv_gameplayfix_blowupfallenzombies", "0", "Allow findradius to find non-solid entities. This may break certain mods.");
|
||||
cvar_t dpcompat_findradiusarealinks = CVARD("dpcompat_findradiusarealinks", "0", "Use the world collision info to accelerate findradius instead of looping through every single entity. May actually be slower for large radiuses, or fail to find entities which have not been linked properly with setorigin.");
|
||||
#ifndef NOLEGACY
|
||||
cvar_t dpcompat_strcatlimitation = CVARD("dpcompat_crippledstrcat", "", "When set, cripples strcat (and related function) string lengths to the value specified.\nSet to 16383 to replicate DP's limit, otherwise leave as 0 to avoid limits.");
|
||||
cvar_t dpcompat_strcat_limit = CVARD("dpcompat_strcat_limit", "", "When set, cripples strcat (and related function) string lengths to the value specified.\nSet to 16383 to replicate DP's limit, otherwise leave as 0 to avoid limits.");
|
||||
#endif
|
||||
cvar_t pr_droptofloorunits = CVARD("pr_droptofloorunits", "256", "Distance that droptofloor is allowed to drop to be considered successul.");
|
||||
cvar_t pr_brokenfloatconvert = CVAR("pr_brokenfloatconvert", "0");
|
||||
|
@ -51,7 +51,7 @@ void PF_Common_RegisterCvars(void)
|
|||
Cvar_Register (&sv_gameplayfix_nolinknonsolid, cvargroup_progs);
|
||||
Cvar_Register (&dpcompat_findradiusarealinks, cvargroup_progs);
|
||||
#ifndef NOLEGACY
|
||||
Cvar_Register (&dpcompat_strcatlimitation, cvargroup_progs);
|
||||
Cvar_Register (&dpcompat_strcat_limit, cvargroup_progs);
|
||||
#endif
|
||||
Cvar_Register (&pr_droptofloorunits, cvargroup_progs);
|
||||
Cvar_Register (&pr_brokenfloatconvert, cvargroup_progs);
|
||||
|
@ -3600,10 +3600,10 @@ void QCBUILTIN PF_strcat (pubprogfuncs_t *prinst, struct globalvars_s *pr_global
|
|||
len += l[i];
|
||||
|
||||
#ifndef NOLEGACY
|
||||
if (dpcompat_strcatlimitation.ival && len > dpcompat_strcatlimitation.ival)
|
||||
if (dpcompat_strcat_limit.ival && len > dpcompat_strcat_limit.ival)
|
||||
{
|
||||
l[i] -= len-dpcompat_strcatlimitation.ival;
|
||||
len -= len-dpcompat_strcatlimitation.ival;
|
||||
l[i]-= len-dpcompat_strcat_limit.ival;
|
||||
len -= len-dpcompat_strcat_limit.ival;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -6251,7 +6251,7 @@ void PDECL PR_FoundDoTranslateGlobal(pubprogfuncs_t *progfuncs, char *name, eval
|
|||
//called after each progs is loaded
|
||||
void PR_ProgsAdded(pubprogfuncs_t *prinst, int newprogs, const char *modulename)
|
||||
{
|
||||
vfsfile_t *f = NULL;
|
||||
vfsfile_t *f = NULL, *f2 = NULL;
|
||||
char lang[64], *h;
|
||||
extern cvar_t language;
|
||||
if (!prinst || newprogs < 0)
|
||||
|
@ -6265,8 +6265,11 @@ void PR_ProgsAdded(pubprogfuncs_t *prinst, int newprogs, const char *modulename)
|
|||
{
|
||||
if (!*lang)
|
||||
break;
|
||||
f = FS_OpenVFS(va("%s.%s.po", modulename, lang), "rb", FS_GAME);
|
||||
if (f)
|
||||
if (!f)
|
||||
f = FS_OpenVFS(va("%s.%s.po", modulename, lang), "rb", FS_GAME);
|
||||
if (!f2)
|
||||
f2 = FS_OpenVFS(va("common.%s.po", lang), "rb", FS_GAME);
|
||||
if (f && f2)
|
||||
break;
|
||||
h = strchr(lang, '_');
|
||||
if (h)
|
||||
|
@ -6276,9 +6279,11 @@ void PR_ProgsAdded(pubprogfuncs_t *prinst, int newprogs, const char *modulename)
|
|||
}
|
||||
}
|
||||
|
||||
if (f)
|
||||
if (f || f2)
|
||||
{
|
||||
void *pofile = PO_Load(f);
|
||||
void *pofile = PO_Create();
|
||||
PO_Merge(pofile, f);
|
||||
PO_Merge(pofile, f2);
|
||||
prinst->FindPrefixGlobals (prinst, newprogs, "dotranslate_", PR_FoundDoTranslateGlobal, pofile);
|
||||
PO_Close(pofile);
|
||||
}
|
||||
|
|
|
@ -1136,7 +1136,7 @@ qintptr_t VARGS VM_Call(vm_t *vm, qintptr_t instruction, ...)
|
|||
arg[3]=va_arg(argptr, qintptr_t);
|
||||
arg[4]=va_arg(argptr, qintptr_t);
|
||||
arg[5]=va_arg(argptr, qintptr_t);
|
||||
arg[6]=va_arg(argptr, qintptr_t);
|
||||
arg[6]=va_arg(argptr, qintptr_t);
|
||||
arg[7]=va_arg(argptr, qintptr_t);
|
||||
va_end(argptr);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ static void QDECL TL_LanguageChanged(struct cvar_s *var, char *oldvalue)
|
|||
#endif
|
||||
}
|
||||
|
||||
cvar_t language = CVARFC("lang", sys_language, CVAR_USERINFO, TL_LanguageChanged);
|
||||
cvar_t language = CVARAFC("lang", sys_language, "prvm_language", CVAR_USERINFO, TL_LanguageChanged);
|
||||
|
||||
void TranslateInit(void)
|
||||
{
|
||||
|
@ -77,7 +77,13 @@ static int TL_LoadLanguage(char *lang)
|
|||
return TL_LoadLanguage(lang);
|
||||
}
|
||||
languages[j].name = strdup(lang);
|
||||
languages[j].po = f?PO_Load(f):NULL;
|
||||
languages[j].po = NULL;
|
||||
|
||||
if (f)
|
||||
{
|
||||
languages[j].po = PO_Create();
|
||||
PO_Merge(languages[j].po, f);
|
||||
}
|
||||
|
||||
return j;
|
||||
}
|
||||
|
@ -328,19 +334,16 @@ static void PO_AddText(struct po_s *po, const char *orig, const char *trans)
|
|||
line->next = po->lines;
|
||||
po->lines = line;
|
||||
}
|
||||
struct po_s *PO_Load(vfsfile_t *file)
|
||||
void PO_Merge(struct po_s *po, vfsfile_t *file)
|
||||
{
|
||||
struct po_s *po;
|
||||
unsigned int buckets = 1024;
|
||||
char *instart, *in, *end;
|
||||
int inlen;
|
||||
char msgid[32768];
|
||||
char msgstr[32768];
|
||||
|
||||
qboolean allowblanks = !!COM_CheckParm("-translatetoblank");
|
||||
|
||||
po = Z_Malloc(sizeof(*po) + Hash_BytesForBuckets(buckets));
|
||||
Hash_InitTable(&po->hash, buckets, po+1);
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
inlen = file?VFS_GETLEN(file):0;
|
||||
instart = in = BZ_Malloc(inlen+1);
|
||||
|
@ -409,6 +412,14 @@ struct po_s *PO_Load(vfsfile_t *file)
|
|||
}
|
||||
|
||||
BZ_Free(instart);
|
||||
}
|
||||
struct po_s *PO_Create(void)
|
||||
{
|
||||
struct po_s *po;
|
||||
unsigned int buckets = 1024;
|
||||
|
||||
po = Z_Malloc(sizeof(*po) + Hash_BytesForBuckets(buckets));
|
||||
Hash_InitTable(&po->hash, buckets, po+1);
|
||||
return po;
|
||||
}
|
||||
void PO_Close(struct po_s *po)
|
||||
|
|
|
@ -1418,7 +1418,7 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="comctl32.lib wsock32.lib odbc32.lib odbccp32.lib winmm.lib"
|
||||
OutputFile="../../fteqwsv64.exe"
|
||||
OutputFile="../../fteqwsv_dbg64.exe"
|
||||
LinkIncremental="2"
|
||||
SuppressStartupBanner="true"
|
||||
AdditionalLibraryDirectories="../libs/dxsdk7/lib"
|
||||
|
@ -1597,9 +1597,6 @@
|
|||
UsePrecompiledHeader="2"
|
||||
PrecompiledHeaderThrough="quakedef.h"
|
||||
PrecompiledHeaderFile=".\MDebug/qwcl.pch"
|
||||
AssemblerListingLocation=".\MDebug/"
|
||||
ObjectFile=".\MDebug/"
|
||||
ProgramDataBaseFileName=".\MDebug/"
|
||||
BrowseInformation="1"
|
||||
BrowseInformationFile=".\MDebug/"
|
||||
WarningLevel="3"
|
||||
|
@ -19771,250 +19768,6 @@
|
|||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\server\svmodel.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="MinGLDebug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MinGLDebug|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="D3DDebug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="D3DDebug|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MinGLRelease|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MinGLRelease|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="GLDebug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="GLDebug|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release Dedicated Server|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release Dedicated Server|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MRelease|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MRelease|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug Dedicated Server|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug Dedicated Server|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MDebug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="MDebug|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="GLRelease|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="GLRelease|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="D3DRelease|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="D3DRelease|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="VkDebug|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="VkDebug|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="VkRelease|Win32"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="VkRelease|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="nonwin"
|
||||
|
@ -25930,7 +25683,6 @@
|
|||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug Dedicated Server|x64"
|
||||
ExcludedFromBuild="true"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
|
|
|
@ -236,6 +236,10 @@ static struct
|
|||
vec3_t reflectcolour;
|
||||
float wateralpha;
|
||||
|
||||
//FIXME: rtlights can't respond to these
|
||||
int offsetmappingmode;
|
||||
float offsetmappingscale;
|
||||
float offsetmappingbias;
|
||||
float specularexpscale; //*32 ish
|
||||
float specularvalscale; //*1 ish
|
||||
} parsestate;
|
||||
|
@ -1149,7 +1153,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
|||
int cvartypes[64];
|
||||
int cvarcount = 0;
|
||||
qboolean onefailed = false;
|
||||
extern cvar_t gl_specular;
|
||||
extern cvar_t gl_specular, gl_specular_power;
|
||||
#endif
|
||||
|
||||
#ifdef VKQUAKE
|
||||
|
@ -1461,7 +1465,7 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
|
|||
if (gl_specular.value)
|
||||
{
|
||||
if (nummodifiers < MAXMODIFIERS)
|
||||
permutationdefines[nummodifiers++] = Z_StrDup("#define SPECULAR\n");
|
||||
permutationdefines[nummodifiers++] = Z_StrDup(va("#define SPECULAR\n#define SPECULAR_BASE_MUL %f\n#define SPECULAR_BASE_POW %f\n", 1.0*gl_specular.value, max(1,gl_specular_power.value)));
|
||||
}
|
||||
for (end = strchr(name, '#'); end && *end; )
|
||||
{
|
||||
|
@ -2363,23 +2367,23 @@ static void Shader_DP_OffsetMapping(shader_t *shader, shaderpass_t *pass, char *
|
|||
{
|
||||
char *token = Shader_ParseString(ptr);
|
||||
if (!strcmp(token, "disable") || !strcmp(token, "none") || !strcmp(token, "off"))
|
||||
;
|
||||
parsestate.offsetmappingmode = 0;
|
||||
else if (!strcmp(token, "default") || !strcmp(token, "normal"))
|
||||
;
|
||||
parsestate.offsetmappingmode = -1;
|
||||
else if (!strcmp(token, "linear"))
|
||||
;
|
||||
parsestate.offsetmappingmode = 1;
|
||||
else if (!strcmp(token, "relief"))
|
||||
;
|
||||
/*scale = */Shader_ParseFloat(shader, ptr, 1);
|
||||
parsestate.offsetmappingmode = 2;
|
||||
parsestate.offsetmappingscale = Shader_ParseFloat(shader, ptr, 1);
|
||||
token = Shader_ParseString(ptr);
|
||||
if (!strcmp(token, "bias"))
|
||||
/*bias = */Shader_ParseFloat(shader, ptr, 0.5);
|
||||
parsestate.offsetmappingbias = Shader_ParseFloat(shader, ptr, 0.5);
|
||||
else if (!strcmp(token, "match"))
|
||||
/*bias = 1.0 - */Shader_ParseFloat(shader, ptr, 0.5);
|
||||
parsestate.offsetmappingbias = 1.0 - Shader_ParseFloat(shader, ptr, 0.5);
|
||||
else if (!strcmp(token, "match8"))
|
||||
/*bias = 1.0 - (1.0/255) * */Shader_ParseFloat(shader, ptr, 128);
|
||||
parsestate.offsetmappingbias = 1.0 - (1.0/255) * Shader_ParseFloat(shader, ptr, 128);
|
||||
else if (!strcmp(token, "match16"))
|
||||
/*bias = 1.0 - (1.0/65535) * */Shader_ParseFloat(shader, ptr, 32768);
|
||||
parsestate.offsetmappingbias = 1.0 - (1.0/65535) * Shader_ParseFloat(shader, ptr, 32768);
|
||||
}
|
||||
static void Shader_DP_GlossScale(shader_t *shader, shaderpass_t *pass, char **ptr)
|
||||
{
|
||||
|
@ -4470,7 +4474,23 @@ void Shader_Programify (shader_t *s)
|
|||
Q_strncatz(args, va("#specmul=%g", parsestate.specularvalscale), sizeof(args));
|
||||
if (parsestate.specularexpscale != 1)
|
||||
Q_strncatz(args, va("#specexp=%g", parsestate.specularexpscale), sizeof(args));
|
||||
|
||||
/* switch(parsestate.offsetmappingmode)
|
||||
{
|
||||
case 0: //force off.
|
||||
Q_strncatz(args, va("#NOOFFSETMAPPING", parsestate.specularexpscale), sizeof(args));
|
||||
break;
|
||||
case 1: //force linear
|
||||
Q_strncatz(args, va("#NORELIEFMAPPING", parsestate.specularexpscale), sizeof(args));
|
||||
break;
|
||||
case 2: //force relief
|
||||
Q_strncatz(args, va("#RELIEFMAPPING", parsestate.specularexpscale), sizeof(args));
|
||||
break;
|
||||
}
|
||||
if (parsestate.offsetmappingscale != 1)
|
||||
Q_strncatz(args, va("#OFFSETMAPPING_SCALE=%g", parsestate.offsetmappingscale), sizeof(args));
|
||||
if (parsestate.offsetmappingbias != 0)
|
||||
Q_strncatz(args, va("#OFFSETMAPPING_BIAS=%g", parsestate.offsetmappingbias), sizeof(args));
|
||||
*/
|
||||
mask = strchr(s->name, '#');
|
||||
if (mask)
|
||||
Q_strncatz(args, mask, sizeof(args));
|
||||
|
|
|
@ -1251,11 +1251,15 @@ static const char *glsl_hdrs[] =
|
|||
"#ifndef SPECEXP\n"
|
||||
"#define SPECEXP 1.0\n"
|
||||
"#endif\n"
|
||||
"#define FTE_SPECULAR_EXPONENT (32.0*float(SPECEXP))\n"
|
||||
"#ifndef SPECULAR_BASE_POW\n"
|
||||
"#define SPECULAR_BASE_POW 32.0\n"
|
||||
"#define SPECULAR_BASE_MUL 1.0\n"
|
||||
"#endif\n"
|
||||
"#define FTE_SPECULAR_EXPONENT (SPECULAR_BASE_POW*float(SPECEXP))\n"
|
||||
"#ifndef SPECMUL\n"
|
||||
"#define SPECMUL 1.0\n"
|
||||
"#endif\n"
|
||||
"#define FTE_SPECULAR_MULTIPLIER (cvar_gl_specular*float(SPECMUL))\n"
|
||||
"#define FTE_SPECULAR_MULTIPLIER (SPECULAR_BASE_MUL*float(SPECMUL))\n"
|
||||
#ifndef NOLEGACY
|
||||
"uniform sampler2DShadow s_shadowmap;"
|
||||
"uniform samplerCube s_projectionmap;"
|
||||
|
@ -1633,6 +1637,9 @@ static const char *glsl_hdrs[] =
|
|||
"#if !defined(OFFSETMAPPING_SCALE)\n"
|
||||
"#define OFFSETMAPPING_SCALE 1.0\n"
|
||||
"#endif\n"
|
||||
"#if !defined(OFFSETMAPPING_BIAS)\n"
|
||||
"#define OFFSETMAPPING_BIAS 0.0\n"
|
||||
"#endif\n"
|
||||
"#if defined(RELIEFMAPPING) && !defined(GL_ES)\n"
|
||||
"float i, f;\n"
|
||||
"vec3 OffsetVector = vec3(normalize(eyevector.xyz).xy * cvar_r_glsl_offsetmapping_scale * OFFSETMAPPING_SCALE * vec2(-1.0, 1.0), -1.0);\n"
|
||||
|
|
|
@ -5695,7 +5695,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"!!permu SPECULAR\n"
|
||||
"!!permu REFLECTCUBEMASK\n"
|
||||
"!!cvarf r_glsl_offsetmapping_scale\n"
|
||||
"!!cvarf gl_specular\n"
|
||||
"!!cvardf r_tessellation_level=5\n"
|
||||
"!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3\n"
|
||||
|
||||
|
@ -5917,9 +5916,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#define s_colourmap s_t0\n"
|
||||
"uniform sampler2D s_colourmap;\n"
|
||||
|
||||
"#ifdef SPECULAR\n"
|
||||
"uniform float cvar_gl_specular;\n"
|
||||
"#endif\n"
|
||||
"#ifdef OFFSETMAPPING\n"
|
||||
"#include \"sys/offsetmapping.h\"\n"
|
||||
"#endif\n"
|
||||
|
@ -5999,7 +5995,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#ifdef SPECULAR\n"
|
||||
"vec4 specs = texture2D(s_specular, tc);\n"
|
||||
"vec3 halfdir = normalize(normalize(eyevector) + delux); //this norm should be the deluxemap info instead\n"
|
||||
"float spec = pow(max(dot(halfdir, norm), 0.0), 2.0*FTE_SPECULAR_EXPONENT * specs.a);\n"
|
||||
"float spec = pow(max(dot(halfdir, norm), 0.0), FTE_SPECULAR_EXPONENT * specs.a);\n"
|
||||
"spec *= FTE_SPECULAR_MULTIPLIER;\n"
|
||||
//NOTE: rtlights tend to have a *4 scaler here to over-emphasise the effect because it looks cool.
|
||||
//As not all maps will have deluxemapping, and the double-cos from the light util makes everything far too dark anyway,
|
||||
|
@ -6009,7 +6005,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#endif\n"
|
||||
|
||||
"#ifdef REFLECTCUBEMASK\n"
|
||||
"vec3 rtc = reflect(-eyevector, norm);\n"
|
||||
"vec3 rtc = reflect(normalize(-eyevector), norm);\n"
|
||||
"rtc = rtc.x*invsurface[0] + rtc.y*invsurface[1] + rtc.z*invsurface[2];\n"
|
||||
"rtc = (m_model * vec4(rtc.xyz,0.0)).xyz;\n"
|
||||
"gl_FragColor.rgb += texture2D(s_reflectmask, tc).rgb * textureCube(s_reflectcube, rtc).rgb;\n"
|
||||
|
@ -6051,6 +6047,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#endif\n"
|
||||
"}\n"
|
||||
"#endif\n"
|
||||
|
||||
},
|
||||
#endif
|
||||
#ifdef VKQUAKE
|
||||
|
@ -8440,6 +8437,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"#endif\n"
|
||||
"uniform sampler2DShadow s_shadowmap;\n"
|
||||
|
||||
//FIXME: shadowmaps need to be atlased!
|
||||
"uniform vec4 l_shadowmapproj; //light projection matrix info\n"
|
||||
"uniform vec2 l_shadowmapscale; //xy are the texture scale, z is 1, w is the scale.\n"
|
||||
"vec3 ShadowmapCoord(vec4 cubeproj)\n"
|
||||
|
@ -8585,6 +8583,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
|
|||
"float nDotL = dot(norm, lightDir);\n"
|
||||
"float lightDiffuse = max(0.0, nDotL) * atten;\n"
|
||||
|
||||
/*calc specular term*/
|
||||
//fixme
|
||||
|
||||
//fixme: apply fog
|
||||
//fixme: output a specular term
|
||||
//fixme: cubemap filters
|
||||
|
|
|
@ -427,6 +427,7 @@ enum qcop_e {
|
|||
OP_BITXOR_V,
|
||||
|
||||
OP_POW_F,
|
||||
OP_CROSS_V,
|
||||
|
||||
OP_EQ_FLD,
|
||||
OP_NE_FLD,
|
||||
|
@ -461,10 +462,10 @@ typedef struct qtest_function_s
|
|||
int unused1;
|
||||
int locals; // assumed! (always 0 in real qtest progs)
|
||||
int profile; // assumed! (always 0 in real qtest progs)
|
||||
|
||||
|
||||
int s_name;
|
||||
int s_file;
|
||||
|
||||
|
||||
int numparms;
|
||||
int parm_start; // different order
|
||||
int parm_size[MAX_PARMS]; // ints instead of bytes...
|
||||
|
@ -540,12 +541,12 @@ typedef struct
|
|||
int first_statement; // negative numbers are builtins
|
||||
int parm_start;
|
||||
int locals; // total ints of parms + locals
|
||||
|
||||
|
||||
int profile; // runtime
|
||||
|
||||
|
||||
string_t s_name;
|
||||
string_t s_file; // source file defined in
|
||||
|
||||
|
||||
int numparms;
|
||||
qbyte parm_size[MAX_PARMS];
|
||||
} dfunction_t;
|
||||
|
@ -555,14 +556,14 @@ typedef struct
|
|||
int first_statement; // negative numbers are builtins
|
||||
int parm_start;
|
||||
int locals; // total ints of parms + locals
|
||||
|
||||
|
||||
int profile; //number of qc instructions executed.
|
||||
prclocks_t profiletime; //total time inside (cpu cycles)
|
||||
prclocks_t profilechildtime; //time inside children (excluding builtins, cpu cycles)
|
||||
|
||||
|
||||
string_t s_name;
|
||||
string_t s_file; // source file defined in
|
||||
|
||||
|
||||
int numparms;
|
||||
qbyte parm_size[MAX_PARMS];
|
||||
} mfunction_t;
|
||||
|
@ -577,25 +578,25 @@ typedef struct
|
|||
{
|
||||
int version;
|
||||
int crc; // check of header file
|
||||
|
||||
|
||||
unsigned int ofs_statements; //comp 1
|
||||
unsigned int numstatements; // statement 0 is an error
|
||||
|
||||
unsigned int ofs_globaldefs; //comp 2
|
||||
unsigned int numglobaldefs;
|
||||
|
||||
|
||||
unsigned int ofs_fielddefs; //comp 4
|
||||
unsigned int numfielddefs;
|
||||
|
||||
|
||||
unsigned int ofs_functions; //comp 8
|
||||
unsigned int numfunctions; // function 0 is an empty
|
||||
|
||||
|
||||
unsigned int ofs_strings; //comp 16
|
||||
unsigned int numstrings; // first string is a null string
|
||||
|
||||
unsigned int ofs_globals; //comp 32
|
||||
unsigned int numglobals;
|
||||
|
||||
|
||||
unsigned int entityfields;
|
||||
|
||||
//debug / version 7 extensions
|
||||
|
|
|
@ -378,8 +378,8 @@ typedef struct QCC_def_s
|
|||
struct QCC_function_s *scope; // function the var was defined in, or NULL
|
||||
struct QCC_def_s *deftail; // arrays and structs create multiple globaldef objects providing different types at the different parts of the single object (struct), or alternative names (vectors). this allows us to correctly set the const type based upon how its initialised.
|
||||
struct QCC_def_s *generatedfor;
|
||||
int initialized; // 1 when a declaration included "= immediate". 2 = extern. 3 = don't warn (unless actually used)
|
||||
int constant; // 1 says we can use the value over and over again
|
||||
int initialized; // 1 when a declaration included "= immediate". 2 = extern.
|
||||
int constant; // 1 says we can use the value over and over again. 2 is used on fields, for some reason.
|
||||
|
||||
struct QCC_def_s *symbolheader; //this is the original symbol within which the def is stored.
|
||||
union QCC_eval_s *symboldata; //null if uninitialised. use sym->symboldata[sym->ofs] to index.
|
||||
|
@ -402,14 +402,17 @@ typedef struct QCC_def_s
|
|||
pbool saved:1; //def may be saved to saved games.
|
||||
pbool isstatic:1; //global, even if scoped. also specific to the file it was seen in.
|
||||
pbool subscoped_away:1; //this local is no longer linked into the locals hash table. don't do remove it twice.
|
||||
// pbool followptr:1;
|
||||
// pbool followptr:1; //float &foo;
|
||||
pbool strip:1; //info about this def should be stripped. it may still consume globals space however, and its storage can still be used, its just not visible.
|
||||
pbool allowinline:1; //calls to this function will attempt to inline the specified function. requires const, supposedly.
|
||||
pbool used:1; //if it remains 0, it may be stripped. this is forced for functions and fields. commonly 0 on fields.
|
||||
pbool unused:1; //silently strip it if it wasn't referenced.
|
||||
pbool localscope:1; //is a local, as opposed to a static (which is only visible within its scope)
|
||||
pbool arraylengthprefix:1; //hexen2 style arrays have a length prefixed to them for auto bounds checks. this can only work reliably for simple non-struct arrays.
|
||||
pbool assumedtype:1; //#merged. the type is not reliable.
|
||||
pbool weak:1; //ignore any initialiser value (only permitted on functions)
|
||||
pbool accumulate:1; //don't finalise the function's statements.
|
||||
pbool nofold:1;
|
||||
|
||||
int fromstatement; //statement that it is valid from.
|
||||
temp_t *temp;
|
||||
|
@ -470,6 +473,7 @@ struct QCC_function_s
|
|||
string_t s_filed; // source file with definition
|
||||
const char *filen;
|
||||
int line;
|
||||
int line_end;
|
||||
char *name; //internal name of function
|
||||
struct QCC_function_s *parentscope; //for nested functions
|
||||
struct QCC_type_s *type; //same as the def's type
|
||||
|
@ -478,6 +482,9 @@ struct QCC_function_s
|
|||
QCC_sref_t returndef; //default return value
|
||||
pbool privatelocals; //false means locals may overlap with other functions, true is needed for compat if stuff is uninitialised.
|
||||
// unsigned int parm_ofs[MAX_PARMS]; // always contiguous, right?
|
||||
|
||||
QCC_statement_t *statements; //if set, then this function isn't finialised yet.
|
||||
size_t numstatements;
|
||||
};
|
||||
|
||||
|
||||
|
@ -578,6 +585,7 @@ extern pbool keyword_strip; //don't write the def to the output.
|
|||
extern pbool keyword_union; //you surly know what a union is!
|
||||
extern pbool keyword_wrap;
|
||||
extern pbool keyword_weak;
|
||||
extern pbool keyword_accumulate;
|
||||
|
||||
extern pbool keyword_unused;
|
||||
extern pbool keyword_used;
|
||||
|
@ -670,6 +678,7 @@ extern pbool type_inlinefunction;
|
|||
QCC_type_t *QCC_TypeForName(char *name);
|
||||
QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype);
|
||||
QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype);
|
||||
QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s *args, int numargs);
|
||||
char *QCC_PR_ParseName (void);
|
||||
CompilerConstant_t *QCC_PR_DefineName(char *name);
|
||||
|
||||
|
@ -752,6 +761,7 @@ enum {
|
|||
WARN_NOTSTANDARDBEHAVIOUR,
|
||||
WARN_DUPLICATEPRECOMPILER,
|
||||
WARN_IDENTICALPRECOMPILER,
|
||||
WARN_GMQCC_SPECIFIC, //extension created by gmqcc that conflicts or isn't properly implemented.
|
||||
WARN_FTE_SPECIFIC, //extension that only FTEQCC will have a clue about.
|
||||
WARN_EXTENSION_USED, //extension that frikqcc also understands
|
||||
WARN_IFSTRING_USED,
|
||||
|
@ -938,8 +948,9 @@ void QCC_PR_NewLine (pbool incomment);
|
|||
#define GDF_INLINE 32 //attempt to inline calls to this function
|
||||
#define GDF_USED 64 //don't strip this, ever.
|
||||
#define GDF_BASICTYPE 128 //don't care about #merge types not being known correctly.
|
||||
QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
||||
QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
||||
#define GDF_SCANLOCAL 256 //don't use the locals hash table
|
||||
QCC_def_t *QCC_PR_GetDef (QCC_type_t *type, const char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
||||
QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, const char *name, struct QCC_function_s *scope, pbool allocate, int arraysize, unsigned int flags);
|
||||
void QCC_FreeTemp(QCC_sref_t t);
|
||||
void QCC_FreeDef(QCC_def_t *def);
|
||||
char *QCC_PR_CheckCompConstTooltip(char *word, char *outstart, char *outend);
|
||||
|
@ -973,8 +984,9 @@ void QCC_PR_EmitArrayGetFunction(QCC_def_t *defscope, QCC_def_t *thearray, char
|
|||
void QCC_PR_EmitArraySetFunction(QCC_def_t *defscope, QCC_def_t *thearray, char *arrayname);
|
||||
void QCC_PR_EmitClassFromFunction(QCC_def_t *defscope, QCC_type_t *basetype);
|
||||
|
||||
QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_function_t *scope, int arraysize, QCC_def_t *rootsymbol, unsigned int ofs, int referable, unsigned int flags);
|
||||
QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, const char *name, QCC_function_t *scope, int arraysize, QCC_def_t *rootsymbol, unsigned int ofs, int referable, unsigned int flags);
|
||||
void QCC_PR_ParseInitializerDef(QCC_def_t *def, unsigned int flags);
|
||||
void QCC_PR_FinaliseFunctions(void);
|
||||
|
||||
|
||||
void PostCompile(void);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -71,13 +71,13 @@ static void Q_strlcpy(char *dest, const char *src, int sizeofdest)
|
|||
|
||||
char *pr_punctuation[] =
|
||||
// longer symbols must be before a shorter partial match
|
||||
{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "(+)", "(-)", "|=", "&~=", "&=", "++", "--", "->", "^=", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "><", "<<", "<", ">>", ">" , "?", "#" , "@", "&" , "|", "%", "^^", "^", "~", ":", NULL};
|
||||
{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "(+)", "(-)", "|=", "&~=", "&=", "++", "--", "->", "^=", "::", ";", ",", "!", "*^", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "><", "<<=", "<<", "<", ">>=", ">>", ">" , "?", "#" , "@", "&" , "|", "%", "^^", "^", "~", ":", NULL};
|
||||
|
||||
char *pr_punctuationremap[] = //a nice bit of evilness.
|
||||
//(+) -> |=
|
||||
//-> -> .
|
||||
//(-) -> &~=
|
||||
{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "|=", "&~=", "|=", "&~=", "&=", "++", "--", ".", "^=", "::", ";", ",", "!", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "><", "<<", "<", ">>", ">" , "?", "#" , "@", "&" , "|", "%", "^^", "^", "~", ":", NULL};
|
||||
{"&&", "||", "<=", ">=","==", "!=", "/=", "*=", "+=", "-=", "|=", "&~=", "|=", "&~=", "&=", "++", "--", ".", "^=", "::", ";", ",", "!", "*^", "*", "/", "(", ")", "-", "+", "=", "[", "]", "{", "}", "...", "..", ".", "><", "<<=", "<<", "<", ">>=", ">>", ">" , "?", "#" , "@", "&" , "|", "%", "^^", "^", "~", ":", NULL};
|
||||
|
||||
// simple types. function types are dynamically allocated
|
||||
QCC_type_t *type_void; //void
|
||||
|
@ -473,7 +473,7 @@ static void QCC_PR_GetDefinesListEnumerate(void *vctx, void *data)
|
|||
QC_snprintfz(term, sizeof(term), "\n%s", def->name);
|
||||
if (def->numparams >= 0)
|
||||
{
|
||||
unsigned int i;
|
||||
int i;
|
||||
QC_strlcat(term, "(", sizeof(term));
|
||||
for (i = 0; i < def->numparams; i++)
|
||||
{
|
||||
|
@ -989,11 +989,10 @@ pbool QCC_PR_Precompiler(void)
|
|||
pr_file_p++;
|
||||
}
|
||||
msg[a] = 0;
|
||||
pr_file_p++;
|
||||
|
||||
QCC_FindBestInclude(msg, compilingfile, false);
|
||||
|
||||
pr_file_p++;
|
||||
|
||||
QCC_PR_SkipToEndOfLine(true);
|
||||
}
|
||||
else if (!strncmp(directive, "datafile", 8))
|
||||
|
@ -1866,6 +1865,7 @@ void QCC_PR_LexString (void)
|
|||
|
||||
if (qccwarningaction[WARN_NOTUTF8])
|
||||
{
|
||||
size_t c;
|
||||
for (c = 0; c < pr_immediate_strlen; )
|
||||
{
|
||||
len = utf8_check(&pr_token[c], &code);
|
||||
|
@ -2243,8 +2243,9 @@ void QCC_PR_LexPunctuation (void)
|
|||
pr_token_type = tt_punct;
|
||||
|
||||
if (pr_file_p[0] == '*' && pr_file_p[1] == '*' && flag_dblstarexp)
|
||||
{
|
||||
strcpy (pr_token, "**");
|
||||
{ //for compat with gmqcc. fteqcc uses *^ internally (which does not conflict with multiplying by dereferenced pointers - sucks for MSCLR c++ syntax)
|
||||
QCC_PR_ParseWarning(WARN_GMQCC_SPECIFIC, "** operator conflicts with pointers. Consider using *^ instead.", pr_token);
|
||||
strcpy (pr_token, "*^");
|
||||
pr_file_p += 2;
|
||||
return;
|
||||
}
|
||||
|
@ -2896,7 +2897,7 @@ void QCC_PR_PreProcessor_Define(pbool append)
|
|||
{
|
||||
char *exploitcheck;
|
||||
s++;
|
||||
QCC_PR_NewLine(false);
|
||||
QCC_PR_NewLine(true);
|
||||
s++;
|
||||
if( s[-1] == '\r' && s[0] == '\n' )
|
||||
{
|
||||
|
@ -2921,7 +2922,7 @@ foo\nbar\nmoo
|
|||
so if present, the preceeding \\\n and following \\\n must become an actual \n instead of being stripped.
|
||||
*/
|
||||
|
||||
for (exploitcheck = s; *exploitcheck && qcc_iswhite(*exploitcheck); exploitcheck++)
|
||||
for (exploitcheck = s; *exploitcheck && qcc_iswhitesameline(*exploitcheck); exploitcheck++)
|
||||
;
|
||||
if (*exploitcheck == '#')
|
||||
{
|
||||
|
@ -3454,7 +3455,12 @@ int QCC_PR_CheckCompConst(void)
|
|||
}
|
||||
}
|
||||
else
|
||||
QCC_PR_ParseError(ERR_TOOFEWPARAMS, "Macro without argument list");
|
||||
{
|
||||
//QCC_PR_ParseError(ERR_TOOFEWPARAMS, "Macro without argument list");
|
||||
pr_file_p = initial_file_p;
|
||||
pr_source_line = initial_line;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3726,7 +3732,11 @@ static void QCC_PR_PrintMacro (qcc_includechunk_t *chunk)
|
|||
QCC_PR_PrintMacro(chunk->prev);
|
||||
if (chunk->cnst)
|
||||
{
|
||||
#if 1
|
||||
printf ("%s:%i: %s is defined here\n", chunk->cnst->fromfile, chunk->cnst->fromline, chunk->cnst->name);
|
||||
#else
|
||||
printf ("%s:%i: expanding %s\n", chunk->currentfilename, chunk->currentlinenumber, chunk->cnst->name);
|
||||
#endif
|
||||
if (verbose)
|
||||
printf ("%s\n", chunk->datastart);
|
||||
}
|
||||
|
@ -4877,8 +4887,13 @@ QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s
|
|||
ftype->vargcount = false;
|
||||
for (i = 0; i < numargs; i++, p++)
|
||||
{
|
||||
p->paramname = qccHunkAlloc(strlen(args[i].paramname)+1);
|
||||
strcpy(p->paramname, args[i].paramname);
|
||||
if (args[i].paramname)
|
||||
{
|
||||
p->paramname = qccHunkAlloc(strlen(args[i].paramname)+1);
|
||||
strcpy(p->paramname, args[i].paramname);
|
||||
}
|
||||
else
|
||||
p->paramname = "";
|
||||
p->type = args[i].type;
|
||||
p->out = args[i].out;
|
||||
p->optional = args[i].optional;
|
||||
|
@ -5395,7 +5410,6 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
{
|
||||
pr_classtype = newt;
|
||||
QCC_PR_ParseInitializerDef(def, 0);
|
||||
QCC_FreeDef(def);
|
||||
pr_classtype = NULL;
|
||||
/*
|
||||
f = QCC_PR_ParseImmediateStatements (def, newparm);
|
||||
|
|
|
@ -281,6 +281,10 @@ typedef struct editor_s {
|
|||
int savefmt;
|
||||
time_t filemodifiedtime;
|
||||
struct editor_s *next;
|
||||
|
||||
//for avoiding silly redraws etc when titles don't actually change...
|
||||
int oldsavefmt;
|
||||
int oldline;
|
||||
} editor_t;
|
||||
editor_t *editors;
|
||||
|
||||
|
@ -2530,6 +2534,11 @@ static void UpdateEditorTitle(editor_t *editor)
|
|||
{
|
||||
char title[2048];
|
||||
char *encoding = "unknown";
|
||||
if (editor->oldsavefmt == editor->savefmt && editor->oldline == editor->curline)
|
||||
return; //nothing changed.
|
||||
editor->oldsavefmt = editor->savefmt;
|
||||
editor->oldline = editor->curline;
|
||||
|
||||
switch(editor->savefmt)
|
||||
{
|
||||
case UTF8_RAW:
|
||||
|
@ -2633,7 +2642,7 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
|||
|
||||
editor->tooltip = CreateWindowEx(0, TOOLTIPS_CLASS, NULL, WS_POPUP|TTS_ALWAYSTIP|TTS_NOPREFIX, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, NULL, ghInstance, NULL);
|
||||
if (editor->tooltip)
|
||||
{
|
||||
{
|
||||
TOOLINFO toolInfo = { 0 };
|
||||
toolInfo.cbSize = sizeof(toolInfo);
|
||||
toolInfo.hwnd = hWnd;
|
||||
|
@ -2844,7 +2853,7 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
|||
SendMessage(editor->editpane, SCI_CALLTIPCANCEL, 0, 0);
|
||||
break;
|
||||
}
|
||||
UpdateEditorTitle(editor);
|
||||
//UpdateEditorTitle(editor);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5513,6 +5522,7 @@ void OptionsDialog(void)
|
|||
tipwnd = CreateWindow(TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, optionsmenu, NULL, ghInstance, NULL);
|
||||
SetWindowPos(tipwnd, HWND_TOPMOST,0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
SendMessage(tipwnd, TTM_SETMAXTIPWIDTH, 0, 500);
|
||||
|
||||
subsection = CreateWindow("BUTTON", "Optimisations", WS_CHILD|WS_VISIBLE|BS_GROUPBOX,
|
||||
0, 0, 400, height-40*4+24, optionsmenu, NULL, ghInstance, NULL);
|
||||
|
@ -6941,6 +6951,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
ghInstance= hInstance;
|
||||
|
||||
GUI_SetDefaultOpts();
|
||||
GUI_ParseCommandLine(lpCmdLine);
|
||||
|
||||
strcpy(enginebinary, "");
|
||||
strcpy(enginebasedir, "");
|
||||
|
|
|
@ -213,6 +213,7 @@ struct {
|
|||
{" F318", WARN_DUPLICATEMACRO},
|
||||
{" F319", WARN_CONSTANTCOMPARISON},
|
||||
{" F320", WARN_PARAMWITHNONAME},
|
||||
{" F321", WARN_GMQCC_SPECIFIC},
|
||||
|
||||
{" F208", WARN_NOTREFERENCEDCONST},
|
||||
{" F209", WARN_EXTRAPRECACHE},
|
||||
|
@ -335,6 +336,7 @@ compiler_flag_t compiler_flag[] = {
|
|||
{&keyword_vector, defaultkeyword, "vector", "Keyword: vector", "Disables the 'vector' keyword."},
|
||||
{&keyword_wrap, defaultkeyword, "wrap", "Keyword: wrap", "Disables the 'wrap' keyword."},
|
||||
{&keyword_weak, defaultkeyword, "weak", "Keyword: weak", "Disables the 'weak' keyword."},
|
||||
{&keyword_accumulate, nondefaultkeyword,"accumulate", "Keyword: accumulate", "Disables the 'accumulate' keyword."},
|
||||
|
||||
//options
|
||||
{&keywords_coexist, FLAG_ASDEFAULT, "kce", "Keywords Coexist", "If you want keywords to NOT be disabled when they a variable by the same name is defined, check here."},
|
||||
|
@ -936,6 +938,8 @@ void QCC_DetermineNeededSymbols(QCC_def_t *endsyssym)
|
|||
{
|
||||
for (; sym; sym = sym->next)
|
||||
{
|
||||
if (sym->unused && !sym->initialized)
|
||||
sym->initialized = 1; //even if its not.
|
||||
sym->used = true;
|
||||
sym->referenced = true; //silence warnings about unreferenced things that can't be stripped
|
||||
if (sym == endsyssym)
|
||||
|
@ -973,9 +977,22 @@ void QCC_DetermineNeededSymbols(QCC_def_t *endsyssym)
|
|||
}
|
||||
}
|
||||
|
||||
const QCC_eval_t *QCC_SRef_EvalConst(QCC_sref_t ref);
|
||||
//allocates final space for the def, making it a true def
|
||||
void QCC_FinaliseDef(QCC_def_t *def)
|
||||
{
|
||||
//#define DEBUG_DUMP_GLOBALMAP
|
||||
#if defined(DEBUG_DUMP) || defined(DEBUG_DUMP_GLOBALMAP)
|
||||
int ssize = def->symbolsize;
|
||||
const QCC_eval_t *v;
|
||||
QCC_sref_t sr;
|
||||
#endif
|
||||
|
||||
if (def->symboldata == qcc_pr_globals + def->ofs)
|
||||
return; //was already finalised.
|
||||
|
||||
if (def->symbolheader != def)
|
||||
QCC_FinaliseDef(def->symbolheader);
|
||||
if (def->symbolheader == def && def->deftail)
|
||||
{
|
||||
//for head symbols, we go through and touch all of their children
|
||||
|
@ -1068,8 +1085,17 @@ void QCC_FinaliseDef(QCC_def_t *def)
|
|||
def->ofs += def->symbolheader->ofs;
|
||||
else
|
||||
{
|
||||
/* globalspertype[def->type->type].size += def->symbolsize;
|
||||
globalspertype[def->type->type].entries += 1;
|
||||
globalspertype[def->type->type].vars += !def->constant;
|
||||
globalspertype[def->type->type].consts += def->constant;
|
||||
*/
|
||||
if (def->ofs)
|
||||
QCC_Error(ERR_INTERNAL, "root symbol %s has an offset", def->name);
|
||||
|
||||
if (def->arraylengthprefix)
|
||||
{
|
||||
//for hexen2 arrays, we need to emit a length first
|
||||
if (numpr_globals+1+def->symbolsize >= MAX_REGS)
|
||||
{
|
||||
if (!opt_overlaptemps || !opt_locals_overlapping)
|
||||
|
@ -1077,20 +1103,21 @@ void QCC_FinaliseDef(QCC_def_t *def)
|
|||
else
|
||||
QCC_Error(ERR_TOOMANYGLOBALS, "numpr_globals exceeded MAX_REGS");
|
||||
}
|
||||
|
||||
//for hexen2 arrays, we need to emit a length first
|
||||
if (def->type->type == ev_vector)
|
||||
((int *)qcc_pr_globals)[numpr_globals] = def->arraysize-1;
|
||||
else
|
||||
((int *)qcc_pr_globals)[numpr_globals] = (def->arraysize*def->type->size)-1; //using float arrays for structs.
|
||||
numpr_globals+=1;
|
||||
}
|
||||
else if (numpr_globals+def->symbolsize >= MAX_REGS)
|
||||
else
|
||||
{
|
||||
if (!opt_overlaptemps || !opt_locals_overlapping)
|
||||
QCC_Error(ERR_TOOMANYGLOBALS, "numpr_globals exceeded MAX_REGS - you'll need to use more optimisations");
|
||||
else
|
||||
QCC_Error(ERR_TOOMANYGLOBALS, "numpr_globals exceeded MAX_REGS");
|
||||
if (numpr_globals+def->symbolsize >= MAX_REGS)
|
||||
{
|
||||
if (!opt_overlaptemps || !opt_locals_overlapping)
|
||||
QCC_Error(ERR_TOOMANYGLOBALS, "numpr_globals exceeded MAX_REGS - you'll need to use more optimisations");
|
||||
else
|
||||
QCC_Error(ERR_TOOMANYGLOBALS, "numpr_globals exceeded MAX_REGS");
|
||||
}
|
||||
}
|
||||
def->ofs += numpr_globals;
|
||||
numpr_globals += def->symbolsize;
|
||||
|
@ -1103,10 +1130,27 @@ void QCC_FinaliseDef(QCC_def_t *def)
|
|||
def->symboldata = qcc_pr_globals + def->ofs;
|
||||
def->symbolsize = numpr_globals - def->ofs;
|
||||
|
||||
#ifdef DEBUG_DUMP
|
||||
#ifdef DEBUG_DUMP_GLOBALMAP
|
||||
if (!def->referenced)
|
||||
printf("Unreferenced ");
|
||||
printf("Finalise %s(%p) @ %i+%i\n", def->name, def, def->ofs, ssize);
|
||||
sr.sym = def;
|
||||
sr.ofs = 0;
|
||||
sr.cast = def->type;
|
||||
v = QCC_SRef_EvalConst(sr);
|
||||
if (v && def->type->type == ev_float)
|
||||
printf("Finalise %s(%f) @ %i+%i\n", def->name, v->_float, def->ofs, ssize);
|
||||
else if (v && def->type->type == ev_vector)
|
||||
printf("Finalise %s(%f %f %f) @ %i+%i\n", def->name, v->vector[0], v->vector[1], v->vector[2], def->ofs, ssize);
|
||||
else if (v && def->type->type == ev_integer)
|
||||
printf("Finalise %s(%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize);
|
||||
else if (v && def->type->type == ev_function)
|
||||
printf("Finalise %s(@%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize);
|
||||
else if (v && def->type->type == ev_field)
|
||||
printf("Finalise %s(.%i) @ %i+%i\n", def->name, v->_int, def->ofs, ssize);
|
||||
else if (v && def->type->type == ev_string)
|
||||
printf("Finalise %s(%s) @ %i+%i\n", def->name, strings+v->_int, def->ofs, ssize);
|
||||
else
|
||||
printf("Finalise %s @ %i+%i\n", def->name, def->ofs, ssize);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1115,9 +1159,29 @@ void QCC_FinaliseDef(QCC_def_t *def)
|
|||
void QCC_UnmarshalLocals(void)
|
||||
{
|
||||
QCC_def_t *d;
|
||||
unsigned int onum, biggest, eog = numpr_globals;
|
||||
unsigned int onum, biggest, eog;
|
||||
size_t i;
|
||||
//first, finalize private locals.
|
||||
|
||||
//finalise all the globals that we've seen so far
|
||||
for (d = pr.def_head.next ; d ; d = d->next)
|
||||
{
|
||||
if (!d->localscope || d->isstatic)
|
||||
QCC_FinaliseDef(d);
|
||||
}
|
||||
|
||||
//first, finalize all static locals that shouldn't form part of the local defs.
|
||||
for (i=0 ; i<numfunctions ; i++)
|
||||
{
|
||||
if (functions[i].privatelocals)
|
||||
{
|
||||
for (d = functions[i].firstlocal; d; d = d->nextlocal)
|
||||
if (d->isstatic || (d->constant && d->initialized))
|
||||
QCC_FinaliseDef(d);
|
||||
}
|
||||
}
|
||||
|
||||
eog = numpr_globals;
|
||||
//next, finalize non-static locals.
|
||||
for (i=0 ; i<numfunctions ; i++)
|
||||
{
|
||||
if (functions[i].privatelocals)
|
||||
|
@ -1127,7 +1191,8 @@ void QCC_UnmarshalLocals(void)
|
|||
printf("function %s locals:\n", functions[i].name);
|
||||
#endif
|
||||
for (d = functions[i].firstlocal; d; d = d->nextlocal)
|
||||
QCC_FinaliseDef(d);
|
||||
if (!d->isstatic && !(d->constant && d->initialized))
|
||||
QCC_FinaliseDef(d);
|
||||
if (verbose >= VERBOSE_DEBUG)
|
||||
{
|
||||
if (onum == numpr_globals)
|
||||
|
@ -1294,13 +1359,10 @@ pbool QCC_WriteData (int crc)
|
|||
def = QCC_PR_GetDef(NULL, "end_sys_fields", NULL, false, 0, false);
|
||||
if (def)
|
||||
def->referenced = true;
|
||||
|
||||
QCC_PR_FinaliseFunctions();
|
||||
QCC_DetermineNeededSymbols(def);
|
||||
|
||||
for (def = pr.def_head.next ; def ; def = def->next)
|
||||
{
|
||||
if (!def->localscope)
|
||||
QCC_FinaliseDef(def);
|
||||
}
|
||||
QCC_UnmarshalLocals();
|
||||
QCC_FinaliseTemps();
|
||||
|
||||
|
@ -2003,7 +2065,7 @@ strofs = (strofs+3)&~3;
|
|||
{
|
||||
char line[2048];
|
||||
|
||||
QC_snprintfz(line, sizeof(line), "code: %s:%i: @%i %s t%i t%i %i (%s", QCC_FileForStatement(i), statements[i].linenum, i, pr_opcodes[statements[i].op].opname, a, b, c, QCC_VarAtOffset(statements[i].a));
|
||||
QC_snprintfz(line, sizeof(line), "code: %s:%i: @%i %s %i %i %i (%s", QCC_FileForStatement(i), statements[i].linenum, i, pr_opcodes[statements[i].op].opname, a, b, c, QCC_VarAtOffset(statements[i].a));
|
||||
QC_snprintfz(line+strlen(line), sizeof(line)-strlen(line), " %s", QCC_VarAtOffset(statements[i].b));
|
||||
QC_snprintfz(line+strlen(line), sizeof(line)-strlen(line), " %s)\n", QCC_VarAtOffset(statements[i].c));
|
||||
printf("%s", line);
|
||||
|
@ -2518,7 +2580,6 @@ static void QCC_MergeStatements16(dstatement16_t *in, unsigned int num)
|
|||
out->linenum = 0;
|
||||
numstatements++;
|
||||
}
|
||||
QCC_def_t *QCC_PR_DummyDef(QCC_type_t *type, char *name, QCC_function_t *scope, int arraysize, QCC_def_t *rootsymbol, unsigned int ofs, int referable, unsigned int flags);
|
||||
static etype_t QCC_MergeFindFieldType(unsigned int ofs, const char *fldname, ddef16_t *fields, size_t numfields)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -3120,6 +3181,11 @@ int QCC_PR_FinishCompilation (void)
|
|||
continue;
|
||||
}
|
||||
}
|
||||
if (d->unused)
|
||||
{
|
||||
d->initialized = 1;
|
||||
continue;
|
||||
}
|
||||
QCC_PR_Warning(ERR_NOFUNC, d->filen, d->s_line, "function %s has no body",d->name);
|
||||
QCC_PR_ParsePrintDef(ERR_NOFUNC, d);
|
||||
bodylessfuncs = true;
|
||||
|
@ -4027,7 +4093,21 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
|
|||
else
|
||||
*compiler_flag[p].enabled = false;
|
||||
}
|
||||
if (!strcmp(myargv[i]+5, "fteqcc"))
|
||||
if (!strcmp(myargv[i]+5, "qccx"))
|
||||
{
|
||||
flag_qccx = true; //fixme: extra stuff
|
||||
qccwarningaction[WARN_DENORMAL] = WA_IGNORE; //this is just too spammy
|
||||
qccwarningaction[WARN_LAXCAST] = WA_IGNORE; //more plausable, but still too spammy. easier to fix at least.
|
||||
}
|
||||
else if (!strcmp(myargv[i]+5, "preqcc"))
|
||||
{
|
||||
flag_hashonly = true;
|
||||
}
|
||||
else if (!strcmp(myargv[i]+5, "reacc"))
|
||||
{
|
||||
flag_acc = true;
|
||||
}
|
||||
else if (!strcmp(myargv[i]+5, "fteqcc"))
|
||||
; //as above, its the default.
|
||||
else if (!strcmp(myargv[i]+5, "id"))
|
||||
{
|
||||
|
@ -4537,10 +4617,11 @@ pbool QCC_main (int argc, char **argv) //as part of the quake engine
|
|||
MAX_GLOBALS = 1<<17;
|
||||
MAX_FIELDS = 1<<12;
|
||||
MAX_STATEMENTS = 0x80000;
|
||||
MAX_FUNCTIONS = 16384;
|
||||
MAX_FUNCTIONS = 32768;
|
||||
maxtypeinfos = 32768;
|
||||
MAX_CONSTANTS = 4096;
|
||||
|
||||
strcpy(destfile, "");
|
||||
compressoutput = 0;
|
||||
|
||||
p = externs->FileSize("qcc.cfg");
|
||||
|
|
|
@ -686,7 +686,7 @@ void PR_Deinit(void)
|
|||
|
||||
PRSV_ClearThreads();
|
||||
#ifdef VM_Q1
|
||||
Q1QVM_Shutdown();
|
||||
Q1QVM_Shutdown(true);
|
||||
#endif
|
||||
if (svprogfuncs)
|
||||
{
|
||||
|
@ -4197,7 +4197,12 @@ int PF_precache_sound_Internal (pubprogfuncs_t *prinst, const char *s)
|
|||
{
|
||||
if (!sv.strings.sound_precache[i])
|
||||
{
|
||||
sv.strings.sound_precache[i] = PR_AddString(prinst, s, 0, false);
|
||||
#ifdef VM_Q1
|
||||
if (svs.gametype == GT_Q1QVM)
|
||||
sv.strings.sound_precache[i] = s;
|
||||
else
|
||||
#endif
|
||||
sv.strings.sound_precache[i] = PR_AddString(prinst, s, 0, false);
|
||||
|
||||
/*touch the file, so any packs will be referenced*/
|
||||
FS_FLocateFile(s, FSLF_IFFOUND, NULL);
|
||||
|
|
|
@ -109,8 +109,8 @@ static struct
|
|||
qboolean triedlib;
|
||||
dllhandle_t lib;
|
||||
|
||||
lua_State * (QDECL *newstate) (lua_Alloc f, void *ud);
|
||||
lua_CFunction (QDECL *atpanic) (lua_State *L, lua_CFunction panicf);
|
||||
lua_State * (QDECL *newstate) (lua_Alloc f, void *ud);
|
||||
lua_CFunction (QDECL *atpanic) (lua_State *L, lua_CFunction panicf);
|
||||
void (QDECL *close) (lua_State *L);
|
||||
int (QDECL *load) (lua_State *L, lua_Reader reader, void *dt, const char *chunkname, const char *mode);
|
||||
int (QDECL *pcallk) (lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k);
|
||||
|
@ -150,22 +150,22 @@ static struct
|
|||
|
||||
int (QDECL *Lcallmeta) (lua_State *L, int obj, const char *e);
|
||||
int (QDECL *Lnewmetatable) (lua_State *L, const char *tname);
|
||||
} lua;
|
||||
} lua;
|
||||
#define pcall(L,n,r,f) pcallk(L, (n), (r), (f), 0, NULL)
|
||||
#define call(L,n,r) callk(L, (n), (r), 0, NULL)
|
||||
#define pop(L,n) settop(L, -(n)-1)
|
||||
#define pushstring(L,s) pushfstring(L,"%s",s)
|
||||
|
||||
#define LUA_TNONE (-1)
|
||||
#define LUA_TNIL 0
|
||||
#define LUA_TBOOLEAN 1
|
||||
#define LUA_TLIGHTUSERDATA 2
|
||||
#define LUA_TNUMBER 3
|
||||
#define LUA_TSTRING 4
|
||||
#define LUA_TTABLE 5
|
||||
#define LUA_TFUNCTION 6
|
||||
#define LUA_TUSERDATA 7
|
||||
#define LUA_TTHREAD 8
|
||||
#define LUA_TNONE (-1)
|
||||
#define LUA_TNIL 0
|
||||
#define LUA_TBOOLEAN 1
|
||||
#define LUA_TLIGHTUSERDATA 2
|
||||
#define LUA_TNUMBER 3
|
||||
#define LUA_TSTRING 4
|
||||
#define LUA_TTABLE 5
|
||||
#define LUA_TFUNCTION 6
|
||||
#define LUA_TUSERDATA 7
|
||||
#define LUA_TTHREAD 8
|
||||
#define LUA_NUMTAGS 9
|
||||
|
||||
#define LUA_REGISTRYINDEX (-1000000 - 1000)
|
||||
|
@ -506,13 +506,13 @@ static int my_lua_entity_get(lua_State *L) //__index
|
|||
lua.pushinteger(L, eval->_int);
|
||||
return 1;
|
||||
case ev_vector:
|
||||
lua.createtable(L, 0, 0);
|
||||
//FIXME: should provide a metatable with a __tostring
|
||||
lua.pushnumber(L, eval->_vector[0]);
|
||||
lua.setfield (L, -2, "x");
|
||||
lua.pushnumber(L, eval->_vector[1]);
|
||||
lua.setfield (L, -2, "y");
|
||||
lua.pushnumber(L, eval->_vector[2]);
|
||||
lua.createtable(L, 0, 0);
|
||||
//FIXME: should provide a metatable with a __tostring
|
||||
lua.pushnumber(L, eval->_vector[0]);
|
||||
lua.setfield (L, -2, "x");
|
||||
lua.pushnumber(L, eval->_vector[1]);
|
||||
lua.setfield (L, -2, "y");
|
||||
lua.pushnumber(L, eval->_vector[2]);
|
||||
lua.setfield (L, -2, "z");
|
||||
return 1;
|
||||
case ev_function:
|
||||
|
@ -1147,13 +1147,13 @@ static int bi_lua_vectoangles(lua_State *L)
|
|||
}
|
||||
VectorAngles(forward, up, ret);
|
||||
|
||||
lua.createtable(L, 0, 0);
|
||||
//FIXME: should provide a metatable with a __tostring
|
||||
lua.pushnumber(L, ret[0]);
|
||||
lua.setfield (L, -2, "x");
|
||||
lua.pushnumber(L, ret[1]);
|
||||
lua.setfield (L, -2, "y");
|
||||
lua.pushnumber(L, ret[2]);
|
||||
lua.createtable(L, 0, 0);
|
||||
//FIXME: should provide a metatable with a __tostring
|
||||
lua.pushnumber(L, ret[0]);
|
||||
lua.setfield (L, -2, "x");
|
||||
lua.pushnumber(L, ret[1]);
|
||||
lua.setfield (L, -2, "y");
|
||||
lua.pushnumber(L, ret[2]);
|
||||
lua.setfield (L, -2, "z");
|
||||
return 1;
|
||||
}
|
||||
|
@ -1509,35 +1509,35 @@ static int bi_lua_loadlua(lua_State *L)
|
|||
|
||||
#define registerfunc(n) lua.pushcclosure(L, bi_lua_##n, 0); lua.setglobal(L, #n);
|
||||
static void my_lua_registerbuiltins(lua_State *L)
|
||||
{
|
||||
lua.atpanic (L, my_lua_panic);
|
||||
|
||||
//standard lua library replacement
|
||||
//this avoids the risk of including any way to access os.execute etc, or other file access.
|
||||
lua.pushcclosure(L, my_lua_tostring, 0);
|
||||
lua.setglobal(L, "tostring");
|
||||
lua.pushcclosure(L, my_lua_print, 0);
|
||||
lua.setglobal(L, "print");
|
||||
|
||||
lua.pushcclosure(L, my_lua_conprint, 0); //for the luls.
|
||||
lua.setglobal(L, "conprint");
|
||||
|
||||
registerfunc(loadlua);
|
||||
|
||||
registerfunc(setmodel);
|
||||
registerfunc(precache_model);
|
||||
registerfunc(precache_sound);
|
||||
registerfunc(lightstyle);
|
||||
registerfunc(spawn);
|
||||
registerfunc(remove);
|
||||
{
|
||||
lua.atpanic (L, my_lua_panic);
|
||||
|
||||
//standard lua library replacement
|
||||
//this avoids the risk of including any way to access os.execute etc, or other file access.
|
||||
lua.pushcclosure(L, my_lua_tostring, 0);
|
||||
lua.setglobal(L, "tostring");
|
||||
lua.pushcclosure(L, my_lua_print, 0);
|
||||
lua.setglobal(L, "print");
|
||||
|
||||
lua.pushcclosure(L, my_lua_conprint, 0); //for the luls.
|
||||
lua.setglobal(L, "conprint");
|
||||
|
||||
registerfunc(loadlua);
|
||||
|
||||
registerfunc(setmodel);
|
||||
registerfunc(precache_model);
|
||||
registerfunc(precache_sound);
|
||||
registerfunc(lightstyle);
|
||||
registerfunc(spawn);
|
||||
registerfunc(remove);
|
||||
registerfunc(nextent);
|
||||
registerfunc(nextclient);
|
||||
//registerfunc(AIM);
|
||||
registerfunc(makestatic);
|
||||
registerfunc(setorigin);
|
||||
registerfunc(setsize);
|
||||
|
||||
registerfunc(dprint);
|
||||
registerfunc(makestatic);
|
||||
registerfunc(setorigin);
|
||||
registerfunc(setsize);
|
||||
|
||||
registerfunc(dprint);
|
||||
registerfunc(bprint);
|
||||
registerfunc(sprint);
|
||||
registerfunc(centerprint);
|
||||
|
@ -1602,20 +1602,20 @@ static void my_lua_registerbuiltins(lua_State *L)
|
|||
|
||||
//registerfunc(PRECACHE_VWEP_MODEL);
|
||||
//registerfunc(SETPAUSE);
|
||||
|
||||
|
||||
|
||||
lua.createtable(L, 0, 0);
|
||||
if (lua.Lnewmetatable(L, "globals"))
|
||||
{
|
||||
lua.pushcclosure(L, my_lua_global_set, 0); //for the luls.
|
||||
lua.setfield (L, -2, "__newindex");
|
||||
|
||||
lua.pushcclosure(L, my_lua_global_get, 0); //for the luls.
|
||||
lua.setfield (L, -2, "__index");
|
||||
}
|
||||
lua.setmetatable(L, -2);
|
||||
lua.setglobal(L, "glob");
|
||||
|
||||
|
||||
|
||||
lua.createtable(L, 0, 0);
|
||||
if (lua.Lnewmetatable(L, "globals"))
|
||||
{
|
||||
lua.pushcclosure(L, my_lua_global_set, 0); //for the luls.
|
||||
lua.setfield (L, -2, "__newindex");
|
||||
|
||||
lua.pushcclosure(L, my_lua_global_get, 0); //for the luls.
|
||||
lua.setfield (L, -2, "__index");
|
||||
}
|
||||
lua.setmetatable(L, -2);
|
||||
lua.setglobal(L, "glob");
|
||||
}
|
||||
|
||||
|
||||
|
@ -1692,21 +1692,21 @@ static edict_t *Lua_DoRespawn(pubprogfuncs_t *pf, edict_t *e, int num)
|
|||
|
||||
//create a new table for the entity, give it a suitable metatable, and store it into the registry (avoiding GC and allowing us to actually hold on to it).
|
||||
lua.pushlightuserdata(L, lua.edicttable[num]);
|
||||
lua.createtable(L, 0, 0);
|
||||
if (lua.Lnewmetatable(L, "entity"))
|
||||
{
|
||||
lua.pushcclosure(L, my_lua_entity_set, 0); //known writes should change the internal info so the engine can use the information.
|
||||
lua.setfield (L, -2, "__newindex");
|
||||
|
||||
lua.pushcclosure(L, my_lua_entity_get, 0); //we need to de-translate the engine's fields too.
|
||||
lua.setfield (L, -2, "__index");
|
||||
|
||||
lua.pushcclosure(L, my_lua_entity_tostring, 0); //cos its prettier than seeing 'table 0x5425729' all over the place
|
||||
lua.setfield (L, -2, "__tostring");
|
||||
|
||||
lua.pushcclosure(L, my_lua_entity_eq, 0); //for comparisons, you know?
|
||||
lua.setfield (L, -2, "__eq");
|
||||
}
|
||||
lua.createtable(L, 0, 0);
|
||||
if (lua.Lnewmetatable(L, "entity"))
|
||||
{
|
||||
lua.pushcclosure(L, my_lua_entity_set, 0); //known writes should change the internal info so the engine can use the information.
|
||||
lua.setfield (L, -2, "__newindex");
|
||||
|
||||
lua.pushcclosure(L, my_lua_entity_get, 0); //we need to de-translate the engine's fields too.
|
||||
lua.setfield (L, -2, "__index");
|
||||
|
||||
lua.pushcclosure(L, my_lua_entity_tostring, 0); //cos its prettier than seeing 'table 0x5425729' all over the place
|
||||
lua.setfield (L, -2, "__tostring");
|
||||
|
||||
lua.pushcclosure(L, my_lua_entity_eq, 0); //for comparisons, you know?
|
||||
lua.setfield (L, -2, "__eq");
|
||||
}
|
||||
lua.setmetatable(L, -2);
|
||||
lua.pushinteger(L, num);
|
||||
lua.setfield (L, -2, "entnum"); //so we know which entity it is.
|
||||
|
|
|
@ -43,22 +43,20 @@ oh, wait, ktx no longer supports those properly.
|
|||
|
||||
#include "pr_common.h"
|
||||
|
||||
#define GAME_API_VERSION 13
|
||||
/*version changes:
|
||||
13: 2009/june gamecode no longer aware of edict_t data (just 'qc' fields).
|
||||
14: 2017/march gamedata_t.maxentities added
|
||||
15: 2017/june for-64bit string indirection changes. added GAME_CLEAR_EDICT.
|
||||
*/
|
||||
#define GAME_API_VERSION 15
|
||||
#define GAME_API_VERSION_MIN 8
|
||||
#define MAX_Q1QVM_EDICTS 768 //according to ktx at api version 12 (fte's protocols go to 2048)
|
||||
#define MAPNAME_LEN 64
|
||||
|
||||
void PR_SV_FillWorldGlobals(world_t *w);
|
||||
|
||||
#if GAME_API_VERSION >= 13
|
||||
#define WASTED_EDICT_T_SIZE (VM_NonNative(q1qvm)?sizeof(int):sizeof(void*))
|
||||
//in version 13, the actual edict_t struct is gone, and there's a pointer to it in its place (which we don't need, but it changes size based on vm/native).
|
||||
#else
|
||||
//this is probably broken on 64bit native code
|
||||
#define WASTED_EDICT_T_SIZE 114
|
||||
//qclib has split edict_t and entvars_t.
|
||||
//mvdsv and the api we're implementing has them in one lump
|
||||
//so we need to bias our entvars_t and fake the offsets a little.
|
||||
#endif
|
||||
static int qvm_api_version;
|
||||
static size_t wasted_edict_t_size;
|
||||
|
||||
//===============================================================
|
||||
|
||||
|
@ -209,6 +207,8 @@ typedef enum
|
|||
GAME_EDICT_BLOCKED, //(self,other)
|
||||
GAME_CLIENT_SAY, //(int isteam)
|
||||
GAME_PAUSED_TIC, //(int milliseconds)
|
||||
|
||||
GAME_CLEAR_EDICT, //v15 (sets self.fields to safe values after they're cleared)
|
||||
} q1qvmgameExport_t;
|
||||
|
||||
|
||||
|
@ -320,6 +320,9 @@ typedef struct
|
|||
unsigned int global;
|
||||
unsigned int fields;
|
||||
int APIversion;
|
||||
#if GAME_API_VERSION >= 14
|
||||
unsigned int maxentities;
|
||||
#endif
|
||||
} gameData32_t;
|
||||
|
||||
typedef struct
|
||||
|
@ -329,6 +332,9 @@ typedef struct
|
|||
quintptr_t global;
|
||||
quintptr_t fields;
|
||||
int APIversion;
|
||||
#if GAME_API_VERSION >= 14
|
||||
unsigned int maxentities;
|
||||
#endif
|
||||
} gameDataN_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -354,10 +360,18 @@ typedef enum {
|
|||
|
||||
|
||||
#define emufields \
|
||||
emufield(gravity, F_FLOAT) \
|
||||
emufield(maxspeed, F_FLOAT) \
|
||||
emufield(movement, F_VECTOR) \
|
||||
emufield(vw_index, F_FLOAT)
|
||||
emufield(gravity, F_FLOAT) \
|
||||
emufield(maxspeed, F_FLOAT) \
|
||||
emufield(movement, F_VECTOR) \
|
||||
emufield(vw_index, F_FLOAT) \
|
||||
emufield(isBot, F_INT)
|
||||
// emufield(items2, F_FLOAT)
|
||||
// emufield(brokenankle, F_FLOAT)
|
||||
// emufield(mod_admin, F_INT)
|
||||
// emufield(hideentity, F_INT)
|
||||
// emufield(trackent, F_INT)
|
||||
// emufield(hideplayers, F_INT)
|
||||
// emufield(visclients, F_INT)
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -371,7 +385,7 @@ static const char *q1qvmentstring;
|
|||
static vm_t *q1qvm;
|
||||
static pubprogfuncs_t q1qvmprogfuncs;
|
||||
|
||||
|
||||
static q1qvmglobalvars_t *gvars;
|
||||
static void *evars; //pointer to the gamecodes idea of an edict_t
|
||||
static quintptr_t vevars; //offset into the vm base of evars
|
||||
|
||||
|
@ -399,7 +413,7 @@ static edict_t *QDECL Q1QVMPF_EdictNum(pubprogfuncs_t *pf, unsigned int num)
|
|||
if (!e)
|
||||
{
|
||||
e = q1qvmprogfuncs.edicttable[num] = Z_TagMalloc(sizeof(edict_t)+sizeof(extentvars_t), VMFSID_Q1QVM);
|
||||
e->v = (stdentvars_t*)((char*)evars + (num * sv.world.edict_size) + WASTED_EDICT_T_SIZE);
|
||||
e->v = (stdentvars_t*)((char*)evars + (num * sv.world.edict_size) + wasted_edict_t_size);
|
||||
e->xv = (extentvars_t*)(e+1);
|
||||
e->entnum = num;
|
||||
}
|
||||
|
@ -428,7 +442,14 @@ static void Q1QVMED_ClearEdict (edict_t *e, qboolean wipe)
|
|||
{
|
||||
int num = e->entnum;
|
||||
if (wipe)
|
||||
memset (e->v, 0, sv.world.edict_size - WASTED_EDICT_T_SIZE);
|
||||
memset (e->v, 0, sv.world.edict_size - wasted_edict_t_size);
|
||||
if (qvm_api_version >= 15)
|
||||
{
|
||||
int oself = pr_global_struct->self;
|
||||
pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, e);
|
||||
VM_Call(q1qvm, GAME_CLEAR_EDICT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
pr_global_struct->self = oself;
|
||||
}
|
||||
e->ereftype = ER_ENTITY;
|
||||
e->entnum = num;
|
||||
}
|
||||
|
@ -520,7 +541,7 @@ static eval_t *QDECL Q1QVMPF_GetEdictFieldValue(pubprogfuncs_t *pf, edict_t *e,
|
|||
{
|
||||
if (cache && !cache->varname)
|
||||
{
|
||||
return (eval_t*)((char*)e->v + cache->spare[0]-WASTED_EDICT_T_SIZE);
|
||||
return (eval_t*)((char*)e->v + cache->spare[0]-wasted_edict_t_size);
|
||||
}
|
||||
if (!strcmp(fieldname, "message"))
|
||||
{
|
||||
|
@ -560,13 +581,149 @@ static void *ASMCALL QDECL Q1QVMPF_PointerToNative(pubprogfuncs_t *prinst, quint
|
|||
|
||||
static const char *ASMCALL QDECL Q1QVMPF_StringToNative(pubprogfuncs_t *prinst, string_t str)
|
||||
{
|
||||
char *ret;
|
||||
quintptr_t ref;
|
||||
if (str == ~0)
|
||||
return " "; //models are weird. yes, this is a hack.
|
||||
if (!str || (quintptr_t)str >= VM_MemoryMask(q1qvm))
|
||||
if (qvm_api_version >= 15)
|
||||
{
|
||||
qboolean stringishacky = sizeof(quintptr_t) != sizeof(string_t) && qvm_api_version >= 15 && !VM_NonNative(q1qvm); //silly bullshit. Really, native gamecode should have its own implementation of this builtin or something, especially as its pretty much only ever used for classnames.
|
||||
if (!str)
|
||||
return ""; //invalid...
|
||||
else if (stringishacky)
|
||||
{
|
||||
if (str >= 0 && str < sv.world.edict_size*sv.world.max_edicts - sizeof(quintptr_t))
|
||||
ref = *(quintptr_t*)((char*)evars + (int)str); //extra indirection added in api 15.
|
||||
else
|
||||
return ""; //error
|
||||
}
|
||||
else
|
||||
{
|
||||
if (str >= 0 && str < sv.world.edict_size*sv.world.max_edicts - sizeof(quintptr_t))
|
||||
ref = *(string_t*)((char*)evars + (int)str); //extra indirection added in api 15.
|
||||
else
|
||||
return ""; //error
|
||||
}
|
||||
}
|
||||
else
|
||||
ref = str;
|
||||
if (!ref || (quintptr_t)ref >= VM_MemoryMask(q1qvm))
|
||||
return ""; //null or invalid pointers.
|
||||
ret = (char*)VM_MemoryBase(q1qvm) + str;
|
||||
return ret;
|
||||
return (char*)VM_MemoryBase(q1qvm) + ref;
|
||||
}
|
||||
static void QDECL Q1QVMPF_SetStringField(pubprogfuncs_t *progfuncs, struct edict_s *ed, string_t *fld, const char *str, pbool str_is_static)
|
||||
{
|
||||
if (!str_is_static)
|
||||
return;
|
||||
if (qvm_api_version >= 15)
|
||||
{
|
||||
qboolean stringishacky = sizeof(quintptr_t) != sizeof(string_t) && qvm_api_version >= 15 && !VM_NonNative(q1qvm); //silly bullshit. Really, native gamecode should have its own implementation of this builtin or something, especially as its pretty much only ever used for classnames.
|
||||
quintptr_t nval = (str - (char*)VM_MemoryBase(q1qvm));
|
||||
if (nval >= VM_MemoryMask(q1qvm))
|
||||
return;
|
||||
|
||||
if (!*fld)
|
||||
Con_DPrintf("Ignoring string set. mod pointer not set.\n");
|
||||
else if (stringishacky)
|
||||
{
|
||||
if (*fld >= 0 && *fld < sv.world.edict_size*sv.world.max_edicts - sizeof(quintptr_t))
|
||||
*(quintptr_t*)((char*)evars + *fld) = nval;
|
||||
else
|
||||
Con_DPrintf("Ignoring string set outside of progs VM\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nval >= 0xffffffff)
|
||||
return; //invalid string! blame 64bit.
|
||||
if (*fld >= 0 && *fld < sv.world.edict_size*sv.world.max_edicts - sizeof(string_t))
|
||||
*(string_t*)((char*)evars + *fld) = (string_t)nval;
|
||||
else
|
||||
Con_DPrintf("Ignoring string set outside of progs VM\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string_t newval = progfuncs->StringToProgs(progfuncs, str);
|
||||
if (newval || !str)
|
||||
*fld = newval;
|
||||
else if (!str)
|
||||
*fld = 0;
|
||||
else
|
||||
{
|
||||
*fld = ~0;
|
||||
//Con_DPrintf("Ignoring string set outside of progs VM\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Q1QVMPF_SetStringGlobal(pubprogfuncs_t *progfuncs, string_t *fld, const char *str, size_t copysize)
|
||||
{
|
||||
if (qvm_api_version >= 15)
|
||||
{
|
||||
qboolean stringishacky = sizeof(quintptr_t) != sizeof(string_t) && qvm_api_version >= 15 && !VM_NonNative(q1qvm); //silly bullshit. Really, native gamecode should have its own implementation of this builtin or something, especially as its pretty much only ever used for classnames.
|
||||
if (!*fld)
|
||||
Con_Printf("Q1QVM: string reference not set. Fix the mod.\n");
|
||||
else if (stringishacky)
|
||||
{ //quintptr_t
|
||||
// if (*fld >= 0 && *fld < sv.world.edict_size*sv.world.max_edicts - sizeof(intptr_t))
|
||||
{
|
||||
if (!*(quintptr_t*)((char*)gvars + *fld))
|
||||
{
|
||||
Con_DPrintf("String buffer not set. Hacking the data in instead.\n");
|
||||
*(quintptr_t*)((char*)gvars + *fld) = (str - (char*)VM_MemoryBase(q1qvm));
|
||||
}
|
||||
else
|
||||
{
|
||||
char *ptr = (char*)*(quintptr_t*)((char*)gvars + *fld);
|
||||
Q_strncpyz(ptr, str, copysize);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //string_t
|
||||
// if (*fld >= 0 && *fld < sv.world.edict_size*sv.world.max_edicts - sizeof(string_t))
|
||||
{
|
||||
if (!*(quintptr_t*)((char*)gvars + *fld))
|
||||
{
|
||||
quintptr_t nval = (str - (char*)VM_MemoryBase(q1qvm));;
|
||||
if (nval > VM_MemoryMask(q1qvm))
|
||||
{
|
||||
Con_Printf("Q1QVM: String buffer not set. Data out of QVM memory space. Fix the mod.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf("String buffer not set. Hacking the data in instead.\n");
|
||||
*(quintptr_t*)((char*)gvars + *fld) = (str - (char*)VM_MemoryBase(q1qvm));;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *ptr = (char*)*(quintptr_t*)((char*)gvars + *fld);
|
||||
Q_strncpyz(ptr, str, copysize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!*fld)
|
||||
{
|
||||
quintptr_t nval = (str - (char*)VM_MemoryBase(q1qvm));
|
||||
if (nval > VM_MemoryMask(q1qvm))
|
||||
{
|
||||
Con_Printf("Q1QVM: String buffer not set. Data out of QVM memory space. Fix the mod.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf("String buffer not set. Hacking the data in instead.\n");
|
||||
*fld = (str - (char*)VM_MemoryBase(q1qvm));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char *ptr = (char*)VM_MemoryBase(q1qvm) + *fld;
|
||||
Q_strncpyz(ptr, str, copysize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int WrapQCBuiltin(builtin_t func, void *offset, quintptr_t mask, const qintptr_t *arg, char *argtypes)
|
||||
|
@ -607,7 +764,7 @@ static int WrapQCBuiltin(builtin_t func, void *offset, quintptr_t mask, const qi
|
|||
#define VALIDATEPOINTER(o,l) if ((qintptr_t)o + l >= mask || VM_POINTER(o) < offset) SV_Error("Call to game trap passes invalid pointer\n"); //out of bounds.
|
||||
static qintptr_t QVM_GetAPIVersion (void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
return GAME_API_VERSION;
|
||||
return qvm_api_version;
|
||||
}
|
||||
|
||||
static qintptr_t QVM_DPrint (void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
|
@ -1245,26 +1402,30 @@ static qintptr_t QVM_strnicmp (void *offset, quintptr_t mask, const qintptr_t *a
|
|||
static qintptr_t QVM_Find (void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
edict_t *e = VM_POINTER(arg[0]);
|
||||
int ofs = VM_LONG(arg[1]) - WASTED_EDICT_T_SIZE;
|
||||
int ofs = (VM_LONG(arg[1]) - wasted_edict_t_size);
|
||||
char *match = VM_POINTER(arg[2]);
|
||||
char *field;
|
||||
int first = e?((char*)e - (char*)evars)/sv.world.edict_size:0;
|
||||
int i;
|
||||
qboolean stringishacky = sizeof(quintptr_t) != sizeof(string_t) && qvm_api_version >= 15 && !VM_NonNative(q1qvm); //silly bullshit. Really, native gamecode should have its own implementation of this builtin or something, especially as its pretty much only ever used for classnames.
|
||||
if (!match)
|
||||
match = "";
|
||||
for (i = first+1; i < sv.world.num_edicts; i++)
|
||||
{
|
||||
e = q1qvmprogfuncs.edicttable[i];
|
||||
field = VM_POINTER(*((string_t*)e->v + ofs/4));
|
||||
if (stringishacky)
|
||||
field = VM_POINTER(*(quintptr_t*)((char*)e->v + ofs));
|
||||
else
|
||||
field = VM_POINTER(*(string_t*)((char*)e->v + ofs));
|
||||
if (field == NULL)
|
||||
{
|
||||
if (*match == '\0')
|
||||
return ((char*)e->v - (char*)offset)-WASTED_EDICT_T_SIZE;
|
||||
return ((char*)e->v - (char*)offset)-wasted_edict_t_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!strcmp(field, match))
|
||||
return ((char*)e->v - (char*)offset)-WASTED_EDICT_T_SIZE;
|
||||
return ((char*)e->v - (char*)offset)-wasted_edict_t_size;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1346,26 +1507,93 @@ static qintptr_t QVM_RedirectCmd (void *offset, quintptr_t mask, const qintptr_t
|
|||
}
|
||||
static qintptr_t QVM_Add_Bot (void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
char *name = VM_POINTER(arg[0]);
|
||||
int bottom = VM_LONG(arg[1]);
|
||||
int top = VM_LONG(arg[2]);
|
||||
char *skin = VM_POINTER(arg[3]);
|
||||
|
||||
#if 1
|
||||
extern int nextuserid;
|
||||
int i;
|
||||
for (i = 0; i < sv.allocated_client_slots; i++)
|
||||
{
|
||||
client_t *cl = &svs.clients[i];
|
||||
if (!*cl->name && !cl->protocol && cl->state == cs_free)
|
||||
{
|
||||
cl->userid = ++nextuserid;
|
||||
cl->protocol = SCP_BAD; //marker for bots
|
||||
cl->state = cs_spawned;
|
||||
cl->spawned = true;
|
||||
sv.spawned_client_slots++;
|
||||
cl->netchan.message.allowoverflow = true;
|
||||
cl->netchan.message.maxsize = 0;
|
||||
cl->datagram.allowoverflow = true;
|
||||
cl->datagram.maxsize = 0;
|
||||
|
||||
cl->edict = EDICT_NUM(sv.world.progs, i+1);
|
||||
|
||||
Info_SetValueForKey(cl->userinfo, "name", name, sizeof(cl->userinfo));
|
||||
Info_SetValueForKey(cl->userinfo, "topcolor", va("%i", top), sizeof(cl->userinfo));
|
||||
Info_SetValueForKey(cl->userinfo, "bottomcolor", va("%i", bottom), sizeof(cl->userinfo));
|
||||
Info_SetValueForKey(cl->userinfo, "skin", skin, sizeof(cl->userinfo));
|
||||
Info_SetValueForStarKey(cl->userinfo, "*bot", "1", sizeof(cl->userinfo));
|
||||
SV_ExtractFromUserinfo(cl, true);
|
||||
SV_SetUpClientEdict (cl, cl->edict);
|
||||
|
||||
SV_FullClientUpdate(cl, NULL);
|
||||
Q1QVM_ClientConnect(cl);
|
||||
|
||||
return cl->edict->entnum;
|
||||
}
|
||||
}
|
||||
#else
|
||||
//FIXME: not implemented, always returns failure.
|
||||
//the other bot functions only ever work on bots anyway, so don't need to be implemented until this one is
|
||||
|
||||
//return WrapQCBuiltin(PF_spawnclient, offset, mask, arg, "");
|
||||
Con_DPrintf("QVM_Add_Bot: not implemented\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
static qintptr_t QVM_Remove_Bot (void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
//fixme: should become general kick
|
||||
//kicks NOW. which generally makes it unsafe for players (calling from StartFrame should be okay).
|
||||
int entnum = VM_LONG(arg[0]);
|
||||
if (entnum >= 1 && entnum <= svs.allocated_client_slots)
|
||||
{
|
||||
client_t *cl = &svs.clients[entnum-1];
|
||||
SV_DropClient(cl);
|
||||
}
|
||||
|
||||
Con_DPrintf("QVM_Remove_Bot: not implemented\n");
|
||||
|
||||
//WrapQCBuiltin(PF_dropclient, offset, mask, arg, "n");
|
||||
return 0;
|
||||
}
|
||||
static qintptr_t QVM_SetBotCMD (void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
{
|
||||
//in mvdsv, this is run *after* the frame.
|
||||
Con_DPrintf("QVM_SetBotCMD: not implemented\n");
|
||||
//this just queues the command for later, even in mvdsv. ignore the msecs value because its basically pointless
|
||||
int edn = VM_LONG(arg[0]);
|
||||
int msec = VM_LONG(arg[1]);
|
||||
float angles_x = VM_FLOAT(arg[2]);
|
||||
float angles_y = VM_FLOAT(arg[3]);
|
||||
float angles_z = VM_FLOAT(arg[4]);
|
||||
int forwardmove = VM_LONG(arg[5]);
|
||||
int sidemove = VM_LONG(arg[6]);
|
||||
int upmove = VM_LONG(arg[7]);
|
||||
int buttons = VM_LONG(arg[8]);
|
||||
int impulse = VM_LONG(arg[9]);
|
||||
|
||||
if (edn >= 1 && edn <= svs.allocated_client_slots)
|
||||
{
|
||||
client_t *cl = &svs.clients[edn-1];
|
||||
cl->lastcmd.msec = msec;
|
||||
cl->lastcmd.angles[0] = ANGLE2SHORT(angles_x);
|
||||
cl->lastcmd.angles[1] = ANGLE2SHORT(angles_y);
|
||||
cl->lastcmd.angles[2] = ANGLE2SHORT(angles_z);
|
||||
cl->lastcmd.forwardmove = forwardmove;
|
||||
cl->lastcmd.sidemove = sidemove;
|
||||
cl->lastcmd.upmove = upmove;
|
||||
cl->lastcmd.buttons = buttons;
|
||||
cl->lastcmd.impulse = impulse;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static qintptr_t QVM_SetUserInfo (void *offset, quintptr_t mask, const qintptr_t *arg)
|
||||
|
@ -1551,19 +1779,19 @@ static qintptr_t QVM_uri_query (void *offset, quintptr_t mask, const qintptr_t *
|
|||
|
||||
if (!pr_enable_uriget.ival)
|
||||
{
|
||||
Con_Printf("QVM_uri_query(\"%s\",%"PRIxPTR"): %s disabled\n", url, (qintptr_t)cb_context, pr_enable_uriget.name);
|
||||
Con_Printf("QVM_uri_query(\"%s\"): %s disabled\n", url, pr_enable_uriget.name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mimetype && *mimetype)
|
||||
{
|
||||
VALIDATEPOINTER(arg[4],datasize);
|
||||
Con_DPrintf("QVM_uri_query(%s,%"PRIxPTR")\n", url, (qintptr_t)cb_context);
|
||||
Con_DPrintf("QVM_uri_query(%s)\n", url);
|
||||
dl = HTTP_CL_Put(url, mimetype, data, datasize, QVM_uri_query_callback);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_DPrintf("QVM_uri_query(%s,%"PRIxPTR")\n", url, (qintptr_t)cb_context);
|
||||
Con_DPrintf("QVM_uri_query(%s)\n", url);
|
||||
dl = HTTP_CL_Get(url, NULL, QVM_uri_query_callback);
|
||||
}
|
||||
if (dl)
|
||||
|
@ -1740,8 +1968,8 @@ struct
|
|||
|
||||
//sql?
|
||||
//model querying?
|
||||
//skeletal objects/tags?
|
||||
//heightmap / brush editing?
|
||||
//custom stats (mod can always writebyte, I guess, sounds horrible though)
|
||||
//csqc ents
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
@ -1823,7 +2051,7 @@ static qintptr_t EXPORT_FN syscallnative (qintptr_t arg, ...)
|
|||
return traps[arg](NULL, ~(quintptr_t)0, args);
|
||||
}
|
||||
|
||||
void Q1QVM_Shutdown(void)
|
||||
void Q1QVM_Shutdown(qboolean notifygame)
|
||||
{
|
||||
int i;
|
||||
if (q1qvm)
|
||||
|
@ -1834,7 +2062,8 @@ void Q1QVM_Shutdown(void)
|
|||
Q_strncpyz(svs.clients[i].namebuf, svs.clients[i].name, sizeof(svs.clients[i].namebuf));
|
||||
svs.clients[i].name = svs.clients[i].namebuf;
|
||||
}
|
||||
VM_Call(q1qvm, GAME_SHUTDOWN, 0, 0, 0);
|
||||
if (notifygame)
|
||||
VM_Call(q1qvm, GAME_SHUTDOWN, 0, 0, 0);
|
||||
VM_Destroy(q1qvm);
|
||||
q1qvm = NULL;
|
||||
VM_fcloseall(VMFSID_Q1QVM);
|
||||
|
@ -1850,6 +2079,25 @@ void Q1QVM_Shutdown(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void QDECL Q1QVM_Get_FrameState(world_t *w, wedict_t *ent, framestate_t *fstate)
|
||||
{
|
||||
memset(fstate, 0, sizeof(*fstate));
|
||||
fstate->g[FS_REG].frame[0] = ent->v->frame;
|
||||
fstate->g[FS_REG].frametime[0] = ent->xv->frame1time;
|
||||
fstate->g[FS_REG].lerpweight[0] = 1;
|
||||
fstate->g[FS_REG].endbone = 0x7fffffff;
|
||||
|
||||
fstate->g[FST_BASE].frame[0] = ent->xv->baseframe;
|
||||
fstate->g[FST_BASE].frametime[0] = ent->xv->/*base*/frame1time;
|
||||
fstate->g[FST_BASE].lerpweight[0] = 1;
|
||||
fstate->g[FST_BASE].endbone = ent->xv->basebone;
|
||||
|
||||
#if defined(SKELETALOBJECTS) || defined(RAGDOLL)
|
||||
if (ent->xv->skeletonindex)
|
||||
skel_lookup(w, ent->xv->skeletonindex, fstate);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void QDECL Q1QVM_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
|
||||
{
|
||||
int oself = pr_global_struct->self;
|
||||
|
@ -1876,20 +2124,6 @@ static qboolean QDECL Q1QVM_Event_ContentsTransition(world_t *w, wedict_t *ent,
|
|||
return false; //always do legacy behaviour
|
||||
}
|
||||
|
||||
static void QDECL Q1QVMPF_SetStringField(pubprogfuncs_t *progfuncs, struct edict_s *ed, string_t *fld, const char *str, pbool str_is_static)
|
||||
{
|
||||
string_t newval = progfuncs->StringToProgs(progfuncs, str);
|
||||
if (newval || !str)
|
||||
*fld = newval;
|
||||
else if (!str)
|
||||
*fld = 0;
|
||||
else
|
||||
{
|
||||
*fld = ~0;
|
||||
// Con_DPrintf("Ignoring string set outside of progs VM\n");
|
||||
}
|
||||
}
|
||||
|
||||
qboolean PR_LoadQ1QVM(void)
|
||||
{
|
||||
static int writable_int;
|
||||
|
@ -1902,12 +2136,11 @@ qboolean PR_LoadQ1QVM(void)
|
|||
gameDataPrivate_t gd;
|
||||
gameDataN_t *gdn;
|
||||
gameData32_t *gd32;
|
||||
q1qvmglobalvars_t *global;
|
||||
qintptr_t ret;
|
||||
qintptr_t limit;
|
||||
extern cvar_t pr_maxedicts;
|
||||
|
||||
Q1QVM_Shutdown();
|
||||
Q1QVM_Shutdown(true);
|
||||
|
||||
q1qvm = VM_Create("qwprogs", com_nogamedirnativecode.ival?NULL:syscallnative, syscallqvm);
|
||||
if (!q1qvm)
|
||||
|
@ -1955,6 +2188,7 @@ qboolean PR_LoadQ1QVM(void)
|
|||
sv.world.Event_Sound = SVQ1_StartSound;
|
||||
sv.world.Event_ContentsTransition = Q1QVM_Event_ContentsTransition;
|
||||
sv.world.Get_CModel = SVPR_GetCModel;
|
||||
sv.world.Get_FrameState = Q1QVM_Get_FrameState;
|
||||
|
||||
sv.world.num_edicts = 0; //we're not ready for most of the builtins yet
|
||||
sv.world.max_edicts = 0; //so clear these out, just in case
|
||||
|
@ -1964,10 +2198,12 @@ qboolean PR_LoadQ1QVM(void)
|
|||
|
||||
q1qvmprogfuncs.stringtable = VM_MemoryBase(q1qvm);
|
||||
|
||||
qvm_api_version = GAME_API_VERSION;
|
||||
|
||||
ret = VM_Call(q1qvm, GAME_INIT, (qintptr_t)(sv.time*1000), rand(), 0, 0, 0);
|
||||
if (!ret)
|
||||
{
|
||||
Q1QVM_Shutdown();
|
||||
Q1QVM_Shutdown(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1982,7 +2218,10 @@ qboolean PR_LoadQ1QVM(void)
|
|||
gd.global = gd32->global;
|
||||
gd.fields = gd32->fields;
|
||||
|
||||
gd.maxedicts = pr_maxedicts.ival; //FIXME
|
||||
if (qvm_api_version >= 14)
|
||||
gd.maxedicts = gd32->maxentities;
|
||||
else
|
||||
gd.maxedicts = MAX_Q1QVM_EDICTS;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1994,7 +2233,30 @@ qboolean PR_LoadQ1QVM(void)
|
|||
gd.global = gdn->global;
|
||||
gd.fields = gdn->fields;
|
||||
|
||||
gd.maxedicts = pr_maxedicts.ival; //FIXME
|
||||
if (qvm_api_version >= 14)
|
||||
gd.maxedicts = gdn->maxentities;
|
||||
else
|
||||
gd.maxedicts = MAX_Q1QVM_EDICTS;
|
||||
}
|
||||
gd.maxedicts = bound(1, pr_maxedicts.ival, gd.maxedicts);
|
||||
|
||||
qvm_api_version = gd.APIversion;
|
||||
if (!(GAME_API_VERSION_MIN <= qvm_api_version && qvm_api_version <= GAME_API_VERSION))
|
||||
{
|
||||
Con_Printf("QVM-API version %i not supported\n", qvm_api_version);
|
||||
Q1QVM_Shutdown(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
//in version 13, the actual edict_t struct is gone, and there's a pointer to it in its place (which is unusable, and changes depending on modes).
|
||||
if (qvm_api_version)
|
||||
wasted_edict_t_size = (VM_NonNative(q1qvm)?sizeof(int):sizeof(void*));
|
||||
else
|
||||
{
|
||||
//fte/qclib has split edict_t and entvars_t.
|
||||
//older versions of the qvm api has them in one lump
|
||||
//so we need to bias the mod's entvars_t offsets a little.
|
||||
wasted_edict_t_size = 114;
|
||||
}
|
||||
|
||||
sv.world.num_edicts = 1;
|
||||
|
@ -2014,21 +2276,21 @@ qboolean PR_LoadQ1QVM(void)
|
|||
sv.world.edict_size = gd.sizeofent;
|
||||
vevars = gd.ents;
|
||||
evars = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, vevars);
|
||||
global = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, gd.global);
|
||||
gvars = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, gd.global);
|
||||
|
||||
if (!evars || !global)
|
||||
if (!evars || !gvars)
|
||||
{
|
||||
Q1QVM_Shutdown();
|
||||
Q1QVM_Shutdown(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
//WARNING: global is not remapped yet...
|
||||
//This code is written evilly, but works well enough
|
||||
#define globalint(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&global->name) //the logic of this is somewhat crazy
|
||||
#define globalfloat(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&global->name)
|
||||
#define globalstring(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&global->name)
|
||||
#define globalvec(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&global->name)
|
||||
#define globalfunc(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&global->name)
|
||||
#define globalint(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&gvars->name) //the logic of this is somewhat crazy
|
||||
#define globalfloat(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&gvars->name)
|
||||
#define globalstring(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&gvars->name)
|
||||
#define globalvec(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&gvars->name)
|
||||
#define globalfunc(required, name) pr_global_ptrs->name = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, (qintptr_t)&gvars->name)
|
||||
#define globalnull(required, name) pr_global_ptrs->name = NULL
|
||||
globalint (true, self); //we need the qw ones, but any in standard quake and not quakeworld, we don't really care about.
|
||||
globalint (true, other);
|
||||
|
@ -2084,6 +2346,9 @@ qboolean PR_LoadQ1QVM(void)
|
|||
pr_global_ptrs->physics_mode = &physics_mode;
|
||||
pr_global_ptrs->trace_brush_id = &writable_int;
|
||||
pr_global_ptrs->trace_brush_faceid = &writable_int;
|
||||
pr_global_ptrs->trace_surface_id = &writable_int;
|
||||
pr_global_ptrs->trace_bone_id = &writable_int;
|
||||
pr_global_ptrs->trace_triangle_id = &writable_int;
|
||||
pr_global_ptrs->global_gravitydir = &defaultgravity;
|
||||
|
||||
// ensureglobal(input_timelength, input_timelength_default);
|
||||
|
@ -2094,12 +2359,12 @@ qboolean PR_LoadQ1QVM(void)
|
|||
|
||||
dimensionsend = dimensiondefault = 255;
|
||||
for (i = 0; i < 16; i++)
|
||||
pr_global_ptrs->spawnparamglobals[i] = (float*)((char*)VM_MemoryBase(q1qvm)+(qintptr_t)(&global->parm1 + i));
|
||||
pr_global_ptrs->spawnparamglobals[i] = (float*)((char*)VM_MemoryBase(q1qvm)+(qintptr_t)(&gvars->parm1 + i));
|
||||
for (; i < NUM_SPAWN_PARMS; i++)
|
||||
pr_global_ptrs->spawnparamglobals[i] = NULL;
|
||||
pr_global_ptrs->parm_string = NULL;
|
||||
|
||||
#define emufield(n,t) if (field[i].type == t && !strcmp(#n, fname)) {fofs.n = (field[i].ofs - WASTED_EDICT_T_SIZE)/sizeof(float); continue;}
|
||||
#define emufield(n,t) if (field[i].type == t && !strcmp(#n, fname)) {fofs.n = (field[i].ofs - wasted_edict_t_size)/sizeof(float); continue;}
|
||||
if (VM_NonNative(q1qvm))
|
||||
{
|
||||
field32_t *field = Q1QVMPF_PointerToNative(&q1qvmprogfuncs, gd.fields);
|
||||
|
@ -2127,10 +2392,26 @@ qboolean PR_LoadQ1QVM(void)
|
|||
sv.world.edicts = (wedict_t*)Q1QVMPF_EdictNum(svprogfuncs, 0);
|
||||
sv.world.usesolidcorpse = true;
|
||||
|
||||
if ((quintptr_t)global->mapname && (quintptr_t)global->mapname+MAPNAME_LEN < VM_MemoryMask(q1qvm))
|
||||
Q_strncpyz((char*)VM_MemoryBase(q1qvm) + global->mapname, svs.name, MAPNAME_LEN);
|
||||
if (qvm_api_version >= 15)
|
||||
{
|
||||
int e;
|
||||
for (e = 0; e <= 32; e++)
|
||||
{
|
||||
pr_global_struct->self = Q1QVMPF_EdictToProgs(svprogfuncs, Q1QVMPF_EdictNum(svprogfuncs, e));
|
||||
VM_Call(q1qvm, GAME_CLEAR_EDICT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
||||
pr_global_struct->self = 0;
|
||||
|
||||
|
||||
Q1QVMPF_SetStringGlobal(sv.world.progs, &gvars->mapname, svs.name, MAPNAME_LEN);
|
||||
}
|
||||
else
|
||||
global->mapname = Q1QVMPF_StringToProgs(sv.world.progs, svs.name);
|
||||
{
|
||||
if ((quintptr_t)gvars->mapname && (quintptr_t)gvars->mapname+MAPNAME_LEN < VM_MemoryMask(q1qvm))
|
||||
Q_strncpyz((char*)VM_MemoryBase(q1qvm) + gvars->mapname, svs.name, MAPNAME_LEN);
|
||||
else
|
||||
gvars->mapname = Q1QVMPF_StringToProgs(sv.world.progs, svs.name);
|
||||
}
|
||||
|
||||
PR_SV_FillWorldGlobals(&sv.world);
|
||||
return true;
|
||||
|
@ -2141,12 +2422,25 @@ qboolean PR_LoadQ1QVM(void)
|
|||
|
||||
void Q1QVM_ClientConnect(client_t *cl)
|
||||
{
|
||||
if (cl->edict->v->netname)
|
||||
if (qvm_api_version >= 15 && !VM_NonNative(q1qvm))
|
||||
{
|
||||
strcpy(cl->namebuf, cl->name);
|
||||
cl->name = (char*)Q1QVMPF_StringToNative(svprogfuncs, cl->edict->v->netname);
|
||||
//FIXME: check this pointer
|
||||
strcpy(cl->name, cl->namebuf);
|
||||
Q_strncpyz(cl->namebuf, cl->name, sizeof(cl->namebuf));
|
||||
Q1QVMPF_SetStringField(sv.world.progs, cl->edict, &cl->edict->v->netname, cl->namebuf, true);
|
||||
}
|
||||
else if (cl->edict->v->netname)
|
||||
{
|
||||
char *name;
|
||||
char *base = VM_MemoryBase(q1qvm);
|
||||
quintptr_t mask = VM_MemoryMask(q1qvm);
|
||||
name = (char*)Q1QVMPF_StringToNative(svprogfuncs, cl->edict->v->netname);
|
||||
if (cl->name > base && cl->name < base+mask)
|
||||
{
|
||||
Q_strncpyz(cl->namebuf, name, sizeof(cl->namebuf));
|
||||
strcpy(name, cl->namebuf);
|
||||
cl->name = name; //so the gamecode can do changes if it wants.
|
||||
}
|
||||
else
|
||||
Con_Printf("WARNING: Mod provided no netname buffer. Player names will not be set properly.\n");
|
||||
}
|
||||
else if (!VM_NonNative(q1qvm))
|
||||
{
|
||||
|
@ -2160,9 +2454,11 @@ void Q1QVM_ClientConnect(client_t *cl)
|
|||
Con_Printf("WARNING: Mod provided no netname buffer. Player names will not be set properly.\n");
|
||||
|
||||
if (fofs.gravity)
|
||||
((float*)sv_player->v)[fofs.gravity] = sv_player->xv->gravity;
|
||||
((float*)cl->edict->v)[fofs.gravity] = cl->edict->xv->gravity;
|
||||
if (fofs.maxspeed)
|
||||
((float*)sv_player->v)[fofs.maxspeed] = sv_player->xv->maxspeed;
|
||||
((float*)cl->edict->v)[fofs.maxspeed] = cl->edict->xv->maxspeed;
|
||||
if (fofs.isBot)
|
||||
((float*)cl->edict->v)[fofs.isBot] = !cl->protocol;
|
||||
|
||||
// call the spawn function
|
||||
pr_global_struct->time = sv.world.physicstime;
|
||||
|
@ -2251,9 +2547,11 @@ void Q1QVM_PostThink(void)
|
|||
sv_player->xv->vw_index = ((float*)sv_player->v)[fofs.vw_index];
|
||||
}
|
||||
|
||||
void Q1QVM_StartFrame(void)
|
||||
void Q1QVM_StartFrame(qboolean botsarespecialsnowflakes)
|
||||
{
|
||||
VM_Call(q1qvm, GAME_START_FRAME, (qintptr_t)(sv.time*1000), 0, 0, 0);
|
||||
if (botsarespecialsnowflakes && qvm_api_version < 15)
|
||||
return; //this stupidity brought to you with api 15!
|
||||
VM_Call(q1qvm, GAME_START_FRAME, (qintptr_t)(sv.time*1000), botsarespecialsnowflakes, 0, 0);
|
||||
}
|
||||
|
||||
void Q1QVM_Blocked(void)
|
||||
|
|
|
@ -132,7 +132,7 @@ qboolean PR_LoadLua(void);
|
|||
#ifdef VM_Q1
|
||||
#define VMFSID_Q1QVM 57235 //the q1qvm zone tag that is freed when the module is purged.
|
||||
struct client_s;
|
||||
void Q1QVM_Shutdown(void);
|
||||
void Q1QVM_Shutdown(qboolean notifygame);
|
||||
qboolean PR_LoadQ1QVM(void);
|
||||
void Q1QVM_ClientConnect(struct client_s *cl);
|
||||
qboolean Q1QVM_GameConsoleCommand(void);
|
||||
|
@ -141,7 +141,7 @@ qboolean Q1QVM_UserInfoChanged(edict_t *player);
|
|||
void Q1QVM_PlayerPreThink(void);
|
||||
void Q1QVM_RunPlayerThink(void);
|
||||
void Q1QVM_PostThink(void);
|
||||
void Q1QVM_StartFrame(void);
|
||||
void Q1QVM_StartFrame(qboolean botsarespecialsnowflakes);
|
||||
void Q1QVM_Blocked(void);
|
||||
void Q1QVM_SetNewParms(void);
|
||||
void Q1QVM_SetChangeParms(void);
|
||||
|
|
|
@ -622,7 +622,7 @@ void SV_UnspawnServer (void) //terminate the running server.
|
|||
SVHL_ShutdownGame();
|
||||
#endif
|
||||
#ifdef VM_Q1
|
||||
Q1QVM_Shutdown();
|
||||
Q1QVM_Shutdown(true);
|
||||
#endif
|
||||
sv.world.worldmodel = NULL;
|
||||
sv.state = ss_dead;
|
||||
|
@ -1147,7 +1147,7 @@ void SV_SpawnServer (const char *server, const char *startspot, qboolean noents,
|
|||
#endif
|
||||
#ifdef VM_Q1
|
||||
if (newgametype != GT_Q1QVM)
|
||||
Q1QVM_Shutdown();
|
||||
Q1QVM_Shutdown(true);
|
||||
#endif
|
||||
|
||||
SV_UpdateMaxPlayers(0);
|
||||
|
|
|
@ -4647,7 +4647,7 @@ void SV_Impulse_f (void)
|
|||
|
||||
SV_SetUpClientEdict(&svs.clients[i], svs.clients[i].edict);
|
||||
|
||||
svs.clients[i].edict->v->netname = PR_SetString(svprogfuncs, "Console");
|
||||
svprogfuncs->SetStringField(svprogfuncs, svs.clients[i].edict, &svs.clients[i].edict->v->netname, "Console", true);
|
||||
|
||||
sv.skipbprintclient = &svs.clients[i];
|
||||
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, svs.clients[i].edict);
|
||||
|
@ -5439,7 +5439,7 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose)
|
|||
}
|
||||
}
|
||||
|
||||
if (!cl->drop && strncmp(val, cl->name, sizeof(cl->namebuf)-1))
|
||||
if (!cl->drop && strncmp(val, cl->name, sizeof(cl->namebuf)-1) && cl->state > cs_zombie)
|
||||
{
|
||||
if (*cl->name && cl->state >= cs_spawned && !cl->spectator && verbose)
|
||||
{
|
||||
|
|
|
@ -156,6 +156,19 @@ Handles cursor positioning, line wrapping, etc
|
|||
#define MAXPRINTMSG 4096
|
||||
// FIXME: make a buffer size safe vsprintf?
|
||||
#ifdef SERVERONLY
|
||||
vfsfile_t *con_pipe;
|
||||
vfsfile_t *Con_POpen(char *conname)
|
||||
{
|
||||
if (!conname || !*conname)
|
||||
{
|
||||
if (con_pipe)
|
||||
VFS_CLOSE(con_pipe);
|
||||
con_pipe = VFSPIPE_Open(2, false);
|
||||
return con_pipe;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void Con_PrintFromThread (void *ctx, void *data, size_t a, size_t b)
|
||||
{
|
||||
Con_Printf("%s", (char*)data);
|
||||
|
@ -188,6 +201,9 @@ void VARGS Con_Printf (const char *fmt, ...)
|
|||
|
||||
Sys_Printf ("%s", msg); // also echo to debugging console
|
||||
Con_Log(msg); // log to console
|
||||
|
||||
if (con_pipe)
|
||||
VFS_PUTS(con_pipe, msg);
|
||||
}
|
||||
void Con_TPrintf (translation_t stringnum, ...)
|
||||
{
|
||||
|
@ -227,6 +243,9 @@ void Con_TPrintf (translation_t stringnum, ...)
|
|||
|
||||
Sys_Printf ("%s", msg); // also echo to debugging console
|
||||
Con_Log(msg); // log to console
|
||||
|
||||
if (con_pipe)
|
||||
VFS_PUTS(con_pipe, msg);
|
||||
}
|
||||
/*
|
||||
================
|
||||
|
@ -2706,9 +2725,10 @@ qboolean SV_SendClientDatagram (client_t *client)
|
|||
#endif
|
||||
}
|
||||
|
||||
msg.maxsize = clientlimit;
|
||||
// copy the accumulated multicast datagram
|
||||
// for this client out to the message
|
||||
if (!client->datagram.overflowed && msg.cursize + client->datagram.cursize <= clientlimit)
|
||||
if (!client->datagram.overflowed && !msg.overflowed && msg.cursize + client->datagram.cursize <= clientlimit)
|
||||
{
|
||||
SZ_Write (&msg, client->datagram.data, client->datagram.cursize);
|
||||
SZ_Clear (&client->datagram);
|
||||
|
|
|
@ -1110,34 +1110,64 @@ void ApplyColour(unsigned int chr)
|
|||
//this could be much more efficient.
|
||||
static void Sys_PrintColouredChars(conchar_t *start, conchar_t *end)
|
||||
{
|
||||
conchar_t m;
|
||||
wchar_t wc[256];
|
||||
int l;
|
||||
DWORD dummy;
|
||||
unsigned int cp, flags, m;
|
||||
|
||||
m = CON_WHITEMASK;
|
||||
l = 0;
|
||||
|
||||
while(start < end)
|
||||
{
|
||||
l = 0;
|
||||
m = *start & CON_FLAGSMASK;
|
||||
for (;;)
|
||||
start = Font_Decode(start, &flags, &cp);
|
||||
|
||||
if (l+2 >= countof(wc) || flags != m)
|
||||
{
|
||||
if (start == end || m != (*start & CON_FLAGSMASK) || l >= countof(wc))
|
||||
ApplyColour(m);
|
||||
if (WinNT)
|
||||
WriteConsoleW(hconsoleout, wc, l, &dummy, NULL);
|
||||
else
|
||||
{
|
||||
ApplyColour(m);
|
||||
if (WinNT)
|
||||
WriteConsoleW(hconsoleout, wc, l, &dummy, NULL);
|
||||
else
|
||||
{
|
||||
//win95 doesn't support wide chars *sigh*. blank consoles suck.
|
||||
char ac[256];
|
||||
l = WideCharToMultiByte(CP_ACP, 0, wc, l, ac, sizeof(ac), NULL, NULL);
|
||||
WriteConsole(hconsoleout, ac, l, &dummy, NULL);
|
||||
}
|
||||
break;
|
||||
//win95 doesn't support wide chars *sigh*. blank consoles suck.
|
||||
char ac[256];
|
||||
l = WideCharToMultiByte(CP_ACP, 0, wc, l, ac, sizeof(ac), NULL, NULL);
|
||||
WriteConsole(hconsoleout, ac, l, &dummy, NULL);
|
||||
}
|
||||
if (!(*start & CON_HIDDEN))
|
||||
wc[l++] = *start & CON_CHARMASK;
|
||||
start++;
|
||||
l = 0;
|
||||
}
|
||||
|
||||
if (!(flags & CON_HIDDEN))
|
||||
{
|
||||
if (cp >= 0xe000 && cp < 0xe100)
|
||||
{
|
||||
cp -= 0xe000;
|
||||
if (cp >= 0x80)
|
||||
{
|
||||
char c1[32] = "---..........> " "[]0123456789.---";
|
||||
cp -= 0x80;
|
||||
if (cp <= countof(c1))
|
||||
cp = c1[cp];
|
||||
}
|
||||
}
|
||||
if (cp > 0xffff)
|
||||
cp = '?'; //too lazy for utf-16 crap when its mostly smilies anyway.
|
||||
wc[l++] = cp;
|
||||
}
|
||||
}
|
||||
|
||||
//and flush it.
|
||||
if (l)
|
||||
{
|
||||
ApplyColour(m);
|
||||
if (WinNT)
|
||||
WriteConsoleW(hconsoleout, wc, l, &dummy, NULL);
|
||||
else
|
||||
{
|
||||
//win95 doesn't support wide chars *sigh*. blank consoles suck.
|
||||
char ac[256];
|
||||
l = WideCharToMultiByte(CP_ACP, 0, wc, l, ac, sizeof(ac), NULL, NULL);
|
||||
WriteConsole(hconsoleout, ac, l, &dummy, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5393,7 +5393,7 @@ static void SVNQ_Spawn_f (void)
|
|||
|
||||
ent->v->colormap = NUM_FOR_EDICT(svprogfuncs, ent);
|
||||
ent->v->team = 0; // FIXME
|
||||
ent->v->netname = PR_SetString(svprogfuncs, host_client->name);
|
||||
svprogfuncs->SetStringField(svprogfuncs, ent, &ent->v->netname, host_client->name, true);
|
||||
|
||||
host_client->entgravity = ent->xv->gravity = 1.0;
|
||||
host_client->entgravity*=sv_gravity.value;
|
||||
|
@ -7585,9 +7585,9 @@ void SV_ExecuteClientMessage (client_t *cl)
|
|||
if (split)
|
||||
split->lossage = cl->lossage;
|
||||
}
|
||||
MSG_ReadDeltaUsercmd (&nullcmd, &oldest);
|
||||
MSG_ReadDeltaUsercmd (&oldest, &oldcmd);
|
||||
MSG_ReadDeltaUsercmd (&oldcmd, &newcmd);
|
||||
MSG_ReadDeltaUsercmd (&nullcmd, &oldest, PROTOCOL_VERSION_QW);
|
||||
MSG_ReadDeltaUsercmd (&oldest, &oldcmd, PROTOCOL_VERSION_QW);
|
||||
MSG_ReadDeltaUsercmd (&oldcmd, &newcmd, PROTOCOL_VERSION_QW);
|
||||
if (!split)
|
||||
break; // either someone is trying to cheat, or they sent input commands for splitscreen clients they no longer own.
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
!!permu SPECULAR
|
||||
!!permu REFLECTCUBEMASK
|
||||
!!cvarf r_glsl_offsetmapping_scale
|
||||
!!cvarf gl_specular
|
||||
!!cvardf r_tessellation_level=5
|
||||
!!samps diffuse lightmap specular normalmap fullbright reflectmask reflectcube paletted lightmap1 lightmap2 lightmap3
|
||||
|
||||
|
@ -230,9 +229,6 @@ void main()
|
|||
#define s_colourmap s_t0
|
||||
uniform sampler2D s_colourmap;
|
||||
|
||||
#ifdef SPECULAR
|
||||
uniform float cvar_gl_specular;
|
||||
#endif
|
||||
#ifdef OFFSETMAPPING
|
||||
#include "sys/offsetmapping.h"
|
||||
#endif
|
||||
|
@ -298,7 +294,7 @@ void main ()
|
|||
vec3 delux = (texture2D(s_deluxmap, lm0).rgb-0.5);
|
||||
#ifdef BUMPMODELSPACE
|
||||
delux = normalize(delux*invsurface);
|
||||
#else
|
||||
#else
|
||||
lightmaps *= 2.0 / max(0.25, delux.z); //counter the darkening from deluxmaps
|
||||
#endif
|
||||
lightmaps *= dot(norm, delux);
|
||||
|
@ -312,7 +308,7 @@ void main ()
|
|||
#ifdef SPECULAR
|
||||
vec4 specs = texture2D(s_specular, tc);
|
||||
vec3 halfdir = normalize(normalize(eyevector) + delux); //this norm should be the deluxemap info instead
|
||||
float spec = pow(max(dot(halfdir, norm), 0.0), 2.0*FTE_SPECULAR_EXPONENT * specs.a);
|
||||
float spec = pow(max(dot(halfdir, norm), 0.0), FTE_SPECULAR_EXPONENT * specs.a);
|
||||
spec *= FTE_SPECULAR_MULTIPLIER;
|
||||
//NOTE: rtlights tend to have a *4 scaler here to over-emphasise the effect because it looks cool.
|
||||
//As not all maps will have deluxemapping, and the double-cos from the light util makes everything far too dark anyway,
|
||||
|
@ -322,7 +318,7 @@ void main ()
|
|||
#endif
|
||||
|
||||
#ifdef REFLECTCUBEMASK
|
||||
vec3 rtc = reflect(-eyevector, norm);
|
||||
vec3 rtc = reflect(normalize(-eyevector), norm);
|
||||
rtc = rtc.x*invsurface[0] + rtc.y*invsurface[1] + rtc.z*invsurface[2];
|
||||
rtc = (m_model * vec4(rtc.xyz,0.0)).xyz;
|
||||
gl_FragColor.rgb += texture2D(s_reflectmask, tc).rgb * textureCube(s_reflectcube, rtc).rgb;
|
||||
|
@ -364,3 +360,4 @@ void main ()
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,6 @@
|
|||
#include "xmpp.h"
|
||||
#ifdef JINGLE
|
||||
static struct c2c_s *JCL_JingleAddContentToSession(jclient_t *jcl, struct c2c_s *c2c, char *with, bresource_t *bres, qboolean creator, char *sid, char *cname, int method, int mediatype)
|
||||
static struct c2c_s *JCL_JingleAddContentToSession(jclient_t *jcl, struct c2c_s *c2c, const char *with, bresource_t *bres, qboolean creator, const char *sid, const char *cname, int method, int mediatype)
|
||||
{
|
||||
struct icestate_s *ice = NULL;
|
||||
char generatedname[64];
|
||||
|
@ -186,7 +186,7 @@ enum
|
|||
JE_UNKNOWNSESSION,
|
||||
JE_UNSUPPORTEDINFO
|
||||
};
|
||||
static void JCL_JingleError(jclient_t *jcl, xmltree_t *tree, char *from, char *id, int type)
|
||||
static void JCL_JingleError(jclient_t *jcl, xmltree_t *tree, const char *from, const char *id, int type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
|
@ -522,7 +522,7 @@ void JCL_JingleTimeouts(jclient_t *jcl, qboolean killall)
|
|||
}
|
||||
}
|
||||
|
||||
void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int protocol)
|
||||
void JCL_Join(jclient_t *jcl, const char *target, const char *sid, qboolean allow, int protocol)
|
||||
{
|
||||
struct c2c_s *c2c = NULL, **link;
|
||||
char autotarget[256];
|
||||
|
@ -618,7 +618,7 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto
|
|||
}
|
||||
}
|
||||
|
||||
static void JCL_JingleParsePeerPorts(jclient_t *jcl, struct c2c_s *c2c, xmltree_t *inj, char *from, char *sid)
|
||||
static void JCL_JingleParsePeerPorts(jclient_t *jcl, struct c2c_s *c2c, xmltree_t *inj, const char *from, const char *sid)
|
||||
{
|
||||
xmltree_t *incontent;
|
||||
xmltree_t *intransport;
|
||||
|
@ -626,7 +626,7 @@ static void JCL_JingleParsePeerPorts(jclient_t *jcl, struct c2c_s *c2c, xmltree_
|
|||
struct icecandinfo_s rem;
|
||||
struct icestate_s *ice;
|
||||
int i, contid;
|
||||
char *cname;
|
||||
const char *cname;
|
||||
|
||||
if (!c2c->sid)
|
||||
return;
|
||||
|
@ -665,7 +665,7 @@ static void JCL_JingleParsePeerPorts(jclient_t *jcl, struct c2c_s *c2c, xmltree_
|
|||
|
||||
for (i = 0; (incandidate = XML_ChildOfTree(intransport, "candidate", i)); i++)
|
||||
{
|
||||
char *s;
|
||||
const char *s;
|
||||
memset(&rem, 0, sizeof(rem));
|
||||
Q_strlcpy(rem.addr, XML_GetParameter(incandidate, "ip", ""), sizeof(rem.addr));
|
||||
Q_strlcpy(rem.candidateid, XML_GetParameter(incandidate, "id", ""), sizeof(rem.candidateid));
|
||||
|
@ -869,12 +869,12 @@ static qboolean JCL_JingleHandleInitiate_GoogleSession(jclient_t *jcl, xmltree_t
|
|||
return true;
|
||||
}
|
||||
#endif
|
||||
static struct c2c_s *JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, char *from)
|
||||
static struct c2c_s *JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, const char *from)
|
||||
{
|
||||
char *sid = XML_GetParameter(inj, "sid", "");
|
||||
const char *sid = XML_GetParameter(inj, "sid", "");
|
||||
|
||||
qboolean okay;
|
||||
char *initiator;
|
||||
const char *initiator;
|
||||
|
||||
struct c2c_s *c2c = NULL;
|
||||
int mt = ICEP_INVALID;
|
||||
|
@ -894,12 +894,12 @@ static struct c2c_s *JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, ch
|
|||
for (i = 0; ; i++)
|
||||
{
|
||||
xmltree_t *incontent = XML_ChildOfTree(inj, "content", i);
|
||||
char *cname = XML_GetParameter(incontent, "name", "");
|
||||
const char *cname = XML_GetParameter(incontent, "name", "");
|
||||
xmltree_t *intransport = XML_ChildOfTree(incontent, "transport", 0);
|
||||
xmltree_t *indescription = XML_ChildOfTree(incontent, "description", 0);
|
||||
char *transportxmlns = intransport?intransport->xmlns:"";
|
||||
char *descriptionxmlns = indescription?indescription->xmlns:"";
|
||||
char *descriptionmedia = XML_GetParameter(indescription, "media", "");
|
||||
const char *transportxmlns = intransport?intransport->xmlns:"";
|
||||
const char *descriptionxmlns = indescription?indescription->xmlns:"";
|
||||
const char *descriptionmedia = XML_GetParameter(indescription, "media", "");
|
||||
if (!incontent)
|
||||
break;
|
||||
|
||||
|
@ -907,7 +907,7 @@ static struct c2c_s *JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, ch
|
|||
|
||||
if (incontent && !strcmp(descriptionmedia, MEDIATYPE_QUAKE) && !strcmp(descriptionxmlns, QUAKEMEDIAXMLNS))
|
||||
{
|
||||
char *host = XML_GetParameter(indescription, "host", "you");
|
||||
const char *host = XML_GetParameter(indescription, "host", "you");
|
||||
if (!strcmp(host, "you"))
|
||||
mt = ICEP_QWSERVER;
|
||||
else if (!strcmp(host, "me"))
|
||||
|
@ -938,9 +938,9 @@ static struct c2c_s *JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, ch
|
|||
//chuck it at the engine and see what sticks. at least one must...
|
||||
while((payload = XML_ChildOfTree(indescription, "payload-type", i++)))
|
||||
{
|
||||
char *name = XML_GetParameter(payload, "name", "");
|
||||
char *clock = XML_GetParameter(payload, "clockrate", "");
|
||||
char *id = XML_GetParameter(payload, "id", "");
|
||||
const char *name = XML_GetParameter(payload, "name", "");
|
||||
const char *clock = XML_GetParameter(payload, "clockrate", "");
|
||||
const char *id = XML_GetParameter(payload, "id", "");
|
||||
char parm[64];
|
||||
char val[64];
|
||||
//note: the engine will ignore codecs it does not support, returning false.
|
||||
|
@ -1028,7 +1028,7 @@ static qboolean JCL_JingleHandleSessionTerminate(jclient_t *jcl, xmltree_t *tree
|
|||
free(c2c);
|
||||
return true;
|
||||
}
|
||||
static qboolean JCL_JingleHandleSessionAccept(jclient_t *jcl, xmltree_t *tree, char *from, struct c2c_s *c2c, buddy_t *b)
|
||||
static qboolean JCL_JingleHandleSessionAccept(jclient_t *jcl, xmltree_t *tree, const char *from, struct c2c_s *c2c, buddy_t *b)
|
||||
{
|
||||
//peer accepted our session
|
||||
//make sure it actually was ours, and not theirs. sneaky sneaky.
|
||||
|
@ -1053,7 +1053,7 @@ static qboolean JCL_JingleHandleSessionAccept(jclient_t *jcl, xmltree_t *tree, c
|
|||
}
|
||||
else
|
||||
{
|
||||
char *responder = XML_GetParameter(tree, "responder", from);
|
||||
const char *responder = XML_GetParameter(tree, "responder", from);
|
||||
int c;
|
||||
if (strcmp(responder, from))
|
||||
{
|
||||
|
@ -1134,10 +1134,10 @@ qboolean JCL_HandleGoogleSession(jclient_t *jcl, xmltree_t *tree, char *from, ch
|
|||
return true;
|
||||
}
|
||||
#endif
|
||||
qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id)
|
||||
qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, const char *from, const char *id)
|
||||
{
|
||||
char *action = XML_GetParameter(tree, "action", "");
|
||||
char *sid = XML_GetParameter(tree, "sid", "");
|
||||
const char *action = XML_GetParameter(tree, "action", "");
|
||||
const char *sid = XML_GetParameter(tree, "sid", "");
|
||||
|
||||
struct c2c_s *c2c = NULL, **link;
|
||||
buddy_t *b;
|
||||
|
|
|
@ -210,7 +210,7 @@ void XMPP_FT_AcceptFile(jclient_t *jcl, int fileid, qboolean accept)
|
|||
|
||||
static qboolean XMPP_FT_IBBChunked(jclient_t *jcl, xmltree_t *x, struct iq_s *iq)
|
||||
{
|
||||
char *from = XML_GetParameter(x, "from", jcl->domain);
|
||||
const char *from = XML_GetParameter(x, "from", jcl->domain);
|
||||
struct ft_s *ft = iq->usrptr, **link, *v;
|
||||
for (link = &jcl->ft; (v=*link); link = &(*link)->next)
|
||||
{
|
||||
|
@ -267,7 +267,7 @@ static qboolean XMPP_FT_IBBChunked(jclient_t *jcl, xmltree_t *x, struct iq_s *iq
|
|||
static qboolean XMPP_FT_IBBBegun(jclient_t *jcl, xmltree_t *x, struct iq_s *iq)
|
||||
{
|
||||
struct ft_s *ft = iq->usrptr, **link, *v;
|
||||
char *from = XML_GetParameter(x, "from", jcl->domain);
|
||||
const char *from = XML_GetParameter(x, "from", jcl->domain);
|
||||
for (link = &jcl->ft; (v=*link); link = &(*link)->next)
|
||||
{
|
||||
if (v == ft && !strcmp(ft->with, from))
|
||||
|
@ -296,7 +296,7 @@ static qboolean XMPP_FT_IBBBegun(jclient_t *jcl, xmltree_t *x, struct iq_s *iq)
|
|||
qboolean XMPP_FT_OfferAcked(jclient_t *jcl, xmltree_t *x, struct iq_s *iq)
|
||||
{
|
||||
struct ft_s *ft = iq->usrptr, **link, *v;
|
||||
char *from = XML_GetParameter(x, "from", jcl->domain);
|
||||
const char *from = XML_GetParameter(x, "from", jcl->domain);
|
||||
for (link = &jcl->ft; (v=*link); link = &(*link)->next)
|
||||
{
|
||||
if (v == ft && !strcmp(ft->with, from))
|
||||
|
@ -328,7 +328,7 @@ qboolean XMPP_FT_OfferAcked(jclient_t *jcl, xmltree_t *x, struct iq_s *iq)
|
|||
return false;
|
||||
}
|
||||
|
||||
void XMPP_FT_SendFile(jclient_t *jcl, char *console, char *to, char *fname)
|
||||
void XMPP_FT_SendFile(jclient_t *jcl, const char *console, const char *to, const char *fname)
|
||||
{
|
||||
xmltree_t *xsi, *xfile, *c;
|
||||
struct ft_s *ft;
|
||||
|
@ -371,7 +371,7 @@ void XMPP_FT_SendFile(jclient_t *jcl, char *console, char *to, char *fname)
|
|||
JCL_SendIQNode(jcl, XMPP_FT_OfferAcked, "set", to, xsi, true)->usrptr = ft;
|
||||
}
|
||||
|
||||
qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, char *iqfrom, char *iqid, xmltree_t *tree)
|
||||
qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, const char *iqfrom, const char *iqid, xmltree_t *tree)
|
||||
{
|
||||
xmltree_t *ot;
|
||||
|
||||
|
@ -384,17 +384,17 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, char *iqfrom, char *iqid, xmltree_t
|
|||
{
|
||||
xmltree_t *c;
|
||||
struct ft_s *ft;
|
||||
char *sid = XML_GetParameter(ot, "sid", "");
|
||||
const char *sid = XML_GetParameter(ot, "sid", "");
|
||||
for (ft = jcl->ft; ft; ft = ft->next)
|
||||
{
|
||||
if (!strcmp(ft->sid, sid) && !strcmp(ft->with, iqfrom))
|
||||
{
|
||||
if (ft->allowed && !ft->begun && ft->transmitting == false)
|
||||
{
|
||||
char *jid;
|
||||
char *host;
|
||||
const char *jid;
|
||||
const char *host;
|
||||
int port;
|
||||
char *mode = XML_GetParameter(ot, "mode", "tcp");
|
||||
const char *mode = XML_GetParameter(ot, "mode", "tcp");
|
||||
int i;
|
||||
if (strcmp(mode, "tcp"))
|
||||
break;
|
||||
|
@ -432,9 +432,9 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, char *iqfrom, char *iqid, xmltree_t
|
|||
if (ot)
|
||||
{
|
||||
struct ft_s *ft;
|
||||
char *sid = XML_GetParameter(ot, "sid", "");
|
||||
const char *sid = XML_GetParameter(ot, "sid", "");
|
||||
int blocksize = atoi(XML_GetParameter(ot, "block-size", "4096")); //technically this is required.
|
||||
char *stanza = XML_GetParameter(ot, "stanza", "iq");
|
||||
const char *stanza = XML_GetParameter(ot, "stanza", "iq");
|
||||
for (ft = jcl->ft; ft; ft = ft->next)
|
||||
{
|
||||
if (!strcmp(ft->sid, sid) && !strcmp(ft->with, iqfrom))
|
||||
|
@ -480,7 +480,7 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, char *iqfrom, char *iqid, xmltree_t
|
|||
if (ot)
|
||||
{
|
||||
struct ft_s **link, *ft;
|
||||
char *sid = XML_GetParameter(ot, "sid", "");
|
||||
const char *sid = XML_GetParameter(ot, "sid", "");
|
||||
for (link = &jcl->ft; *link; link = &(*link)->next)
|
||||
{
|
||||
ft = *link;
|
||||
|
@ -522,7 +522,7 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, char *iqfrom, char *iqid, xmltree_t
|
|||
if (ot)
|
||||
{
|
||||
char block[65536];
|
||||
char *sid = XML_GetParameter(ot, "sid", "");
|
||||
const char *sid = XML_GetParameter(ot, "sid", "");
|
||||
// unsigned short seq = atoi(XML_GetParameter(ot, "seq", "0"));
|
||||
int blocksize;
|
||||
struct ft_s *ft;
|
||||
|
@ -549,16 +549,16 @@ qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, char *iqfrom, char *iqid, xmltree_t
|
|||
ot = XML_ChildOfTreeNS(tree, "http://jabber.org/protocol/si", "si", 0);
|
||||
if (ot)
|
||||
{
|
||||
char *profile = XML_GetParameter(ot, "profile", "");
|
||||
const char *profile = XML_GetParameter(ot, "profile", "");
|
||||
|
||||
if (!strcmp(profile, "http://jabber.org/protocol/si/profile/file-transfer"))
|
||||
{
|
||||
// char *mimetype = XML_GetParameter(ot, "mime-type", "text/plain");
|
||||
char *sid = XML_GetParameter(ot, "id", "");
|
||||
const char *sid = XML_GetParameter(ot, "id", "");
|
||||
xmltree_t *file = XML_ChildOfTreeNS(ot, "http://jabber.org/protocol/si/profile/file-transfer", "file", 0);
|
||||
char *fname = XML_GetParameter(file, "name", "file.txt");
|
||||
const char *fname = XML_GetParameter(file, "name", "file.txt");
|
||||
// char *date = XML_GetParameter(file, "date", "");
|
||||
char *md5hash = XML_GetParameter(file, "hash", "");
|
||||
const char *md5hash = XML_GetParameter(file, "hash", "");
|
||||
int fsize = strtoul(XML_GetParameter(file, "size", "0"), NULL, 0);
|
||||
// char *desc = XML_GetChildBody(file, "desc", "");
|
||||
char authlink[512];
|
||||
|
|
|
@ -7,7 +7,7 @@ void (*Con_TrySubPrint)(const char *conname, const char *message);
|
|||
|
||||
void XML_Destroy(xmltree_t *t);
|
||||
|
||||
char *XML_GetParameter(xmltree_t *t, char *paramname, char *def)
|
||||
const char *XML_GetParameter(xmltree_t *t, const char *paramname, const char *def)
|
||||
{
|
||||
xmlparams_t *p;
|
||||
if (t)
|
||||
|
@ -18,11 +18,11 @@ char *XML_GetParameter(xmltree_t *t, char *paramname, char *def)
|
|||
}
|
||||
return def;
|
||||
}
|
||||
void XML_AddParameter(xmltree_t *t, char *paramname, char *value)
|
||||
void XML_AddParameter(xmltree_t *t, const char *paramname, const char *value)
|
||||
{
|
||||
xmlparams_t *p = malloc(sizeof(xmlparams_t));
|
||||
Q_strlcpy(p->name, paramname, sizeof(p->name));
|
||||
Q_strlcpy(p->val, value, sizeof(p->val));
|
||||
Q_strlcpy(p->val, value?value:"", sizeof(p->val));
|
||||
|
||||
if (t->params) //reverse insert
|
||||
{
|
||||
|
@ -38,17 +38,24 @@ void XML_AddParameter(xmltree_t *t, char *paramname, char *value)
|
|||
t->params = p;
|
||||
}
|
||||
}
|
||||
void XML_AddParameteri(xmltree_t *t, char *paramname, int value)
|
||||
void XML_AddParameteri(xmltree_t *t, const char *paramname, int value)
|
||||
{
|
||||
char svalue[64];
|
||||
Q_snprintf(svalue, sizeof(svalue), "%i", value);
|
||||
XML_AddParameter(t, paramname, svalue);
|
||||
}
|
||||
xmltree_t *XML_CreateNode(xmltree_t *parent, char *name, char *xmlns, char *body)
|
||||
xmltree_t *XML_CreateNode(xmltree_t *parent, const char *name, const char *xmlns, const char *body)
|
||||
{
|
||||
int bodylen = strlen(body);
|
||||
int bodylen;
|
||||
struct subtree_s *node = malloc(sizeof(*node));
|
||||
|
||||
if (!body)
|
||||
body = "";
|
||||
if (!xmlns)
|
||||
xmlns = "";
|
||||
|
||||
bodylen = strlen(body);
|
||||
|
||||
//clear out links
|
||||
node->params = NULL;
|
||||
node->child = NULL;
|
||||
|
@ -101,7 +108,7 @@ const struct
|
|||
};
|
||||
//converts < to < etc.
|
||||
//returns the end of d.
|
||||
char *XML_Markup(char *s, char *d, int dlen)
|
||||
char *XML_Markup(const char *s, char *d, int dlen)
|
||||
{
|
||||
int i;
|
||||
dlen--;
|
||||
|
@ -248,7 +255,7 @@ char *XML_GenerateString(xmltree_t *root, qboolean readable)
|
|||
buf_cat(&buf, "", 1);
|
||||
return buf.buf;
|
||||
}
|
||||
xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronly, char *defaultnamespace)
|
||||
xmltree_t *XML_Parse(const char *buffer, int *startpos, int maxpos, qboolean headeronly, const char *defaultnamespace)
|
||||
{
|
||||
xmlparams_t *p;
|
||||
xmltree_t *child;
|
||||
|
@ -258,8 +265,8 @@ xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronl
|
|||
int bodymax = 0;
|
||||
int pos, i;
|
||||
char *tagend;
|
||||
char *tagstart;
|
||||
char *ns;
|
||||
const char *tagstart;
|
||||
const char *ns;
|
||||
char token[1024];
|
||||
pos = *startpos;
|
||||
while (buffer[pos] >= '\0' && buffer[pos] <= ' ')
|
||||
|
@ -337,11 +344,9 @@ skippedcomment:
|
|||
ns = strchr(token, ':');
|
||||
if (ns)
|
||||
{
|
||||
*ns = 0;
|
||||
ns++;
|
||||
|
||||
memcpy(ret->xmlns, "xmlns:", 6);
|
||||
Q_strlcpy(ret->xmlns+6, token, sizeof(ret->xmlns)-6);
|
||||
Q_strlncpy(ret->xmlns+6, token, sizeof(ret->xmlns)-6, ns-token);
|
||||
ns++;
|
||||
Q_strlcpy(ret->name, ns, sizeof(ret->name));
|
||||
}
|
||||
else
|
||||
|
@ -589,7 +594,7 @@ void XML_Destroy(xmltree_t *t)
|
|||
free(t);
|
||||
}
|
||||
|
||||
xmltree_t *XML_ChildOfTree(xmltree_t *t, char *name, int childnum)
|
||||
xmltree_t *XML_ChildOfTree(xmltree_t *t, const char *name, int childnum)
|
||||
{
|
||||
if (t)
|
||||
{
|
||||
|
@ -604,7 +609,7 @@ xmltree_t *XML_ChildOfTree(xmltree_t *t, char *name, int childnum)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
xmltree_t *XML_ChildOfTreeNS(xmltree_t *t, char *xmlns, char *name, int childnum)
|
||||
xmltree_t *XML_ChildOfTreeNS(xmltree_t *t, const char *xmlns, const char *name, int childnum)
|
||||
{
|
||||
if (t)
|
||||
{
|
||||
|
@ -619,7 +624,7 @@ xmltree_t *XML_ChildOfTreeNS(xmltree_t *t, char *xmlns, char *name, int childnum
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
char *XML_GetChildBody(xmltree_t *t, char *paramname, char *def)
|
||||
const char *XML_GetChildBody(xmltree_t *t, const char *paramname, const char *def)
|
||||
{
|
||||
xmltree_t *c = XML_ChildOfTree(t, paramname, 0);
|
||||
if (c)
|
||||
|
@ -627,7 +632,7 @@ char *XML_GetChildBody(xmltree_t *t, char *paramname, char *def)
|
|||
return def;
|
||||
}
|
||||
|
||||
void XML_ConPrintTree(xmltree_t *t, char *subconsole, int indent)
|
||||
void XML_ConPrintTree(xmltree_t *t, const char *subconsole, int indent)
|
||||
{
|
||||
int start, c, chunk;
|
||||
struct buf_ctx buf = {NULL, 0, 0};
|
||||
|
@ -653,7 +658,7 @@ void XML_ConPrintTree(xmltree_t *t, char *subconsole, int indent)
|
|||
}
|
||||
|
||||
|
||||
static void XML_SkipWhite(char *msg, int *pos, int max)
|
||||
static void XML_SkipWhite(const char *msg, int *pos, int max)
|
||||
{
|
||||
while (*pos < max && (
|
||||
msg[*pos] == ' ' ||
|
||||
|
@ -663,7 +668,7 @@ static void XML_SkipWhite(char *msg, int *pos, int max)
|
|||
))
|
||||
*pos+=1;
|
||||
}
|
||||
static qboolean XML_ParseString(char *msg, int *pos, int max, char *out, int outlen)
|
||||
static qboolean XML_ParseString(const char *msg, int *pos, int max, char *out, int outlen)
|
||||
{
|
||||
*out = 0;
|
||||
if (*pos < max && msg[*pos] == '\"')
|
||||
|
@ -712,7 +717,7 @@ static qboolean XML_ParseString(char *msg, int *pos, int max, char *out, int out
|
|||
}
|
||||
return false;
|
||||
}
|
||||
xmltree_t *XML_FromJSON(xmltree_t *t, char *name, char *json, int *jsonpos, int jsonlen)
|
||||
xmltree_t *XML_FromJSON(xmltree_t *t, const char *name, const char *json, int *jsonpos, int jsonlen)
|
||||
{
|
||||
char child[4096];
|
||||
XML_SkipWhite(json, jsonpos, jsonlen);
|
||||
|
|
|
@ -20,18 +20,18 @@ typedef struct subtree_s
|
|||
|
||||
|
||||
|
||||
char *XML_GetParameter(xmltree_t *t, char *paramname, char *def);
|
||||
void XML_AddParameter(xmltree_t *t, char *paramname, char *value);
|
||||
void XML_AddParameteri(xmltree_t *t, char *paramname, int value);
|
||||
xmltree_t *XML_CreateNode(xmltree_t *parent, char *name, char *xmlns, char *body);
|
||||
char *XML_Markup(char *s, char *d, int dlen);
|
||||
const char *XML_GetParameter(xmltree_t *t, const char *paramname, const char *def);
|
||||
void XML_AddParameter(xmltree_t *t, const char *paramname, const char *value);
|
||||
void XML_AddParameteri(xmltree_t *t, const char *paramname, int value);
|
||||
xmltree_t *XML_CreateNode(xmltree_t *parent, const char *name, const char *xmlns, const char *body);
|
||||
char *XML_Markup(const char *s, char *d, int dlen);
|
||||
void XML_Unmark(char *s);
|
||||
char *XML_GenerateString(xmltree_t *root, qboolean readable);
|
||||
xmltree_t *XML_Parse(char *buffer, int *startpos, int maxpos, qboolean headeronly, char *defaultnamespace);
|
||||
xmltree_t *XML_Parse(const char *buffer, int *startpos, int maxpos, qboolean headeronly, const char *defaultnamespace);
|
||||
void XML_Destroy(xmltree_t *t);
|
||||
xmltree_t *XML_ChildOfTree(xmltree_t *t, char *name, int childnum);
|
||||
xmltree_t *XML_ChildOfTreeNS(xmltree_t *t, char *xmlns, char *name, int childnum);
|
||||
char *XML_GetChildBody(xmltree_t *t, char *paramname, char *def);
|
||||
void XML_ConPrintTree(xmltree_t *t, char *subconsole, int indent);
|
||||
xmltree_t *XML_ChildOfTree(xmltree_t *t, const char *name, int childnum);
|
||||
xmltree_t *XML_ChildOfTreeNS(xmltree_t *t, const char *xmlns, const char *name, int childnum);
|
||||
const char *XML_GetChildBody(xmltree_t *t, const char *paramname, const char *def);
|
||||
void XML_ConPrintTree(xmltree_t *t, const char *subconsole, int indent);
|
||||
|
||||
xmltree_t *XML_FromJSON(xmltree_t *t, char *name, char *json, int *jsonpos, int jsonlen);
|
||||
xmltree_t *XML_FromJSON(xmltree_t *t, const char *name, const char *json, int *jsonpos, int jsonlen);
|
||||
|
|
|
@ -76,12 +76,22 @@ typedef struct bresource_s
|
|||
typedef struct buddy_s
|
||||
{
|
||||
bresource_t *resources;
|
||||
bresource_t *defaultresource; //this is the one that last replied
|
||||
bresource_t *defaultresource; //this is the one that last replied (must be null for chatrooms, so we only talk to the room in general)
|
||||
bresource_t *ourselves; //this is set back to ourselves when in a chatroom
|
||||
int defaulttimestamp;
|
||||
qboolean askfriend;
|
||||
qboolean friended;
|
||||
qboolean chatroom; //chatrooms are bizzare things that need special handling.
|
||||
qboolean vcardphotochanged;
|
||||
enum {
|
||||
BT_UNKNOWN, //this buddy isn't known...
|
||||
BT_ROSTER, //this is a friend! or at least on our list of potential friends anyway.
|
||||
BT_CHATROOM //we're treating this 'guy' as a MUC, each of their resources is a different person. which is weird.
|
||||
} btype;
|
||||
|
||||
qboolean room_autojoin;
|
||||
char *room_nick;
|
||||
char *room_password;
|
||||
char *room_topic;
|
||||
|
||||
char name[256];
|
||||
char vcardphotohash[41];
|
||||
|
@ -110,6 +120,9 @@ typedef struct jclient_s
|
|||
|
||||
qhandle_t socket;
|
||||
|
||||
qhandle_t rcon_pipe; //contains console prints
|
||||
char rcon_peer[256]; //the name of the guy currently receiving console prints
|
||||
|
||||
//we buffer output for times when the outgoing socket is full.
|
||||
//mostly this only happens at the start of the connection when the socket isn't actually open yet.
|
||||
char *outbuf;
|
||||
|
@ -226,6 +239,7 @@ typedef struct jclient_s
|
|||
qboolean accepted; //connection is going
|
||||
qboolean creator; //true if we're the creator.
|
||||
unsigned int peercaps;
|
||||
qboolean displayed; //temp flag for displaying jingle sessions with people that are not on our buddy list for whatever reasons
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -313,32 +327,33 @@ extern icefuncs_t *piceapi;
|
|||
#endif
|
||||
|
||||
|
||||
qboolean NET_DNSLookup_SRV(char *host, char *out, int outlen);
|
||||
qboolean NET_DNSLookup_SRV(const char *host, char *out, int outlen);
|
||||
|
||||
//xmpp functionality
|
||||
struct iq_s *JCL_SendIQNode(jclient_t *jcl, qboolean (*callback) (jclient_t *jcl, xmltree_t *tree, struct iq_s *iq), char *iqtype, char *target, xmltree_t *node, qboolean destroynode);
|
||||
void JCL_AddClientMessagef(jclient_t *jcl, char *fmt, ...);
|
||||
void JCL_AddClientMessageString(jclient_t *jcl, char *msg);
|
||||
qboolean JCL_FindBuddy(jclient_t *jcl, char *jid, buddy_t **buddy, bresource_t **bres, qboolean create);
|
||||
struct iq_s *JCL_SendIQNode(jclient_t *jcl, qboolean (*callback) (jclient_t *jcl, xmltree_t *tree, struct iq_s *iq), const char *iqtype, const char *target, xmltree_t *node, qboolean destroynode);
|
||||
void JCL_AddClientMessagef(jclient_t *jcl, const char *fmt, ...);
|
||||
void JCL_AddClientMessageString(jclient_t *jcl, const char *msg);
|
||||
qboolean JCL_FindBuddy(jclient_t *jcl, const char *jid, buddy_t **buddy, bresource_t **bres, qboolean create);
|
||||
void JCL_ForgetBuddy(jclient_t *jcl, buddy_t *buddy, bresource_t *bres);
|
||||
|
||||
//quake functionality
|
||||
void JCL_GenLink(jclient_t *jcl, char *out, int outlen, char *action, char *context, char *contextres, char *sid, char *txtfmt, ...);
|
||||
void Con_SubPrintf(const char *subname, char *format, ...);
|
||||
void JCL_GenLink(jclient_t *jcl, char *out, int outlen, const char *action, const char *context, const char *contextres, const char *sid, const char *txtfmt, ...);
|
||||
void Con_SubPrintf(const char *subname, const char *format, ...);
|
||||
void XMPP_ConversationPrintf(const char *context, const char *title, char *format, ...);
|
||||
|
||||
//jingle functions
|
||||
void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int protocol);
|
||||
void JCL_Join(jclient_t *jcl, const char *target, const char *sid, qboolean allow, int protocol);
|
||||
void JCL_JingleTimeouts(jclient_t *jcl, qboolean killall);
|
||||
//jingle iq message handlers
|
||||
qboolean JCL_HandleGoogleSession(jclient_t *jcl, xmltree_t *tree, char *from, char *id);
|
||||
qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id);
|
||||
qboolean JCL_HandleGoogleSession(jclient_t *jcl, xmltree_t *tree, const char *from, const char *id);
|
||||
qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, const char *from, const char *id);
|
||||
|
||||
void XMPP_FT_AcceptFile(jclient_t *jcl, int fileid, qboolean accept);
|
||||
qboolean XMPP_FT_OfferAcked(jclient_t *jcl, xmltree_t *x, struct iq_s *iq);
|
||||
qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, char *iqfrom, char *iqid, xmltree_t *tree);
|
||||
void XMPP_FT_SendFile(jclient_t *jcl, char *console, char *to, char *fname);
|
||||
qboolean XMPP_FT_ParseIQSet(jclient_t *jcl, const char *iqfrom, const char *iqid, xmltree_t *tree);
|
||||
void XMPP_FT_SendFile(jclient_t *jcl, const char *console, const char *to, const char *fname);
|
||||
void XMPP_FT_Frame(jclient_t *jcl);
|
||||
|
||||
void Base64_Add(char *s, int len);
|
||||
void Base64_Add(const char *s, int len);
|
||||
char *Base64_Finish(void);
|
||||
int Base64_Decode(char *out, int outlen, char *src, int srclen);
|
||||
int Base64_Decode(char *out, int outlen, const char *src, int srclen);
|
||||
|
|
|
@ -59,6 +59,9 @@ BUILTINR(void *, Plug_GetNativePointer, (const char *funcname));
|
|||
BUILTIN(void, Con_Print, (const char *text)); //on to main console.
|
||||
#undef ARGNAMES
|
||||
|
||||
#define ARGNAMES ,conname,flags
|
||||
BUILTINR(qhandle_t, Con_POpen, (const char *conname, unsigned int flags));
|
||||
#undef ARGNAMES
|
||||
#define ARGNAMES ,conname,text
|
||||
BUILTIN(void, Con_SubPrint, (const char *conname, const char *text)); //on to named sub console (creating it too).
|
||||
#undef ARGNAMES
|
||||
|
@ -528,6 +531,7 @@ void Plug_InitStandardBuiltins(void)
|
|||
CHECKBUILTIN(Con_SetConsoleFloat);
|
||||
CHECKBUILTIN(Con_GetConsoleString);
|
||||
CHECKBUILTIN(Con_SetConsoleString);
|
||||
CHECKBUILTIN(Con_POpen);
|
||||
}
|
||||
|
||||
#ifndef Q3_VM
|
||||
|
|
|
@ -140,6 +140,7 @@ extern "C" {
|
|||
#endif
|
||||
extern qintptr_t (QDECL *plugin_syscall)( qintptr_t arg, ... );
|
||||
|
||||
void Q_strlncpy(char *d, const char *s, int sizeofd, int lenofs);
|
||||
void Q_strlcpy(char *d, const char *s, int n);
|
||||
void Q_strlcat(char *d, const char *s, int n);
|
||||
int Q_snprintf(char *buffer, size_t maxlen, const char *format, ...);
|
||||
|
@ -198,6 +199,7 @@ EBUILTIN(void *, Plug_GetNativePointer, (const char *funcname));
|
|||
#endif
|
||||
EBUILTIN(void, Con_Print, (const char *text)); //on to main console.
|
||||
|
||||
EBUILTIN(qhandle_t, Con_POpen, (const char *conname, unsigned int flags));
|
||||
EBUILTIN(void, Con_SubPrint, (const char *subname, const char *text)); //on to sub console.
|
||||
EBUILTIN(void, Con_RenameSub, (const char *oldname, const char *newname)); //rename a console.
|
||||
EBUILTIN(int, Con_IsActive, (const char *conname));
|
||||
|
|
|
@ -235,13 +235,13 @@ void QI_RefreshMapList(qboolean forcedisplay)
|
|||
|
||||
for (file = thedatabase->child; file; file = file->sibling)
|
||||
{
|
||||
char *id = XML_GetParameter(file, "id", "unnamed");
|
||||
char *rating = XML_GetParameter(file, "rating", "");
|
||||
const char *id = XML_GetParameter(file, "id", "unnamed");
|
||||
const char *rating = XML_GetParameter(file, "rating", "");
|
||||
int ratingnum = atoi(rating);
|
||||
char *author = XML_GetChildBody(file, "author", "unknown");
|
||||
char *desc = XML_GetChildBody(file, "description", "<NO DESCRIPTION>");
|
||||
char *type;
|
||||
char *date;
|
||||
const char *author = XML_GetChildBody(file, "author", "unknown");
|
||||
const char *desc = XML_GetChildBody(file, "description", "<NO DESCRIPTION>");
|
||||
const char *type;
|
||||
const char *date;
|
||||
int year, month, day;
|
||||
int startmapnum, i;
|
||||
char ratingtext[65];
|
||||
|
@ -397,7 +397,7 @@ static xmltree_t *QI_FindArchive(const char *name)
|
|||
xmltree_t *file;
|
||||
for (file = thedatabase->child; file; file = file->sibling)
|
||||
{
|
||||
char *id = XML_GetParameter(file, "id", "unnamed");
|
||||
const char *id = XML_GetParameter(file, "id", "unnamed");
|
||||
if (strcmp(file->name, "file"))
|
||||
continue; //erk?
|
||||
|
||||
|
@ -408,7 +408,7 @@ static xmltree_t *QI_FindArchive(const char *name)
|
|||
}
|
||||
static void QI_AddPackages(xmltree_t *qifile)
|
||||
{
|
||||
char *id;
|
||||
const char *id;
|
||||
char extra[1024];
|
||||
char clean[512];
|
||||
unsigned int i;
|
||||
|
|
|
@ -567,6 +567,22 @@ int rand(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
void Q_strlncpy(char *d, const char *s, int sizeofd, int lenofs)
|
||||
{
|
||||
int i;
|
||||
sizeofd--;
|
||||
if (sizeofd < 0)
|
||||
return; //this could be an error
|
||||
|
||||
for (i=0; lenofs-- > 0; i++)
|
||||
{
|
||||
if (i == sizeofd)
|
||||
break;
|
||||
*d++ = *s++;
|
||||
}
|
||||
*d='\0';
|
||||
}
|
||||
|
||||
void Q_strlcpy(char *d, const char *s, int n)
|
||||
{
|
||||
int i;
|
||||
|
|
Loading…
Reference in a new issue