misc fixes, tweaks, and hacks.

qc rt target api now uses names instead of numbers. shaders can name such rendertargets in advance.
added timing info to qc profiling, instead of just opcodes executed.
added sv_showconnectionlessmessages, to show all messages that don't relate to a client, so omc can see if he's getting DDOSed easily.
try to show proper error messages with the xmpp plugin, at least for certain things.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4714 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-08-03 14:47:47 +00:00
parent d63b8cefd6
commit 402aa52362
38 changed files with 502 additions and 269 deletions

View file

@ -3510,6 +3510,13 @@ void CL_LinkPacketEntities (void)
CL_RotateAroundTag(ent, state->number, state->tagentity, state->tagindex);
}
#ifdef RAGDOLL
if (model && model->dollinfo)
rag_updatedeltaent(ent, le);
ent->framestate.g[FS_REG].frame[0] &= ~0x8000;
ent->framestate.g[FS_REG].frame[1] &= ~0x8000;
#endif
CLQ1_AddShadow(ent);
CLQ1_AddPowerupShell(ent, false, state->effects);
@ -3527,11 +3534,6 @@ void CL_LinkPacketEntities (void)
VectorMA(dl->origin, 16, dl->axis[0], dl->origin);
}
#ifdef RAGDOLL
if (model && model->dollinfo)
rag_updatedeltaent(ent, le);
#endif
if (model2)
CL_AddVWeapModel (ent, model2);

View file

@ -1511,6 +1511,8 @@ void CL_Disconnect_f (void)
CL_Disconnect ();
connectinfo.trying = false;
CSQC_UnconnectedInit();
}
/*

View file

@ -2424,10 +2424,10 @@ void CLDP_ParseDownloadBegin(char *s)
{
qdownload_t *dl = cls.download;
char buffer[8192];
unsigned int size, pos, chunk;
qofs_t size, pos, chunk;
char *fname;
Cmd_TokenizeString(s+1, false, false);
size = (unsigned int)atoi(Cmd_Argv(1));
size = (qofs_t)strtoull(Cmd_Argv(1), NULL, 0);
fname = Cmd_Argv(2);
if (!dl || strcmp(fname, dl->remotename))

View file

@ -4226,7 +4226,7 @@ typedef struct
qbyte srcdata[1];
} mp3decoder_t;
void S_MP3_Abort(sfx_t *sfx)
static void S_MP3_Abort(sfx_t *sfx)
{
mp3decoder_t *dec = sfx->decoder.buf;

View file

@ -312,7 +312,7 @@ typedef struct rendererinfo_s {
texid_tf (*IMG_LoadCompressed) (const char *name);
texid_tf (*IMG_FindTexture) (const char *identifier, unsigned int flags);
texid_tf (*IMG_AllocNewTexture) (const char *identifier, int w, int h, unsigned int flags);
void (*IMG_Upload) (texid_t tex, char *name, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags);
void (*IMG_Upload) (texid_t tex, const char *name, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags);
void (*IMG_DestroyTexture) (texid_t tex);
void (*R_Init) (void); //FIXME - merge implementations
@ -398,7 +398,7 @@ typedef struct rendererinfo_s {
#define BE_RenderToTextureUpdate2d rf->BE_RenderToTextureUpdate2d
texid_t R2D_RT_Configure(unsigned int id, int width, int height, uploadfmt_t rtfmt);
texid_t R2D_RT_GetTexture(unsigned int id, unsigned int *width, unsigned int *height);
texid_t R2D_RT_DetachTexture(unsigned int id);
texid_t R2D_RT_Configure(const char *id, int width, int height, uploadfmt_t rtfmt);
texid_t R2D_RT_GetTexture(const char *id, unsigned int *width, unsigned int *height);

View file

@ -1557,44 +1557,47 @@ void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_
r_refdef.useperspective = *p;
break;
case VF_RT_DESTCOLOUR:
if (prinst->callargc >= 4)
case VF_RT_DESTCOLOUR0:
{
int i = parametertype - VF_RT_DESTCOLOUR0;
Q_strncpyz(r_refdef.rt_destcolour[i].texname, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(r_refdef.rt_destcolour[i].texname));
if (prinst->callargc >= 4 && *r_refdef.rt_destcolour[i].texname)
{
float fmt = G_FLOAT(OFS_PARM2);
float *size = G_VECTOR(OFS_PARM3);
R2D_RT_Configure(*p, size[0], size[1], fmt);
R2D_RT_Configure(r_refdef.rt_destcolour[i].texname, size[0], size[1], fmt);
}
r_refdef.rt_destcolour = *p;
BE_RenderToTextureUpdate2d(true);
}
break;
case VF_RT_SOURCECOLOUR:
if (prinst->callargc >= 4)
Q_strncpyz(r_refdef.rt_sourcecolour.texname, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(r_refdef.rt_sourcecolour));
if (prinst->callargc >= 4 && *r_refdef.rt_sourcecolour.texname)
{
float fmt = G_FLOAT(OFS_PARM2);
float *size = G_VECTOR(OFS_PARM3);
R2D_RT_Configure(*p, size[0], size[1], fmt);
R2D_RT_Configure(r_refdef.rt_sourcecolour.texname, size[0], size[1], fmt);
}
r_refdef.rt_sourcecolour = *p;
BE_RenderToTextureUpdate2d(false);
break;
case VF_RT_DEPTH:
if (prinst->callargc >= 4)
Q_strncpyz(r_refdef.rt_depth.texname, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(r_refdef.rt_depth.texname));
if (prinst->callargc >= 4 && *r_refdef.rt_depth.texname)
{
float fmt = G_FLOAT(OFS_PARM2);
float *size = G_VECTOR(OFS_PARM3);
R2D_RT_Configure(*p, size[0], size[1], fmt);
R2D_RT_Configure(r_refdef.rt_depth.texname, size[0], size[1], fmt);
}
r_refdef.rt_depth = *p;
BE_RenderToTextureUpdate2d(false);
break;
case VF_RT_RIPPLE:
if (prinst->callargc >= 4)
Q_strncpyz(r_refdef.rt_ripplemap.texname, PR_GetStringOfs(prinst, OFS_PARM1), sizeof(r_refdef.rt_ripplemap.texname));
if (prinst->callargc >= 4 && *r_refdef.rt_ripplemap.texname)
{
float fmt = G_FLOAT(OFS_PARM2);
float *size = G_VECTOR(OFS_PARM3);
R2D_RT_Configure(*p, size[0], size[1], fmt);
R2D_RT_Configure(r_refdef.rt_ripplemap.texname, size[0], size[1], fmt);
}
r_refdef.rt_ripplemap = *p;
BE_RenderToTextureUpdate2d(false);
break;
@ -2452,16 +2455,19 @@ static void QCBUILTIN PF_cs_getinputstate (pubprogfuncs_t *prinst, struct global
/*outgoing_sequence says how many packets have actually been sent, but there's an extra pending packet which has not been sent yet - be warned though, its data will change in the coming frames*/
if (f == cl.movesequence)
{
int i;
cmd = &independantphysics[seat];
for (f=0 ; f<3 ; f++)
cmd->angles[f] = ((int)(csqc_playerview->viewangles[f]*65536.0/360)&65535);
if (!cmd->msec)
{
tmp = *cmd;
cmd = &tmp;
CL_BaseMove (&tmp, seat, 0, 72);
for (i=0 ; i<3 ; i++)
cmd->angles[i] = ((int)(csqc_playerview->viewangles[i]*65536.0/360)&65535);
if (!cmd->msec)
{
// *cmd = cl.outframes[(f-1)&UPDATE_MASK].cmd[seat];
CL_BaseMove (cmd, seat, 0, 72);
}
cmd->msec = (realtime - cl.outframes[(f-1)&UPDATE_MASK].senttime)*1000;
}
else
{

View file

@ -34,14 +34,6 @@ static avec4_t draw_mesh_colors[4];
index_t r_quad_indexes[6] = {0, 1, 2, 2, 3, 0};
unsigned int r2d_be_flags;
static struct
{
texid_t id;
int width;
int height;
uploadfmt_t fmt;
} *rendertargets;
static unsigned int numrendertargets;
extern cvar_t scr_conalpha;
extern cvar_t gl_conback;
@ -125,10 +117,6 @@ void R2D_Shutdown(void)
cl_numstris = 0;
cl_maxstris = 0;
while (numrendertargets>0)
R_DestroyTexture(rendertargets[--numrendertargets].id);
free(rendertargets);
rendertargets = NULL;
if (font_console == font_default)
font_console = NULL;
@ -1301,30 +1289,22 @@ void R2D_DrawCrosshair(void)
R2D_ImageColours(1, 1, 1, 1);
}
static texid_t internalrt;
//resize a texture for a render target and specify the format of it.
//pass TF_INVALID and sizes=0 to get without configuring (shaders that hardcode an $rt1 etc).
texid_t R2D_RT_Configure(unsigned int id, int width, int height, uploadfmt_t rtfmt)
texid_t R2D_RT_Configure(const char *id, int width, int height, uploadfmt_t rtfmt)
{
id--; //0 is invalid.
if (id < 0 || id > 255) //sanity limit
return r_nulltex;
//extend the array if needed. these should be fairly light.
if (id >= numrendertargets)
texid_t tid;
if (!strcmp(id, "-"))
{
rendertargets = realloc(rendertargets, (id+1) * sizeof(*rendertargets));
while(numrendertargets <= id)
internalrt = tid = R_AllocNewTexture("", 0, 0, IF_NOMIPMAP);
}
else
{
rendertargets[numrendertargets].id = r_nulltex;
rendertargets[numrendertargets].width = 0;
rendertargets[numrendertargets].height = 0;
rendertargets[numrendertargets].fmt = TF_INVALID;
numrendertargets++;
tid = R_FindTexture(id, IF_NOMIPMAP);
if (!TEXVALID(tid))
tid = R_AllocNewTexture(id, 0, 0, IF_NOMIPMAP);
}
}
if (!TEXVALID(rendertargets[id].id))
rendertargets[id].id = R_AllocNewTexture(va("", id+1), 0, 0, IF_NOMIPMAP);
if (rtfmt)
{
switch(rtfmt)
@ -1337,55 +1317,31 @@ texid_t R2D_RT_Configure(unsigned int id, int width, int height, uploadfmt_t rtf
case 6: rtfmt = TF_DEPTH32; break;
default:rtfmt = TF_INVALID; break;
}
// if (rendertargets[id].fmt != rtfmt || rendertargets[id].width != width || rendertargets[id].height != height)
{
rendertargets[id].fmt = rtfmt;
rendertargets[id].width = width;
rendertargets[id].height = height;
R_Upload(rendertargets[id].id, "", rtfmt, NULL, NULL, width, height, IF_NOMIPMAP);
R_Upload(tid, id, rtfmt, NULL, NULL, width, height, IF_NOMIPMAP);
tid.ref->width = width;
tid.ref->height = height;
}
}
return rendertargets[id].id;
return tid;
}
texid_t R2D_RT_GetTexture(unsigned int id, unsigned int *width, unsigned int *height)
texid_t R2D_RT_GetTexture(const char *id, unsigned int *width, unsigned int *height)
{
if (!id)
texid_t tid;
if (!strcmp(id, "-"))
tid = internalrt;
else
tid = R_FindTexture(id, IF_NOMIPMAP);
if (tid.ref)
{
*width = tid.ref->width;
*height = tid.ref->height;
}
else
{
*width = 0;
*height = 0;
return r_nulltex;
}
id--;
if (id >= numrendertargets)
{
Con_Printf("Render target %u is not configured\n", id);
R2D_RT_Configure(id, 0, 0, TF_INVALID);
if (id >= numrendertargets)
{
*width = 0;
*height = 0;
return r_nulltex;
}
}
*width = rendertargets[id].width;
*height = rendertargets[id].height;
return rendertargets[id].id;
}
texid_t R2D_RT_DetachTexture(unsigned int id)
{
texid_t r;
id--;
if (id >= numrendertargets)
return r_nulltex;
r = rendertargets[id].id;
rendertargets[id].id = r_nulltex;
rendertargets[id].fmt = TF_INVALID;
rendertargets[id].width = 0;
rendertargets[id].height = 0;
return r;
return tid;
}
#endif

View file

@ -215,7 +215,7 @@ void Surf_AddStain(vec3_t org, float red, float green, float blue, float radius)
for (i=1 ; i< pmove.numphysent ; i++) //0 is world...
{
pe = &pmove.physents[i];
if (pe->model && pe->model->surfaces == cl.worldmodel->surfaces)
if (pe->model && pe->model->surfaces == cl.worldmodel->surfaces && !pe->model->needload)
{
parms[1] = org[0] - pe->origin[0];
parms[2] = org[1] - pe->origin[1];

View file

@ -189,6 +189,11 @@ typedef struct
void CL_BlendFog(fogstate_t *result, fogstate_t *oldf, float time, fogstate_t *newf);
void CL_ResetFog(void);
typedef struct {
char texname[MAX_QPATH];
} rtname_t;
#define R_MAX_RENDERTARGETS 8
#define R_MAX_RECURSE 6
#define R_POSTPROC_PASSES 6
#define RDFD_FOV 1
@ -230,10 +235,10 @@ typedef struct
unsigned int flipcull; /*reflected/flipped view, requires inverted culling (should be set to SHADER_CULL_FLIPPED or 0)*/
qboolean useperspective; /*not orthographic*/
int rt_destcolour; /*used for 2d. written by 3d*/
int rt_sourcecolour; /*read by 2d. not used for 3d. */
int rt_depth; /*read by 2d. used by 3d (renderbuffer used if not set)*/
int rt_ripplemap; /*read by 2d. used by 3d (internal ripplemap buffer used if not set)*/
rtname_t rt_destcolour[R_MAX_RENDERTARGETS]; /*used for 2d. written by 3d*/
rtname_t rt_sourcecolour; /*read by 2d. not used for 3d. */
rtname_t rt_depth; /*read by 2d. used by 3d (renderbuffer used if not set)*/
rtname_t rt_ripplemap; /*read by 2d. used by 3d (internal ripplemap buffer used if not set)*/
qbyte *forcedvis;
qboolean areabitsknown;
@ -357,6 +362,8 @@ enum imageflags
IF_UIPIC = 1<<10, //subject to texturemode2d
IF_LINEAR = 1<<11,
IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha
IF_RENDERTARGET = 1<<28, /*never loaded from disk, loading can't fail*/
IF_EXACTEXTENSION = 1<<29,
IF_REPLACE = 1<<30,
IF_SUBDIRONLY = 1<<31

View file

@ -149,7 +149,17 @@ static int OSS_InitCard(soundcardinfo_t *sc, int cardnum)
Con_Printf("Initing OSS sound device %s\n", snddev);
#ifdef __linux__
//linux is a pile of shit.
//nonblock is needed to get around issues with the old/buggy linux oss3 clone implementation, as well as because this code is too lame to thread audio.
sc->audio_fd = open(snddev, O_RDWR | O_NONBLOCK); //try the primary device
//fixme: the following is desired once threading is supported.
//int flags = fcntl(fd, F_GETFL, 0);
//fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
#else
//FIXME: remove non-block if we're using threads.
sc->audio_fd = open(snddev, O_WRONLY | O_NONBLOCK); //try the primary device
#endif
if (sc->audio_fd < 0)
{
perror(snddev);

View file

@ -1536,7 +1536,7 @@ void Sys_Quit (void)
}
#if 1
#if 0
/*
================
Sys_DoubleTime

View file

@ -49,7 +49,7 @@ static texid_tf Headless_IMG_AllocNewTexture (const char *identifier, int w, int
{
return dummytex;
}
static void Headless_IMG_Upload (texid_t tex, char *name, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags)
static void Headless_IMG_Upload (texid_t tex, const char *name, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags)
{
}
static void Headless_IMG_DestroyTexture (texid_t tex)

View file

@ -235,7 +235,7 @@ qboolean NET_CompareAdr (netadr_t *a, netadr_t *b)
if (b->address.ip6[i] != 0)
return false; //only matches if they're 0s, otherwise its not an ipv4 address there
for (; i < 12; i++)
if (b->address.ip6[i] != 0xff && b->address.ip6[i] != 0x00) //0x00 is depricated
if (b->address.ip6[i] != 0xff)// && b->address.ip6[i] != 0x00) //0x00 is depricated
return false; //only matches if they're 0s or ffs, otherwise its not an ipv4 address there
for (i = 0; i < 4; i++)
{
@ -251,7 +251,7 @@ qboolean NET_CompareAdr (netadr_t *a, netadr_t *b)
return false; //only matches if they're 0s, otherwise its not an ipv4 address there
for (; i < 12; i++)
if (a->address.ip6[i] != 0xff && a->address.ip6[i] != 0x00) //0x00 is depricated
if (a->address.ip6[i] != 0xff)// && a->address.ip6[i] != 0x00) //0x00 is depricated
return false; //only matches if they're 0s or ffs, otherwise its not an ipv4 address there
for (i = 0; i < 4; i++)
@ -1297,6 +1297,8 @@ qboolean NET_StringToAdrMasked (const char *s, netadr_t *a, netadr_t *amask)
// NET_CompareAdrMasked: given 3 addresses, 2 to compare with a complimentary mask,
// returns true or false if they match
//WARNING: a is typically an ipv6 address, even if its an ipv4-mapped address.
//so ipv4ify first.
qboolean NET_CompareAdrMasked(netadr_t *a, netadr_t *b, netadr_t *mask)
{
int i;
@ -1318,7 +1320,7 @@ qboolean NET_CompareAdrMasked(netadr_t *a, netadr_t *b, netadr_t *mask)
if (b->address.ip6[i] != 0)
return false; //only matches if they're 0s, otherwise its not an ipv4 address there
for (; i < 12; i++)
if (b->address.ip6[i] != 0xff && b->address.ip6[i] != 0x00) //0x00 is depricated
if (b->address.ip6[i] != 0xff)// && b->address.ip6[i] != 0x00) //0x00 is depricated
return false; //only matches if they're 0s or ffs, otherwise its not an ipv4 address there
for (i = 0; i < 4; i++)
{
@ -1334,7 +1336,7 @@ qboolean NET_CompareAdrMasked(netadr_t *a, netadr_t *b, netadr_t *mask)
return false; //only matches if they're 0s, otherwise its not an ipv4 address there
for (; i < 12; i++)
if (a->address.ip6[i] != 0xff && a->address.ip6[i] != 0x00) //0x00 is depricated
if (a->address.ip6[i] != 0xff)// && a->address.ip6[i] != 0x00) //0x00 is depricated
return false; //only matches if they're 0s or ffs, otherwise its not an ipv4 address there
for (i = 0; i < 4; i++)

View file

@ -1324,6 +1324,8 @@ void Plug_Initialise(qboolean fromgamedir)
Plug_Client_Init();
}
if (plug_loaddefault.value)
{
if (!fromgamedir)
{
FS_NativePath("", FS_BINARYPATH, nat, sizeof(nat));
@ -1331,8 +1333,6 @@ void Plug_Initialise(qboolean fromgamedir)
Sys_EnumerateFiles(nat, "fteplug_*" ARCH_CPU_POSTFIX ARCH_DL_POSTFIX, Plug_EnumeratedRoot, NULL, NULL);
}
if (fromgamedir)
{
if (plug_loaddefault.value)
{
COM_EnumerateFiles("plugins/*.qvm", Plug_Emumerated, ".qvm");
}

View file

@ -1218,8 +1218,8 @@ were contacted during the move.
*/
void PM_PlayerMove (float gamespeed)
{
int i;
int tmp; //for rounding
// int i;
// int tmp; //for rounding
frametime = pmove.cmd.msec * 0.001*gamespeed;
pmove.numtouch = 0;

View file

@ -577,10 +577,17 @@ typedef enum
VF_STATSENTITIY = 207, //the player number for the stats.
VF_SCREENVOFFSET = 208,
VF_RT_DESTCOLOUR = 209,
VF_RT_SOURCECOLOUR = 210,
VF_RT_DEPTH = 211,
VF_RT_RIPPLE = 212, /**/
VF_RT_SOURCECOLOUR = 209,
VF_RT_DEPTH = 210,
VF_RT_RIPPLE = 211, /**/
VF_RT_DESTCOLOUR0 = 212,
VF_RT_DESTCOLOUR1 = 213,
VF_RT_DESTCOLOUR2 = 214,
VF_RT_DESTCOLOUR3 = 215,
VF_RT_DESTCOLOUR4 = 216,
VF_RT_DESTCOLOUR5 = 217,
VF_RT_DESTCOLOUR6 = 218,
VF_RT_DESTCOLOUR7 = 219,
} viewflags;
/*FIXME: this should be changed*/

View file

@ -125,6 +125,10 @@ void TL_InitLanguages(void)
*lang = 0;
//we don't understand codesets sadly.
lang = strrchr(sys_language, '.');
if (lang)
*lang = 0;
//we also only support the single primary locale (no fallbacks, we're just using the language[+territory])
lang = strrchr(sys_language, ':');
if (lang)
*lang = 0;
//but we do support territories.

View file

@ -8853,6 +8853,14 @@
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\in_win.c"
@ -11207,6 +11215,14 @@
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\pr_csqc.c"
@ -16872,6 +16888,7 @@
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
@ -21383,7 +21400,6 @@
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"

View file

@ -63,6 +63,12 @@ static hashtable_t skincolourmapped;
//q3 .skin support
static skinfile_t **registeredskins;
static skinid_t numregisteredskins;
struct cctx_s
{
texid_t diffuse;
int width;
int height;
};
void Mod_WipeSkin(skinid_t id)
{
skinfile_t *sk;
@ -99,7 +105,7 @@ skinfile_t *Mod_LookupSkin(skinid_t id)
return registeredskins[id];
return NULL;
}
static void Mod_ComposeSkin(char *texture)
static void Mod_ComposeSkin(char *texture, struct cctx_s *cctx)
{
float x=0, y=0;
float w, h;
@ -121,19 +127,13 @@ static void Mod_ComposeSkin(char *texture)
//load the image and set some default sizes, etc.
sourceimg = R2D_SafeCachePic(tname);
if (!sourceimg) //no shader? no point in doing anything.
return;
if (sourceimg) //no shader? no point in doing anything.
{
w = sourceimg->width;
h = sourceimg->height;
//create a render target if one is not already selected
if (!r_refdef.rt_destcolour)
{
r_refdef.rt_destcolour = 1; //fixme: this 1 here is a technicality. it will destroy this render target slot. we should find/make a free one instead.
R2D_RT_Configure(r_refdef.rt_destcolour, x+w, y+h, TF_RGBA32);
BE_RenderToTextureUpdate2d(true);
}
else
w = h = 0;
while(*s)
{
@ -171,6 +171,21 @@ static void Mod_ComposeSkin(char *texture)
}
}
if (!w || !h)
return;
//create a render target if one is not already selected
if (!TEXVALID(cctx->diffuse))
{
strcpy(r_refdef.rt_destcolour[0].texname, "-");
cctx->width = x+w;
cctx->height = y+h;
cctx->diffuse = R2D_RT_Configure(r_refdef.rt_destcolour[0].texname, cctx->width, cctx->height, TF_RGBA32);
BE_RenderToTextureUpdate2d(true);
}
if (!sourceimg)
return;
R2D_ImageColours(r,g,b,a);
R2D_Image(x, 512-(y+h), w, h, 0, 1, 1, 0, sourceimg);
@ -233,6 +248,9 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
//body
if (com_tokentype != TTP_LINEENDING)
{
struct cctx_s cctx;
memset(&cctx, 0, sizeof(cctx));
Q_strncpyz(skin->mappings[skin->nummappings].surface, com_token, sizeof(skin->mappings[skin->nummappings].surface));
skintext = COM_ParseToken(skintext, NULL);
Q_strncpyz(shadername, com_token, sizeof(shadername));
@ -249,14 +267,14 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
else
break;
skintext = COM_Parse(skintext);
Mod_ComposeSkin(com_token);
Mod_ComposeSkin(com_token, &cctx);
}
skin->mappings[skin->nummappings].needsfree = 1;
skin->mappings[skin->nummappings].texnums.base = R2D_RT_DetachTexture(r_refdef.rt_destcolour);
skin->mappings[skin->nummappings].texnums.base = cctx.diffuse;
skin->nummappings++;
r_refdef.rt_destcolour = 0;
*r_refdef.rt_destcolour[0].texname = 0;
BE_RenderToTextureUpdate2d(true);
}
}

View file

@ -4523,9 +4523,9 @@ void GLBE_RenderToTextureUpdate2d(qboolean destchanged)
unsigned int width = 0, height = 0;
if (destchanged)
{
if (r_refdef.rt_destcolour)
if (*r_refdef.rt_destcolour[0].texname)
{
texid_t tex = R2D_RT_GetTexture(r_refdef.rt_destcolour, &width, &height);
texid_t tex = R2D_RT_GetTexture(r_refdef.rt_destcolour[0].texname, &width, &height);
GLBE_FBO_Update(&shaderstate.fbo_2dfbo, true, FBO_TEX_COLOUR, tex, r_nulltex, width, height);
}
else
@ -4535,8 +4535,8 @@ void GLBE_RenderToTextureUpdate2d(qboolean destchanged)
}
else
{
shaderstate.tex_sourcecol = R2D_RT_GetTexture(r_refdef.rt_sourcecolour, &width, &height);
shaderstate.tex_sourcedepth = R2D_RT_GetTexture(r_refdef.rt_depth, &width, &height);
shaderstate.tex_sourcecol = R2D_RT_GetTexture(r_refdef.rt_sourcecolour.texname, &width, &height);
shaderstate.tex_sourcedepth = R2D_RT_GetTexture(r_refdef.rt_depth.texname, &width, &height);
}
}
void GLBE_FBO_Sources(texid_t sourcecolour, texid_t sourcedepth)

View file

@ -93,10 +93,10 @@ void GL_UploadFmt(texid_t tex, const char *name, enum uploadfmt fmt, void *data,
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP, GL_DEPTH_COMPONENT32_ARB);
break;
case TF_RGBA16F:
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP, GL_RGBA16F_ARB);
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP|IF_CLAMP, GL_RGBA16F_ARB);
break;
case TF_RGBA32F:
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP, GL_RGBA32F_ARB);
GL_Upload32_Int(name, NULL, width, height, flags|IF_NOMIPMAP|IF_CLAMP, GL_RGBA32F_ARB);
break;
default:
@ -590,11 +590,11 @@ void GL_Set2D (qboolean flipped)
float rad, ang;
float tmp[16], tmp2[16];
float w = vid.width, h = vid.height;
qboolean fbo = !!r_refdef.rt_destcolour;
qboolean fbo = !!*r_refdef.rt_destcolour[0].texname;
if (fbo)
{
R2D_RT_GetTexture(r_refdef.rt_destcolour, &vid.fbpwidth, &vid.fbpheight);
R2D_RT_GetTexture(r_refdef.rt_destcolour[0].texname, &vid.fbpwidth, &vid.fbpheight);
vid.fbvwidth = vid.fbpwidth;
vid.fbvheight = vid.fbpheight;
}
@ -1241,6 +1241,12 @@ static void GL_Upload32_Int (const char *name, unsigned *data, int width, int he
glcolormode = GL_DEPTH_COMPONENT;
type = GL_UNSIGNED_BYTE;
}
else if (glcolormode == GL_RGBA16F_ARB || glcolormode == GL_RGBA32F_ARB)
{
samples = glcolormode;
glcolormode = GL_RGBA;
type = GL_FLOAT;
}
else if (gl_config.gles)
{
glcolormode = GL_RGBA; /*our input is RGBA or RGBX, with the internal format restriction, we must therefore always have an alpha value*/
@ -1319,7 +1325,8 @@ static void GL_Upload32_Int (const char *name, unsigned *data, int width, int he
GL_Texturemode_Apply(targ, flags);
if (!data)
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data);
scaled = NULL;
// qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data);
else if (scaled_width == width && scaled_height == height)
{
if (((flags&IF_NOMIPMAP)||gl_config.sgis_generate_mipmap) && !(flags & IF_PREMULTIPLYALPHA)) //gotta love this with NPOT textures... :)
@ -1330,7 +1337,7 @@ static void GL_Upload32_Int (const char *name, unsigned *data, int width, int he
else if (type == GL_UNSIGNED_SHORT_4_4_4_4)
GL_8888to4444(targface, (unsigned char *)data, (unsigned short*)scaled, 0, scaled_width, scaled_height);
else
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, data);
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, type, data);
goto done;
}
memcpy (scaled, data, width*height*4);
@ -1367,7 +1374,7 @@ static void GL_Upload32_Int (const char *name, unsigned *data, int width, int he
else if (type == GL_UNSIGNED_SHORT_4_4_4_4)
GL_8888to4444(targface, (unsigned char *)scaled, (unsigned short*)uploadmemorybufferintermediate, 0, scaled_width, scaled_height);
else
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, GL_UNSIGNED_BYTE, scaled);
qglTexImage2D (targface, 0, samples, scaled_width, scaled_height, 0, glcolormode, type, scaled);
if (!(flags&IF_NOMIPMAP) && !gl_config.sgis_generate_mipmap)
{
miplevel = 0;

View file

@ -1499,7 +1499,7 @@ r_refdef must be set before the first call
*/
void GLR_RenderView (void)
{
int dofbo = r_refdef.rt_destcolour || r_refdef.rt_depth;
int dofbo = *r_refdef.rt_destcolour[0].texname || *r_refdef.rt_depth.texname;
double time1 = 0, time2;
checkglerror();
@ -1525,18 +1525,27 @@ void GLR_RenderView (void)
if (dofbo)
{
unsigned int flags = 0;
texid_t col = r_nulltex, depth = r_nulltex;
texid_t col[R_MAX_RENDERTARGETS], depth = r_nulltex;
unsigned int cw=0, ch=0, dw=0, dh=0;
int mrt;
//3d views generally ignore source colour+depth.
//FIXME: support depth with no colour
if (r_refdef.rt_destcolour)
col = R2D_RT_GetTexture(r_refdef.rt_destcolour, &cw, &ch);
if (r_refdef.rt_depth)
depth = R2D_RT_GetTexture(r_refdef.rt_depth, &dw, &dh);
for (mrt = 0; mrt < R_MAX_RENDERTARGETS; mrt++)
{
if (*r_refdef.rt_destcolour[mrt].texname)
col[mrt] = R2D_RT_GetTexture(r_refdef.rt_destcolour[mrt].texname, &cw, &ch);
else
{
col[mrt] = r_nulltex;
break;
}
}
if (*r_refdef.rt_depth.texname)
depth = R2D_RT_GetTexture(r_refdef.rt_depth.texname, &dw, &dh);
if (r_refdef.rt_destcolour)
if (mrt)
{ //colour (with or without depth)
if (r_refdef.rt_depth && (dw != cw || dh != dh))
if (*r_refdef.rt_depth.texname && (dw != cw || dh != dh))
{
Con_Printf("RT: destcolour and depth render targets are of different sizes\n"); //should check rgb/depth modes too I guess.
depth = r_nulltex;
@ -1549,13 +1558,13 @@ void GLR_RenderView (void)
vid.fbvwidth = vid.fbpwidth = dw;
vid.fbvheight = vid.fbpheight = dh;
}
if (TEXVALID(col))
if (TEXVALID(col[0]))
flags |= FBO_TEX_COLOUR;
if (TEXVALID(depth))
flags |= FBO_TEX_DEPTH;
else
flags |= FBO_RB_DEPTH;
GLBE_FBO_Update(&fbo_gameview, true, flags, col, depth, vid.fbpwidth, vid.fbpheight);
GLBE_FBO_Update(&fbo_gameview, true, flags, col[0], depth, vid.fbpwidth, vid.fbpheight);
}
else
{

View file

@ -594,7 +594,17 @@ static int Shader_SetImageFlags(shader_t *shader, shaderpass_t *pass, char **nam
while (name)
{
if (!Q_strnicmp(*name, "$3d:", 4))
if (!Q_strnicmp(*name, "$rt:", 4))
{
*name += 4;
flags |= IF_RENDERTARGET;
}
else if (!Q_strnicmp(*name, "$clamp:", 7))
{
*name += 7;
flags |= IF_CLAMP;
}
else if (!Q_strnicmp(*name, "$3d:", 4))
{
*name+=4;
flags = (flags&~IF_TEXTYPE) | IF_3DMAP;
@ -643,6 +653,13 @@ static texid_t Shader_FindImage ( char *name, int flags )
if (!Q_stricmp (name, "$whiteimage"))
return r_whiteimage;
}
if (flags & IF_RENDERTARGET)
{
texid_t tid = R_FindTexture(name, (flags&~IF_RENDERTARGET)|IF_NOMIPMAP);
if (!TEXVALID(tid))
tid = R_AllocNewTexture(name, 0, 0, (flags&~IF_RENDERTARGET)|IF_NOMIPMAP);
return tid;
}
return R_LoadHiResTexture(name, NULL, flags);
}

View file

@ -697,7 +697,7 @@ reeval:
#endif
}
newf = &pr_functions[fnum & ~0xff000000];
newf = &pr_cp_functions[fnum & ~0xff000000];
if (newf->first_statement < 0)
{ // negative statements are built in functions
@ -968,11 +968,11 @@ reeval:
break;
case OP_CSTATE:
externs->cstateop(&progfuncs->funcs, OPA->_float, OPB->_float, pr_xfunction - pr_functions);
externs->cstateop(&progfuncs->funcs, OPA->_float, OPB->_float, pr_xfunction - pr_cp_functions);
break;
case OP_CWSTATE:
externs->cwstateop(&progfuncs->funcs, OPA->_float, OPB->_float, pr_xfunction - pr_functions);
externs->cwstateop(&progfuncs->funcs, OPA->_float, OPB->_float, pr_xfunction - pr_cp_functions);
break;
case OP_THINKTIME:

View file

@ -547,7 +547,7 @@ int PDECL PR_GetFuncArgCount(pubprogfuncs_t *ppf, func_t func)
unsigned int pnum;
unsigned int fnum;
dfunction_t *f;
mfunction_t *f;
pnum = (func & 0xff000000)>>24;
fnum = (func & 0x00ffffff);
@ -566,7 +566,7 @@ int PDECL PR_GetFuncArgCount(pubprogfuncs_t *ppf, func_t func)
func_t PDECL PR_FindFunc(pubprogfuncs_t *ppf, const char *funcname, progsnum_t pnum)
{
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
dfunction_t *f=NULL;
mfunction_t *f=NULL;
if (pnum == PR_ANY)
{
for (pnum = 0; (unsigned)pnum < maxprogs; pnum++)
@ -1041,10 +1041,12 @@ pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf)
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
struct progstate_s *ps;
unsigned int i, f, j, s;
unsigned long long cpufrequency;
struct
{
char *fname;
int profile;
unsigned long long profiletime;
} *sorted, t;
if (!prinst.profiling)
{
@ -1053,6 +1055,8 @@ pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf)
return true;
}
cpufrequency = Sys_GetClockRate();
for (i = 0; i < maxprogs; i++)
{
ps = &pr_progstate[i];
@ -1068,14 +1072,16 @@ pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf)
continue;
sorted[s].fname = ps->functions[f].s_name+progfuncs->funcs.stringtable;
sorted[s].profile = ps->functions[f].profile;
sorted[s].profiletime = ps->functions[f].profiletime - ps->functions[f].profilechildtime;
ps->functions[f].profile = 0;
ps->functions[f].profiletime = 0;
s++;
}
// good 'ol bubble sort
for (f = 0; f < s; f++)
for (j = f; j < s; j++)
if (sorted[f].profile > sorted[j].profile)
if (sorted[f].profiletime > sorted[j].profiletime)
{
t = sorted[f];
sorted[f] = sorted[j];
@ -1084,7 +1090,7 @@ pbool PDECL PR_DumpProfiles (pubprogfuncs_t *ppf)
//print it out
for (f = 0; f < s; f++)
printf("%s: %u\n", sorted[f].fname, sorted[f].profile);
printf("%s: %u %g\n", sorted[f].fname, sorted[f].profile, (float)(((double)sorted[f].profiletime) / cpufrequency));
free(sorted);
}
return true;

View file

@ -512,6 +512,23 @@ typedef struct
qbyte parm_size[MAX_PARMS];
} QCC_dfunction_t;
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.
unsigned long long profiletime; //total time inside (cpu cycles)
unsigned long long 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;
#define PROG_QTESTVERSION 3
#define PROG_VERSION 6
#define PROG_KKQWSVVERSION 7

View file

@ -436,9 +436,9 @@ unsigned int *ED_FindGlobalOfsFromProgs (progfuncs_t *progfuncs, char *name, pro
ED_FindFunction
============
*/
dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, const char *name, progsnum_t *prnum, progsnum_t fromprogs)
mfunction_t *ED_FindFunction (progfuncs_t *progfuncs, const char *name, progsnum_t *prnum, progsnum_t fromprogs)
{
dfunction_t *func;
mfunction_t *func;
unsigned int i;
char *sep;
@ -507,7 +507,7 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val, pbool v
{
static char line[4096];
fdef_t *fielddef;
dfunction_t *f;
mfunction_t *f;
#ifdef DEF_SAVEGLOBAL
type &= ~DEF_SAVEGLOBAL;
@ -620,7 +620,7 @@ char *PDECL PR_UglyValueString (pubprogfuncs_t *ppf, etype_t type, eval_t *val)
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
static char line[4096];
fdef_t *fielddef;
dfunction_t *f;
mfunction_t *f;
int i, j;
#ifdef DEF_SAVEGLOBAL
@ -732,7 +732,7 @@ char *PR_UglyOldValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val)
{
static char line[4096];
fdef_t *fielddef;
dfunction_t *f;
mfunction_t *f;
#ifdef DEF_SAVEGLOBAL
type &= ~DEF_SAVEGLOBAL;
@ -1107,7 +1107,7 @@ pbool PDECL ED_ParseEval (pubprogfuncs_t *ppf, eval_t *eval, int type, const cha
fdef_t *def;
char *v, *w;
string_t st;
dfunction_t *func;
mfunction_t *func;
switch (type & ~DEF_SAVEGLOBAL)
{
@ -1189,7 +1189,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, int qcptr, unsigned int fldofs, int
fdef_t *def;
char *v, *w;
string_t st;
dfunction_t *func;
mfunction_t *func;
int type = fldtype & ~DEF_SAVEGLOBAL;
qcptr += fldofs*sizeof(int);
@ -1596,7 +1596,7 @@ char *SaveCallStack (progfuncs_t *progfuncs, char *buf, int *bufofs, int bufmax)
{
#define AddS(str) PR_Cat(buf, str, bufofs, bufmax)
char buffer[8192];
const dfunction_t *f;
const mfunction_t *f;
int i;
int progs;
@ -1915,7 +1915,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, float killonspawnfl
if (!resethunk)
{
dfunction_t *f;
mfunction_t *f;
if ((var = QC_GetEdictFieldValue (&progfuncs->funcs, (struct edict_s *)ed, "classname", NULL)))
{
f = ED_FindFunction(progfuncs, var->string + progfuncs->funcs.stringtable, NULL, -1);
@ -1923,7 +1923,7 @@ int PDECL PR_LoadEnts(pubprogfuncs_t *ppf, const char *file, float killonspawnfl
{
var = (eval_t *)((int *)pr_globals + ED_FindGlobalOfs(progfuncs, "self"));
var->edict = EDICT_TO_PROG(progfuncs, ed);
PR_ExecuteProgram(&progfuncs->funcs, f-pr_functions);
PR_ExecuteProgram(&progfuncs->funcs, f-pr_cp_functions);
}
}
}
@ -2502,7 +2502,7 @@ PR_LoadProgs
*/
int PR_ReallyLoadProgs (progfuncs_t *progfuncs, const char *filename, int headercrc, progstate_t *progstate, pbool complain)
{
unsigned int i, type;
unsigned int i, j, type;
// extensionbuiltin_t *eb;
// float fl;
int len;
@ -2521,6 +2521,7 @@ int PR_ReallyLoadProgs (progfuncs_t *progfuncs, const char *filename, int header
ddef16_t *gd16, *fld16;
float *glob;
dfunction_t *fnc;
mfunction_t *fnc2;
dstatement16_t *st16;
int hmark=0xffffffff;
@ -2676,7 +2677,7 @@ retry:
return false;
}
fnc = pr_functions = (dfunction_t *)((qbyte *)pr_progs + pr_progs->ofs_functions);
fnc = (dfunction_t *)((qbyte *)pr_progs + pr_progs->ofs_functions);
pr_strings = ((char *)pr_progs + pr_progs->ofs_strings);
current_progstate->globaldefs = *(void**)&gd16 = (void *)((qbyte *)pr_progs + pr_progs->ofs_globaldefs);
current_progstate->fielddefs = *(void**)&fld16 = (void *)((qbyte *)pr_progs + pr_progs->ofs_fielddefs);
@ -2753,9 +2754,9 @@ retry:
{
len=sizeof(dfunction_t)*pr_progs->numfunctions;
s = PRHunkAlloc(progfuncs, len, "dfunctiontable");
QC_decode(progfuncs, PRLittleLong(*(int *)pr_functions), len, 2, (char *)(((int *)pr_functions)+1), s);
QC_decode(progfuncs, PRLittleLong(*(int *)fnc), len, 2, (char *)(((int *)fnc)+1), s);
fnc = pr_functions = (dfunction_t *)s;
fnc = (dfunction_t *)s;
}
if (pr_progs->blockscompressed & 16) //string table
{
@ -2839,7 +2840,7 @@ retry:
}
}
pr_functions = fnc;
pr_cp_functions = NULL;
// pr_strings = ((char *)pr_progs + pr_progs->ofs_strings);
gd16 = *(ddef16_t**)&current_progstate->globaldefs = (ddef16_t *)((qbyte *)pr_progs + pr_progs->ofs_globaldefs);
fld16 = (ddef16_t *)((qbyte *)pr_progs + pr_progs->ofs_fielddefs);
@ -2855,45 +2856,50 @@ retry:
current_progstate->edict_size = pr_progs->entityfields * 4 + externs->edictsize;
if (sizeof(mfunction_t) > sizeof(qtest_function_t))
Sys_Error("assumption no longer works");
// byte swap the lumps
switch(current_progstate->structtype)
{
case PST_QTEST:
// qtest needs a struct remap
pr_cp_functions = (mfunction_t*)fnc;
fnc2 = pr_cp_functions;
for (i=0 ; i<pr_progs->numfunctions; i++)
{
int j;
//qtest functions are bigger, so we can just do this in-place
qtest_function_t qtfunc = ((qtest_function_t*)fnc)[i];
fnc[i].first_statement = PRLittleLong (qtfunc.first_statement);
fnc[i].parm_start = PRLittleLong (qtfunc.parm_start);
fnc[i].s_name = (string_t)PRLittleLong (qtfunc.s_name);
fnc[i].s_file = (string_t)PRLittleLong (qtfunc.s_file);
fnc[i].numparms = PRLittleLong (qtfunc.numparms);
fnc[i].locals = PRLittleLong (qtfunc.locals);
fnc2[i].first_statement = PRLittleLong (qtfunc.first_statement);
fnc2[i].parm_start = PRLittleLong (qtfunc.parm_start);
fnc2[i].s_name = (string_t)PRLittleLong (qtfunc.s_name);
fnc2[i].s_file = (string_t)PRLittleLong (qtfunc.s_file);
fnc2[i].numparms = PRLittleLong (qtfunc.numparms);
fnc2[i].locals = PRLittleLong (qtfunc.locals);
for (j=0; j<MAX_PARMS;j++)
fnc[i].parm_size[j] = PRLittleLong (qtfunc.parm_size[j]);
fnc2[i].parm_size[j] = PRLittleLong (qtfunc.parm_size[j]);
fnc[i].s_name += stringadjust;
fnc[i].s_file += stringadjust;
fnc2[i].s_name += stringadjust;
fnc2[i].s_file += stringadjust;
}
break;
case PST_KKQWSV:
case PST_DEFAULT:
case PST_FTE32:
for (i=0 ; i<pr_progs->numfunctions; i++)
pr_cp_functions = PRHunkAlloc(progfuncs, sizeof(*pr_cp_functions)*pr_progs->numfunctions, "mfunctions");
for (i=0,fnc2=pr_cp_functions; i<pr_progs->numfunctions; i++, fnc2++)
{
#ifndef NOENDIAN
fnc[i].first_statement = PRLittleLong (fnc[i].first_statement);
fnc[i].parm_start = PRLittleLong (fnc[i].parm_start);
fnc[i].s_name = (string_t)PRLittleLong ((long)fnc[i].s_name);
fnc[i].s_file = (string_t)PRLittleLong ((long)fnc[i].s_file);
fnc[i].numparms = PRLittleLong (fnc[i].numparms);
fnc[i].locals = PRLittleLong (fnc[i].locals);
#endif
fnc[i].s_name += stringadjust;
fnc[i].s_file += stringadjust;
fnc2->first_statement = PRLittleLong (fnc[i].first_statement);
fnc2->parm_start = PRLittleLong (fnc[i].parm_start);
fnc2->s_name = (string_t)PRLittleLong ((long)fnc[i].s_name) + stringadjust;
fnc2->s_file = (string_t)PRLittleLong ((long)fnc[i].s_file) + stringadjust;
fnc2->numparms = PRLittleLong (fnc[i].numparms);
fnc2->locals = PRLittleLong (fnc[i].locals);
for (j=0; j<MAX_PARMS;j++)
fnc2->parm_size[j] = fnc[i].parm_size[j];
}
break;
default:

View file

@ -31,7 +31,6 @@
#endif
#endif
//=============================================================================
/*
@ -307,7 +306,7 @@ static void PDECL PR_PrintRelevantLocals(progfuncs_t *progfuncs)
void PDECL PR_StackTrace (pubprogfuncs_t *ppf, int showlocals)
{
progfuncs_t *progfuncs = (progfuncs_t *)ppf;
const dfunction_t *f;
const mfunction_t *f;
int i;
int progs;
int arg;
@ -488,7 +487,7 @@ PR_EnterFunction
Returns the new program statement counter
====================
*/
int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum)
int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, mfunction_t *f, int progsnum)
{
int i, j, c, o;
@ -496,6 +495,10 @@ int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsn
pr_stack[pr_depth].f = pr_xfunction;
pr_stack[pr_depth].progsnum = progsnum;
pr_stack[pr_depth].pushed = pr_spushed;
if (prinst.profiling)
{
pr_stack[pr_depth].timestamp = Sys_GetClock();
}
pr_depth++;
if (pr_depth == MAX_STACK_DEPTH)
{
@ -563,10 +566,22 @@ int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs)
// up stack
pr_depth--;
PR_SwitchProgsParms(progfuncs, pr_stack[pr_depth].progsnum);
pr_xfunction = pr_stack[pr_depth].f;
pr_spushed = pr_stack[pr_depth].pushed;
if (prinst.profiling)
{
unsigned long long cycles;
cycles = Sys_GetClock() - pr_stack[pr_depth].timestamp;
pr_xfunction->profiletime += cycles;
pr_xfunction = pr_stack[pr_depth].f;
if (pr_depth)
pr_xfunction->profilechildtime += cycles;
}
else
pr_xfunction = pr_stack[pr_depth].f;
localstack_used -= pr_spushed;
return pr_stack[pr_depth].s;
}
@ -911,7 +926,7 @@ char *PDECL PR_EvaluateDebugString(pubprogfuncs_t *ppf, char *key)
case ev_function:
{
dfunction_t *func;
mfunction_t *func;
int i;
int progsnum = -1;
char *s = assignment;
@ -962,7 +977,7 @@ void SetExecutionToLine(progfuncs_t *progfuncs, int linenum)
{
int pn = pr_typecurrent;
int snum;
const dfunction_t *f = pr_xfunction;
const mfunction_t *f = pr_xfunction;
switch(current_progstate->structtype)
{
@ -998,7 +1013,7 @@ int PDECL PR_ToggleBreakpoint(pubprogfuncs_t *ppf, char *filename, int linenum,
unsigned int fl;
unsigned int i;
int pn = pr_typecurrent;
dfunction_t *f;
mfunction_t *f;
int op = 0; //warning about not being initialized before use
for (pn = 0; (unsigned)pn < maxprogs; pn++)
@ -1170,7 +1185,7 @@ static char *lastfile = 0;
int pn = pr_typecurrent;
int i;
const dfunction_t *f = pr_xfunction;
const mfunction_t *f = pr_xfunction;
pr_xstatement = statement;
if (!externs->useeditor)
@ -1244,7 +1259,7 @@ static int PR_ExecuteCode16 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
int swtchtype = 0; //warning about not being initialized before use
const dstatement16_t *fte_restrict st;
dfunction_t *fte_restrict newf;
mfunction_t *fte_restrict newf;
int i;
edictrun_t *ed;
eval_t *ptr;
@ -1291,7 +1306,7 @@ static int PR_ExecuteCode32 (progfuncs_t *fte_restrict progfuncs, int s, int *ft
int swtchtype = 0; //warning about not being initialized before use
const dstatement32_t *fte_restrict st;
dfunction_t *fte_restrict newf;
mfunction_t *fte_restrict newf;
int i;
edictrun_t *ed;
eval_t *ptr;
@ -1406,7 +1421,7 @@ static void PR_ExecuteCode (progfuncs_t *progfuncs, int s)
void PDECL PR_ExecuteProgram (pubprogfuncs_t *ppf, func_t fnum)
{
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
dfunction_t *f;
mfunction_t *f;
int i;
unsigned int initial_progs;
int oldexitdepth;
@ -1446,7 +1461,7 @@ void PDECL PR_ExecuteProgram (pubprogfuncs_t *ppf, func_t fnum)
oldexitdepth = prinst.exitdepth;
f = &pr_functions[fnum & ~0xff000000];
f = &pr_cp_functions[fnum & ~0xff000000];
if (f->first_statement < 0)
{ // negative statements are built in functions
@ -1519,7 +1534,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf)
int ed = prinst.exitdepth;
int localsoffset, baselocalsoffset;
qcthread_t *thread = externs->memalloc(sizeof(qcthread_t));
const dfunction_t *f;
const mfunction_t *f;
//copy out the functions stack.
for (i = 0,localsoffset=0; i < ed; i++)
@ -1584,7 +1599,7 @@ struct qcthread_s *PDECL PR_ForkStack(pubprogfuncs_t *ppf)
void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
{
progfuncs_t *progfuncs = (progfuncs_t*)ppf;
dfunction_t *f, *oldf;
mfunction_t *f, *oldf;
int i,l,ls;
progsnum_t initial_progs;
int oldexitdepth;
@ -1628,7 +1643,7 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
}
if (i+1 == thread->fstackdepth)
f = &pr_functions[fnum];
f = &pr_cp_functions[fnum];
else
f = pr_progstate[thread->fstack[i+1].progsnum].functions + thread->fstack[i+1].fnum;
for (l = 0; l < f->locals; l++)
@ -1644,7 +1659,7 @@ void PDECL PR_ResumeThread (pubprogfuncs_t *ppf, struct qcthread_s *thread)
PR_RunError(&progfuncs->funcs, "Thread stores incorrect locals count\n");
f = &pr_functions[fnum];
f = &pr_cp_functions[fnum];
// thread->lstackused -= f->locals; //the current function is the odd one out.

View file

@ -61,9 +61,10 @@ typedef struct sharedvar_s
typedef struct
{
int s;
dfunction_t *f;
mfunction_t *f;
int progsnum;
int pushed;
unsigned long long timestamp;
} prstack_t;
typedef struct prinst_s
@ -130,7 +131,7 @@ int reorganisefields;
int exitdepth;
pbool profiling;
dfunction_t *pr_xfunction;
mfunction_t *pr_xfunction;
#define pr_xfunction prinst.pr_xfunction
int pr_xstatement;
#define pr_xstatement prinst.pr_xstatement
@ -297,7 +298,7 @@ typedef enum
typedef struct progstate_s
{
dprograms_t *progs;
dfunction_t *functions;
mfunction_t *functions;
char *strings;
union {
ddefXX_t *globaldefs;
@ -342,7 +343,7 @@ typedef struct extensionbuiltin_s {
#define pr_progs current_progstate->progs
#define pr_functions current_progstate->functions
#define pr_cp_functions current_progstate->functions
#define pr_strings current_progstate->strings
#define pr_globaldefs16 ((ddef16_t*)current_progstate->globaldefs)
#define pr_globaldefs32 ((ddef32_t*)current_progstate->globaldefs)
@ -443,6 +444,49 @@ fdef_t *PDECL ED_FieldInfo (pubprogfuncs_t *progfuncs, unsigned int *count);
char *PDECL PR_UglyValueString (pubprogfuncs_t *progfuncs, etype_t type, eval_t *val);
pbool PDECL ED_ParseEval (pubprogfuncs_t *progfuncs, eval_t *eval, int type, const char *s);
//cpu clock stuff (glorified rdtsc), for profile timing only
#if !defined(Sys_GetClock) && defined(_WIN32)
//windows has some specific functions for this (traditionally wrapping rdtsc)
//note: on some systems, you may need to force cpu affinity to a single core via task manager
static unsigned long long Sys_GetClock(void)
{
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
return li.QuadPart;
}
static unsigned long long Sys_GetClockRate(void)
{
LARGE_INTEGER li;
QueryPerformanceFrequency(&li);
return li.QuadPart;
}
#endif
#if !defined(Sys_GetClock) && defined(__unix__)
//linux/unix has some annoying abstraction and shows time in nanoseconds rather than cycles. lets hope we don't waste too much time reading it.
#include <unistd.h>
#if defined(_POSIX_TIMERS) && _POSIX_TIMERS >= 0
static unsigned long long Sys_GetClock(void)
{
struct timespec c;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &c);
return (c.tv_sec*1000000000ull) + tc.tv_nsec;
}
static unsigned long long Sys_GetClockRate(void)
{
return 1000000000ull;
}
#endif
#endif
#ifndef Sys_GetClock
//other systems have no choice but to omit this feature in some way. this is just for profiling, so we can get away with stubs.
#define Sys_GetClock() 0
#define Sys_GetClockRate() 1
#endif
#endif
@ -477,7 +521,7 @@ ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, const char *name, pr
fdef_t *ED_FindField (progfuncs_t *progfuncs, const char *name);
fdef_t *ED_ClassFieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs, const char *classname);
fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs);
dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, const char *name, progsnum_t *pnum, progsnum_t fromprogs);
mfunction_t *ED_FindFunction (progfuncs_t *progfuncs, const char *name, progsnum_t *pnum, progsnum_t fromprogs);
func_t PDECL PR_FindFunc(pubprogfuncs_t *progfncs, const char *funcname, progsnum_t pnum);
//void PDECL PR_Configure (pubprogfuncs_t *progfncs, size_t addressable_size, int max_progs);
int PDECL PR_InitEnts(pubprogfuncs_t *progfncs, int maxents);

View file

@ -3209,12 +3209,13 @@ QCC_def_t *QCC_PR_ParseImmediate (void)
if (pr_immediate_type == type_string)
{
char tmp[8192];
strcpy(tmp, pr_immediate_string);
strncpy(tmp, pr_immediate_string, sizeof(tmp)-1);
tmp[sizeof(tmp)-1] = 0;
for(;;)
{
QCC_PR_Lex ();
if (pr_token_type == tt_immediate && pr_token_type == tt_immediate)
if (pr_token_type == tt_immediate && pr_immediate_type == type_string)
strcat(tmp, pr_immediate_string);
else
break;

View file

@ -2913,6 +2913,7 @@ int QCC_PR_CheckCompConst(void)
strftime( retbuf, sizeof(retbuf),
"\"%H:%M\"", localtime( &long_time ));
pr_file_p += 8;
QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
return true;
}
@ -2930,15 +2931,17 @@ int QCC_PR_CheckCompConst(void)
return true;
}
if (!strncmp(pr_file_p, "__QCCVER__", 8))
if (!strncmp(pr_file_p, "__RAND__", 8))
{
char retbuf[128];
QC_snprintfz(retbuf, sizeof(retbuf), "%i", rand());
time_t long_time;
time( &long_time );
strftime( retbuf, sizeof(retbuf),
"\"%a %d %b %Y\"", localtime( &long_time ));
pr_file_p += 8;
QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
return true;
}
if (!strncmp(pr_file_p, "__QCCVER__", 8))
{
pr_file_p += 10;
QCC_PR_IncludeChunkEx("FTEQCC "__DATE__","__TIME__"", true, NULL, NULL);
@ -2947,7 +2950,7 @@ int QCC_PR_CheckCompConst(void)
if (!strncmp(pr_file_p, "__FILE__", 8))
{
char retbuf[256];
sprintf(retbuf, "\"%s\"", strings + s_file);
QC_snprintfz(retbuf, sizeof(retbuf), "\"%s\"", strings + s_file);
pr_file_p += 8;
QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
@ -2956,7 +2959,7 @@ int QCC_PR_CheckCompConst(void)
if (!strncmp(pr_file_p, "__LINE__", 8))
{
char retbuf[256];
sprintf(retbuf, "\"%i\"", pr_source_line);
QC_snprintfz(retbuf, sizeof(retbuf), "\"%i\"", pr_source_line);
pr_file_p += 8;
QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
return true;
@ -2964,7 +2967,7 @@ int QCC_PR_CheckCompConst(void)
if (!strncmp(pr_file_p, "__FUNC__", 8))
{
char retbuf[256];
sprintf(retbuf, "\"%s\"",pr_scope?pr_scope->name:"<NO FUNCTION>");
QC_snprintfz(retbuf, sizeof(retbuf), "\"%s\"",pr_scope?pr_scope->name:"<NO FUNCTION>");
pr_file_p += 8;
QCC_PR_IncludeChunkEx(retbuf, true, NULL, NULL);
return true;

View file

@ -92,7 +92,7 @@ int logprintf(const char *format, ...)
int main (int argc, char **argv)
{
int sucess;
pbool sucess;
progexterns_t ext;
progfuncs_t funcs;
progfuncs = &funcs;
@ -113,5 +113,5 @@ int main (int argc, char **argv)
#ifdef _WIN32
// fgetc(stdin); //wait for keypress
#endif
return !sucess;
return sucess?EXIT_SUCCESS:EXIT_FAILURE;
}

View file

@ -10611,10 +10611,17 @@ void PR_DumpPlatform_f(void)
{"VF_SCREENPSIZE", "const float", CS|MENU, "Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect).", VF_SCREENPSIZE},
{"VF_VIEWENTITY", "const float", CS, "Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too.", VF_VIEWENTITY},
{"VF_RT_DESTCOLOUR", "const float", CS|MENU, "The FrameBuffer texture index to write colour info into. 1-based. Additional arguments are: format (rgba8=1,rgba16f=2,rgba32f=3), sizexy. Written to by both 3d and 2d rendering. Note that any rendertargets may be destroyed on video mode changes or so.", VF_RT_DESTCOLOUR},
{"VF_RT_SOURCECOLOUR", "const float", CS|MENU, "The FrameBuffer texture index to use with shaders that specify a $sourcecolour map.", VF_RT_SOURCECOLOUR},
{"VF_RT_DEPTH", "const float", CS|MENU, "The FrameBuffer texture index to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (16bit=4,24bit=5,32bit=6), sizexy.", VF_RT_DEPTH},
{"VF_RT_RIPPLE", "const float", CS|MENU, "The FrameBuffer texture index to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy.", VF_RT_RIPPLE},
{"VF_RT_DESTCOLOUR", "const float", CS|MENU, "The texture name to write colour info into, this includes both 3d and 2d drawing.\nAdditional arguments are: format (rgba8=1,rgba16f=2,rgba32f=3), sizexy.\nWritten to by both 3d and 2d rendering.\nNote that any rendertarget textures may be destroyed on video mode changes or so. Shaders can name render targets by prefixing texture names with '$rt:', or $sourcecolour.", VF_RT_DESTCOLOUR0},
// {"VF_RT_DESTCOLOUR1", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR1},
// {"VF_RT_DESTCOLOUR2", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR2},
// {"VF_RT_DESTCOLOUR3", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR3},
// {"VF_RT_DESTCOLOUR4", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR4},
// {"VF_RT_DESTCOLOUR5", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR5},
// {"VF_RT_DESTCOLOUR6", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR6},
// {"VF_RT_DESTCOLOUR7", "const float", CS|MENU, "Like VF_RT_DESTCOLOUR, for multiple render targets.", VF_RT_DESTCOLOUR7},
{"VF_RT_SOURCECOLOUR", "const float", CS|MENU, "The texture name to use with shaders that specify a $sourcecolour map.", VF_RT_SOURCECOLOUR},
{"VF_RT_DEPTH", "const float", CS|MENU, "The texture name to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (16bit=4,24bit=5,32bit=6), sizexy.", VF_RT_DEPTH},
{"VF_RT_RIPPLE", "const float", CS|MENU, "The texture name to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy.", VF_RT_RIPPLE},
{"RF_VIEWMODEL", "const float", CS, "Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob.", CSQCRF_VIEWMODEL},
{"RF_EXTERNALMODEL", "const float", CS, "Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible.", CSQCRF_EXTERNALMODEL},

View file

@ -762,6 +762,28 @@ void SV_KickSlot_f (void)
Con_Printf("Client %i is not active\n", clnum);
}
//ipv4ify if its an ipv6 ipv4-mapped address.
netadr_t *NET_IPV4ify(netadr_t *a, netadr_t *tmp)
{
if (a->type == NA_IPV6 &&
!*(int*)&a->address.ip6[0] &&
!*(int*)&a->address.ip6[4] &&
!*(short*)&a->address.ip6[8] &&
*(short*)&a->address.ip6[10]==(short)0xffff)
{
tmp->type = NA_IP;
tmp->connum = a->connum;
tmp->scopeid = a->scopeid;
tmp->port = a->port;
tmp->address.ip[0] = a->address.ip6[12];
tmp->address.ip[1] = a->address.ip6[13];
tmp->address.ip[2] = a->address.ip6[14];
tmp->address.ip[3] = a->address.ip6[15];
a = tmp;
}
return a;
}
//will kick clients if they got banned (without being safe)
void SV_EvaluatePenalties(client_t *cl)
{
@ -774,12 +796,14 @@ void SV_EvaluatePenalties(client_t *cl)
int numpenalties = 0;
int numreasons = 0;
int i;
netadr_t tmp, *a;
if (cl->realip.type != NA_INVALID)
{
a = NET_IPV4ify(&cl->realip, &tmp);
for (banip = svs.bannedips; banip; banip=banip->next)
{
if (NET_CompareAdrMasked(&cl->realip, &banip->adr, &banip->adrmask))
if (NET_CompareAdrMasked(a, &banip->adr, &banip->adrmask))
{
for (i = 0; i < sizeof(penaltyreason)/sizeof(penaltyreason[0]); i++)
{
@ -794,9 +818,10 @@ void SV_EvaluatePenalties(client_t *cl)
}
}
}
a = NET_IPV4ify(&cl->netchan.remote_address, &tmp);
for (banip = svs.bannedips; banip; banip=banip->next)
{
if (NET_CompareAdrMasked(&cl->netchan.remote_address, &banip->adr, &banip->adrmask))
if (NET_CompareAdrMasked(a, &banip->adr, &banip->adrmask))
{
for (i = 0; i < sizeof(penaltyreason)/sizeof(penaltyreason[0]); i++)
{
@ -1037,10 +1062,13 @@ char *SV_BannedReason (netadr_t *a)
{
char *reason = filterban.value?NULL:""; //"" = banned with no explicit reason
bannedips_t *banip;
netadr_t tmp;
if (NET_IsLoopBackAddress(a))
return NULL; // never filter loopback
a = NET_IPV4ify(a, &tmp);
for (banip = svs.bannedips; banip; banip=banip->next)
{
if (NET_CompareAdrMasked(a, &banip->adr, &banip->adrmask))
@ -1788,7 +1816,7 @@ static void SV_Status_f (void)
, cl->netchan.qport);
if (cl->download)
{
Con_Printf (" %3i %4i", (cl->downloadcount*100)/cl->downloadsize, cl->downloadsize/1024);
Con_Printf (" %3g %4u", (cl->downloadcount*100.0)/cl->downloadsize, (unsigned int)(cl->downloadsize/1024));
}
if (cl->spectator)
Con_Printf(" (s)\n");
@ -2169,7 +2197,7 @@ void SV_User_f (void)
if (*cl->guid)
Con_Printf("guid: %s\n", cl->guid);
if (cl->download)
Con_Printf ("download: \"%s\" %ik/%ik (%i%%)", cl->downloadfn, cl->downloadcount/1024, cl->downloadsize/1024, (cl->downloadcount*100)/cl->downloadsize);
Con_Printf ("download: \"%s\" %uk/%uk (%g%%)", cl->downloadfn, (unsigned int)(cl->downloadcount/1024), (unsigned int)(cl->downloadsize/1024), (cl->downloadcount*100.0)/cl->downloadsize);
if (cl->penalties & BAN_CRIPPLED)
Con_Printf("crippled\n");

View file

@ -143,6 +143,7 @@ cvar_t sv_minping = CVARF("sv_minping", "", CVAR_SERVERINFO);
cvar_t sv_bigcoords = CVARFD("sv_bigcoords", "", CVAR_SERVERINFO, "Uses floats for coordinates instead of 16bit values. Affects clients thusly:\nQW: enforces a mandatory protocol extension\nDP: enables DPP7 protocol support\nNQ: uses RMQ protocol (protocol 999).");
cvar_t sv_calcphs = CVARFD("sv_calcphs", "2", CVAR_LATCH, "Enables culling of sound effects. 0=always skip phs. Sounds are globally broadcast. 1=always generate phs. Sounds are always culled. On large maps the phs will be dumped to disk. 2=On large single-player maps, generation of phs is skipped. Otherwise like option 1.");
cvar_t sv_showconnectionlessmessages = CVARD("sv_showconnectionlessmessages", "0", "Display a line describing each connectionless message that arrives on the server. Primarily a debugging feature, but also potentially useful to admins.");
cvar_t sv_cullplayers_trace = CVARFD("sv_cullplayers_trace", "", CVAR_SERVERINFO, "Attempt to cull player entities using tracelines as an anti-wallhack.");
cvar_t sv_cullentities_trace = CVARFD("sv_cullentities_trace", "", CVAR_SERVERINFO, "Attempt to cull non-player entities using tracelines as an extreeme anti-wallhack.");
cvar_t sv_phs = CVARD("sv_phs", "1", "If 1, do not use the phs. It is generally better to use sv_calcphs instead, and leave this as 1.");
@ -3954,6 +3955,9 @@ qboolean SV_ConnectionlessPacket (void)
c = Cmd_Argv(0);
if (sv_showconnectionlessmessages.ival)
Con_Printf("%s: %s\n", NET_AdrToString (adr, sizeof(adr), &net_from), s);
if (!strcmp(c, "ping") || ( c[0] == A2A_PING && (c[1] == 0 || c[1] == '\n')) )
SVC_Ping ();
else if (c[0] == A2A_ACK && (c[1] == 0 || c[1] == '\n') )
@ -4645,8 +4649,8 @@ dominping:
continue;
// packet is not from a known client
// Con_Printf ("%s:sequenced packet without connection\n"
// ,NET_AdrToString(net_from));
if (sv_showconnectionlessmessages.ival)
Con_Printf ("%s:sequenced packet without connection\n", NET_AdrToString (com_token, sizeof(com_token), &net_from)); //hack: com_token cos we need some random temp buffer.
}
return received;
@ -5289,7 +5293,8 @@ void SV_InitLocal (void)
#endif
Cvar_Set(&sv_public, "1");
Cvar_Register (&sv_banproxies, "Server Permissions");
Cvar_Register (&sv_showconnectionlessmessages, cvargroup_servercontrol);
Cvar_Register (&sv_banproxies, cvargroup_serverpermissions);
Cvar_Register (&sv_master, cvargroup_servercontrol);
Cvar_Register (&sv_masterport, cvargroup_servercontrol);

View file

@ -1671,7 +1671,7 @@ void SV_ClearQCStats(void)
}
extern cvar_t dpcompat_stats;
void SV_UpdateQCStats(edict_t *ent, int *statsi, const char **statss, float *statsf)
void SV_UpdateQCStats(edict_t *ent, int *statsi, char const** statss, float *statsf)
{
const char *s;
int i;
@ -1722,13 +1722,13 @@ void SV_UpdateQCStats(edict_t *ent, int *statsi, const char **statss, float *sta
}
/*this function calculates the current stat values for the given client*/
void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf[MAX_CL_STATS], char *statss[MAX_CL_STATS])
void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf[MAX_CL_STATS], char const **statss)
{
edict_t *ent;
ent = client->edict;
memset (statsi, 0, sizeof(int)*MAX_CL_STATS);
memset (statsf, 0, sizeof(float)*MAX_CL_STATS);
memset (statss, 0, sizeof(char*)*MAX_CL_STATS);
memset ((void*)statss, 0, sizeof(char const*)*MAX_CL_STATS); //cast needed to get msvc to behave.
// if we are a spectator and we are tracking a player, we get his stats
// so our status bar reflects his

View file

@ -3070,7 +3070,8 @@ void SV_BeginDownload_f(void)
if (ISNQCLIENT(host_client))
{
char *s = va("\ncl_downloadbegin %i %s\n", host_client->downloadsize, host_client->downloadfn);
//FIXME support 64bit files
char *s = va("\ncl_downloadbegin %u %s\n", (unsigned int)host_client->downloadsize, host_client->downloadfn);
ClientReliableWrite_Begin (host_client, svc_stufftext, 2+strlen(s));
ClientReliableWrite_String (host_client, s);
host_client->send_message = true;
@ -5621,7 +5622,7 @@ void AddLinksToPmove_Force ( edict_t *player, areanode_t *node )
link_t *l, *next;
edict_t *check;
int pl;
int i;
// int i;
int solid;
pl = EDICT_TO_PROG(svprogfuncs, player);

View file

@ -2883,20 +2883,53 @@ void JCL_ParseMessage(jclient_t *jcl, xmltree_t *tree)
if (!strcmp(type, "error"))
{
char *reason = NULL;
ot = XML_ChildOfTree(tree, "error", 0);
if (ot->child)
reason = ot->child->name;
if (XML_ChildOfTree(ot, "remote-server-not-found", 0)) reason = "Remote Server Not Found";
if (XML_ChildOfTree(ot, "bad-request", 0)) reason = "Bad Request";
if (XML_ChildOfTree(ot, "conflict", 0)) reason = "Conflict Error";
if (XML_ChildOfTree(ot, "feature-not-implemented", 0)) reason = "feature-not-implemented";
if (XML_ChildOfTree(ot, "forbidden", 0)) reason = "forbidden";
if (XML_ChildOfTree(ot, "gone", 0)) reason = "'gone' Error";
if (XML_ChildOfTree(ot, "internal-server-error", 0)) reason = "internal-server-error";
if (XML_ChildOfTree(ot, "item-not-found", 0)) reason = "item-not-found";
if (XML_ChildOfTree(ot, "jid-malformed", 0)) reason = "jid-malformed";
if (XML_ChildOfTree(ot, "not-acceptable", 0)) reason = "not-acceptable";
if (XML_ChildOfTree(ot, "not-allowed", 0)) reason = "not-allowed";
if (XML_ChildOfTree(ot, "not-authorized", 0)) reason = "not-authorized";
if (XML_ChildOfTree(ot, "policy-violation", 0)) reason = "policy-violation";
if (XML_ChildOfTree(ot, "recipient-unavailable", 0)) reason = "recipient-unavailable";
if (XML_ChildOfTree(ot, "redirect", 0)) reason = "'redirect' Error";
if (XML_ChildOfTree(ot, "registration-required", 0)) reason = "registration-required";
if (XML_ChildOfTree(ot, "remote-server-not-found", 0)) reason = "remote-server-not-found";
if (XML_ChildOfTree(ot, "remote-server-timeout", 0)) reason = "remote-server-timeout";
if (XML_ChildOfTree(ot, "resource-constraint", 0)) reason = "resource-constraint";
if (XML_ChildOfTree(ot, "service-unavailable", 0)) reason = "service-unavailable";
if (XML_ChildOfTree(ot, "subscription-required", 0)) reason = "subscription-required";
if (XML_ChildOfTree(ot, "undefined-condition", 0)) reason = "undefined-condition";
if (XML_ChildOfTree(ot, "unexpected-request", 0)) reason = "unexpected-request";
ot = XML_ChildOfTree(tree, "body", 0);
if (ot)
{
unparsable = false;
if (reason)
Con_SubPrintf(ctx, "^1Error: %s (%s): ", reason, f);
else
Con_SubPrintf(ctx, "^1error sending message to %s: ", f);
if (f)
{
if (!strncmp(ot->body, "/me ", 4))
Con_SubPrintf(ctx, "* ^2%s^7%s\n", f, ot->body+3);
Con_SubPrintf(ctx, "* ^2%s^7%s\n", ((!strcmp(jcl->localalias, ">>"))?"me":jcl->localalias), ot->body+3);
else
Con_SubPrintf(ctx, "^2%s^7: %s\n", f, ot->body);
Con_SubPrintf(ctx, "%s\n", ot->body);
}
}
else
Con_SubPrintf(ctx, "error sending message: %s\r", f);
Con_SubPrintf(ctx, "error sending message to %s\r", f);
return;
}
if (f)
@ -4665,16 +4698,20 @@ void JCL_Command(int accid, char *console)
else if (!strcmp(arg[0]+1, "friend"))
{
//FIXME: validate the name. deal with xml markup.
//try and make sense of the name given
JCL_ToJID(jcl, arg[1], arg[3], sizeof(arg[3]), false);
if (!strchr(arg[3], '@'))
Con_SubPrintf(console, "Missing @ character. Trying anyway, but this will be assumed to be a server rather than a user.\n", arg[0]);
//can also rename. We should probably read back the groups for the update.
JCL_SendIQf(jcl, NULL, "set", NULL, "<query xmlns='jabber:iq:roster'><item jid='%s' name='%s'></item></query>", arg[1], arg[2]);
JCL_SendIQf(jcl, NULL, "set", NULL, "<query xmlns='jabber:iq:roster'><item jid='%s' name='%s'></item></query>", arg[3], arg[2]);
//start looking for em
JCL_AddClientMessagef(jcl, "<presence to='%s' type='subscribe'/>", arg[1]);
JCL_AddClientMessagef(jcl, "<presence to='%s' type='subscribe'/>", arg[13]);
//let em see us
if (jcl->preapproval)
JCL_AddClientMessagef(jcl, "<presence to='%s' type='subscribed'/>", arg[1]);
JCL_AddClientMessagef(jcl, "<presence to='%s' type='subscribed'/>", arg[3]);
}
else if (!strcmp(arg[0]+1, "unfriend"))
{