2005-12-15 19:41:11 +00:00
|
|
|
//included directly from plugin.c
|
|
|
|
//this is the client-only things.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static plugin_t *menuplug; //plugin that has the current menu
|
|
|
|
static plugin_t *protocolclientplugin;
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Menu_Control(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return 0;
|
|
|
|
|
2005-12-15 19:41:11 +00:00
|
|
|
switch(VM_LONG(arg[0]))
|
|
|
|
{
|
|
|
|
case 0: //take away all menus
|
|
|
|
case 1:
|
|
|
|
if (menuplug)
|
|
|
|
{
|
|
|
|
plugin_t *oldplug = currentplug;
|
|
|
|
currentplug = menuplug;
|
|
|
|
Plug_Menu_Event(3, 0);
|
|
|
|
menuplug = NULL;
|
|
|
|
currentplug = oldplug;
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Remove(kdm_emenu);
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
|
|
|
if (VM_LONG(arg[0]) != 1)
|
|
|
|
return 1;
|
|
|
|
//give us menu control
|
|
|
|
menuplug = currentplug;
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Add(kdm_emenu);
|
2005-12-15 19:41:11 +00:00
|
|
|
m_state = m_plugin;
|
|
|
|
return 1;
|
|
|
|
case 2: //weather it's us or not.
|
|
|
|
return currentplug == menuplug && m_state == m_plugin;
|
|
|
|
case 3: //weather a menu is active
|
2015-07-14 14:47:00 +00:00
|
|
|
return !!Key_Dest_Has(kdm_emenu|kdm_gmenu);
|
2005-12-15 19:41:11 +00:00
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Key_GetKeyCode(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
|
|
|
int modifier;
|
|
|
|
return Key_StringToKeynum(VM_POINTER(arg[0]), &modifier);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_SCR_CenterPrint(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return 0;
|
|
|
|
|
2008-11-09 22:29:28 +00:00
|
|
|
SCR_CenterPrint(0, VM_POINTER(arg[0]), true);
|
2005-12-15 19:41:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
//Make SURE that the engine has resolved all cvar pointers into globals before this happens.
|
|
|
|
plugin_t *plugin;
|
|
|
|
char name[64];
|
2013-11-21 23:02:28 +00:00
|
|
|
int type;
|
|
|
|
char *script;
|
2005-12-15 19:41:11 +00:00
|
|
|
mpic_t *pic;
|
|
|
|
} pluginimagearray_t;
|
|
|
|
int pluginimagearraylen;
|
|
|
|
pluginimagearray_t *pluginimagearray;
|
|
|
|
|
2013-11-21 23:02:28 +00:00
|
|
|
#include "shader.h"
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_LoadImage(char *name, int type, char *script)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
mpic_t *pic;
|
|
|
|
|
2006-02-13 01:00:56 +00:00
|
|
|
if (!*name)
|
|
|
|
return 0;
|
|
|
|
|
2005-12-15 19:41:11 +00:00
|
|
|
for (i = 0; i < pluginimagearraylen; i++)
|
|
|
|
{
|
|
|
|
if (!pluginimagearray[i].plugin)
|
|
|
|
break;
|
|
|
|
if (pluginimagearray[i].plugin == currentplug)
|
|
|
|
{
|
|
|
|
if (!strcmp(name, pluginimagearray[i].name))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i == pluginimagearraylen)
|
|
|
|
{
|
|
|
|
pluginimagearraylen++;
|
|
|
|
pluginimagearray = BZ_Realloc(pluginimagearray, pluginimagearraylen*sizeof(pluginimagearray_t));
|
2008-05-09 14:22:37 +00:00
|
|
|
pluginimagearray[i].pic = NULL;
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (pluginimagearray[i].pic)
|
2008-02-19 12:36:51 +00:00
|
|
|
return i+1; //already loaded.
|
2005-12-15 19:41:11 +00:00
|
|
|
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer != QR_NONE)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2013-11-21 23:02:28 +00:00
|
|
|
if (type == 3)
|
|
|
|
pic = NULL;
|
|
|
|
else if (type == 2)
|
|
|
|
pic = R_RegisterShader(name, SUF_NONE, script);
|
|
|
|
else if (type)
|
2011-03-31 01:14:01 +00:00
|
|
|
pic = R2D_SafePicFromWad(name);
|
2005-12-15 19:41:11 +00:00
|
|
|
else
|
2011-03-31 01:14:01 +00:00
|
|
|
pic = R2D_SafeCachePic(name);
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
pic = NULL;
|
|
|
|
|
|
|
|
Q_strncpyz(pluginimagearray[i].name, name, sizeof(pluginimagearray[i].name));
|
2013-11-21 23:02:28 +00:00
|
|
|
pluginimagearray[i].type = type;
|
2005-12-15 19:41:11 +00:00
|
|
|
pluginimagearray[i].pic = pic;
|
|
|
|
pluginimagearray[i].plugin = currentplug;
|
2013-11-21 23:02:28 +00:00
|
|
|
pluginimagearray[i].script = script?Z_StrDup(script):NULL;
|
2006-02-13 01:00:56 +00:00
|
|
|
return i + 1;
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
|
|
|
|
2016-07-12 00:40:13 +00:00
|
|
|
qbyte *Read32BitImageFile(qbyte *buf, int len, int *width, int *height, qboolean *hasalpha, const char *fname);
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_LoadImageData(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
|
|
|
qintptr_t ret = 0;
|
|
|
|
char *name = VM_POINTER(arg[0]);
|
2014-02-13 23:54:57 +00:00
|
|
|
// char *mimetype = VM_POINTER(arg[1]);
|
2013-11-21 23:02:28 +00:00
|
|
|
void *codeddata = VM_POINTER(arg[2]);
|
|
|
|
unsigned int datalength = VM_LONG(arg[3]);
|
2014-10-05 20:04:11 +00:00
|
|
|
image_t *t;
|
2013-11-21 23:02:28 +00:00
|
|
|
qbyte *rgbdata;
|
|
|
|
unsigned int width, height;
|
|
|
|
|
|
|
|
if (VM_OOB(arg[2], arg[3]))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if ((rgbdata = Read32BitImageFile(codeddata, datalength, &width, &height, NULL, name)))
|
|
|
|
{
|
2015-04-14 23:12:17 +00:00
|
|
|
// name = va("%s", name);
|
2014-10-05 20:04:11 +00:00
|
|
|
|
|
|
|
t = Image_FindTexture(name, NULL, IF_NOMIPMAP|IF_UIPIC|IF_CLAMP);
|
2013-11-21 23:02:28 +00:00
|
|
|
if (!TEXVALID(t))
|
2014-10-05 20:04:11 +00:00
|
|
|
t = Image_CreateTexture(name, NULL, IF_NOMIPMAP|IF_UIPIC|IF_CLAMP);
|
2013-11-21 23:02:28 +00:00
|
|
|
if (TEXVALID(t))
|
|
|
|
{
|
2014-10-05 20:04:11 +00:00
|
|
|
Image_Upload(t, TF_RGBA32, rgbdata, NULL, width, height, IF_NOMIPMAP|IF_UIPIC|IF_CLAMP);
|
2013-11-21 23:02:28 +00:00
|
|
|
ret = Plug_Draw_LoadImage(name, 3, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
BZ_Free(rgbdata);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_LoadImageShader(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
|
|
|
char *name = VM_POINTER(arg[0]);
|
|
|
|
char *script = VM_POINTER(arg[1]);
|
|
|
|
return Plug_Draw_LoadImage(name, 2, script);
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_LoadImagePic(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
|
|
|
char *name = VM_POINTER(arg[0]);
|
|
|
|
int type = arg[1];
|
|
|
|
if (type != 0 && type != 1)
|
|
|
|
return 0;
|
|
|
|
return Plug_Draw_LoadImage(name, type, NULL);
|
|
|
|
}
|
|
|
|
|
2005-12-15 19:41:11 +00:00
|
|
|
void Plug_DrawReloadImages(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < pluginimagearraylen; i++)
|
|
|
|
{
|
|
|
|
if (!pluginimagearray[i].plugin)
|
|
|
|
{
|
|
|
|
pluginimagearray[i].pic = NULL;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2011-03-31 01:14:01 +00:00
|
|
|
pluginimagearray[i].pic = R2D_SafePicFromWad(pluginimagearray[i].name);
|
|
|
|
//pluginimagearray[i].pic = R2D_SafeCachePic(pluginimagearray[i].name);
|
|
|
|
//pluginimagearray[i].pic = NULL;
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-31 04:21:08 +00:00
|
|
|
static void Plug_FreePlugImages(plugin_t *plug)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < pluginimagearraylen; i++)
|
|
|
|
{
|
|
|
|
if (pluginimagearray[i].plugin == plug)
|
|
|
|
{
|
|
|
|
pluginimagearray[i].plugin = 0;
|
|
|
|
pluginimagearray[i].pic = NULL;
|
|
|
|
pluginimagearray[i].name[0] = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-21 04:12:00 +00:00
|
|
|
//int R2D_ImageSize (qhandle_t image, float *w, float *h)
|
|
|
|
static qintptr_t VARGS Plug_Draw_ImageSize(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
float *w = VM_POINTER(arg[1]), *h = VM_POINTER(arg[2]);
|
|
|
|
int iw, ih, ret;
|
|
|
|
mpic_t *pic;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (VM_OOB(arg[1], sizeof(*w)) || VM_OOB(arg[2], sizeof(*w)))
|
|
|
|
return -1;
|
|
|
|
*w = 0;
|
|
|
|
*h = 0;
|
|
|
|
if (qrenderer == QR_NONE)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
i = VM_LONG(arg[0]);
|
|
|
|
if (i <= 0 || i > pluginimagearraylen)
|
|
|
|
return -1; // you fool
|
|
|
|
i = i - 1;
|
|
|
|
if (pluginimagearray[i].plugin != currentplug)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (pluginimagearray[i].pic)
|
|
|
|
pic = pluginimagearray[i].pic;
|
|
|
|
else if (pluginimagearray[i].type == 1)
|
|
|
|
return 0; //wasn't loaded.
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pic = R2D_SafeCachePic(pluginimagearray[i].name);
|
|
|
|
if (!pic)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = R_GetShaderSizes(pic, &iw, &ih, true);
|
|
|
|
*w = iw;
|
|
|
|
*h = ih;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-03-31 01:14:01 +00:00
|
|
|
//int R2D_Image (float x, float y, float w, float h, float s1, float t1, float s2, float t2, qhandle_t image)
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_Image(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
|
|
|
mpic_t *pic;
|
|
|
|
int i;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2005-12-15 19:41:11 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
i = VM_LONG(arg[8]);
|
2006-02-13 01:00:56 +00:00
|
|
|
if (i <= 0 || i > pluginimagearraylen)
|
2005-12-15 19:41:11 +00:00
|
|
|
return -1; // you fool
|
2006-02-13 01:00:56 +00:00
|
|
|
i = i - 1;
|
2005-12-15 19:41:11 +00:00
|
|
|
if (pluginimagearray[i].plugin != currentplug)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (pluginimagearray[i].pic)
|
|
|
|
pic = pluginimagearray[i].pic;
|
2013-11-21 23:02:28 +00:00
|
|
|
else if (pluginimagearray[i].type == 1)
|
2005-12-15 19:41:11 +00:00
|
|
|
return 0; //wasn't loaded.
|
|
|
|
else
|
2006-01-21 00:06:49 +00:00
|
|
|
{
|
2011-03-31 01:14:01 +00:00
|
|
|
pic = R2D_SafeCachePic(pluginimagearray[i].name);
|
2006-01-21 00:06:49 +00:00
|
|
|
if (!pic)
|
|
|
|
return -1;
|
|
|
|
}
|
2005-12-15 19:41:11 +00:00
|
|
|
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_Image(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), VM_FLOAT(arg[4]), VM_FLOAT(arg[5]), VM_FLOAT(arg[6]), VM_FLOAT(arg[7]), pic);
|
2005-12-15 19:41:11 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
//x1,y1,x2,y2
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_Line(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2015-04-21 04:12:00 +00:00
|
|
|
R2D_Line(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]), NULL);
|
2005-12-15 19:41:11 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_Character(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2009-11-04 21:16:50 +00:00
|
|
|
int x, y;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return 0;
|
2013-12-29 22:48:28 +00:00
|
|
|
Font_BeginString(font_default, arg[0], arg[1], &x, &y);
|
2015-07-14 14:47:00 +00:00
|
|
|
Font_DrawChar(x, y, CON_WHITEMASK, 0xe000 | (unsigned int)arg[2]);
|
2013-12-29 22:48:28 +00:00
|
|
|
Font_EndString(font_default);
|
2005-12-15 19:41:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2015-06-17 13:05:20 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_CharacterH(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
float x = VM_FLOAT(arg[0]);
|
|
|
|
float y = VM_FLOAT(arg[1]);
|
|
|
|
float h = VM_FLOAT(arg[2]);
|
|
|
|
unsigned int flags = VM_LONG(arg[3]);
|
|
|
|
unsigned int charc = VM_LONG(arg[4]);
|
|
|
|
conchar_t cmask = CON_WHITEMASK;
|
|
|
|
if (qrenderer == QR_NONE)
|
|
|
|
return 0;
|
|
|
|
if (flags & 1)
|
|
|
|
cmask |= CON_2NDCHARSETTEXT;
|
|
|
|
if (!(flags & 2))
|
|
|
|
cmask |= 0xe000;
|
|
|
|
Font_BeginScaledString(font_default, x, y, h, h, &x, &y);
|
2015-07-14 14:47:00 +00:00
|
|
|
Font_DrawScaleChar(x, y, cmask, charc);
|
2015-06-17 13:05:20 +00:00
|
|
|
Font_EndString(font_default);
|
|
|
|
return 0;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_String(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2013-11-21 23:02:28 +00:00
|
|
|
{
|
|
|
|
int ipx, px, py;
|
|
|
|
conchar_t buffer[2048], *str;
|
2015-07-14 14:47:00 +00:00
|
|
|
unsigned int codeflags, codepoint;
|
2013-11-21 23:02:28 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
|
|
|
return 0;
|
|
|
|
COM_ParseFunString(CON_WHITEMASK, VM_POINTER(arg[2]), buffer, sizeof(buffer), false);
|
|
|
|
str = buffer;
|
2013-12-29 22:48:28 +00:00
|
|
|
Font_BeginString(font_default, VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), &px, &py);
|
2013-11-21 23:02:28 +00:00
|
|
|
ipx = px;
|
|
|
|
while(*str)
|
|
|
|
{
|
2015-07-14 14:47:00 +00:00
|
|
|
str = Font_Decode(str, &codeflags, &codepoint);
|
|
|
|
if (codepoint == '\n')
|
2013-11-21 23:02:28 +00:00
|
|
|
py += Font_CharHeight();
|
2015-07-14 14:47:00 +00:00
|
|
|
else if (codepoint == '\r')
|
2013-11-21 23:02:28 +00:00
|
|
|
px = ipx;
|
|
|
|
else
|
2015-07-14 14:47:00 +00:00
|
|
|
px = Font_DrawChar(px, py, codeflags, codepoint);
|
2013-11-21 23:02:28 +00:00
|
|
|
}
|
2013-12-29 22:48:28 +00:00
|
|
|
Font_EndString(font_default);
|
2013-11-21 23:02:28 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2015-06-17 13:05:20 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_StringH(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
float x = VM_FLOAT(arg[0]);
|
|
|
|
float y = VM_FLOAT(arg[1]);
|
|
|
|
float h = VM_FLOAT(arg[2]);
|
|
|
|
unsigned int flags = VM_LONG(arg[3]);
|
|
|
|
char *instr = VM_POINTER(arg[4]);
|
|
|
|
float ipx;
|
|
|
|
conchar_t buffer[2048], *str, cmask = CON_WHITEMASK;
|
2015-07-14 14:47:00 +00:00
|
|
|
unsigned int codeflags, codepoint;
|
2015-06-17 13:05:20 +00:00
|
|
|
unsigned int parseflags = 0;
|
|
|
|
if (qrenderer == QR_NONE)
|
|
|
|
return 0;
|
|
|
|
if (flags & 1)
|
|
|
|
cmask |= CON_2NDCHARSETTEXT;
|
|
|
|
if (flags & 2)
|
|
|
|
parseflags |= PFS_FORCEUTF8;
|
|
|
|
COM_ParseFunString(CON_WHITEMASK, instr, buffer, sizeof(buffer), parseflags);
|
|
|
|
str = buffer;
|
|
|
|
Font_BeginScaledString(font_default, x, y, h, h, &x, &y);
|
|
|
|
ipx = x;
|
|
|
|
while(*str)
|
|
|
|
{
|
2015-07-14 14:47:00 +00:00
|
|
|
str = Font_Decode(str, &codeflags, &codepoint);
|
|
|
|
if (codepoint == '\n')
|
2015-06-17 13:05:20 +00:00
|
|
|
y += Font_CharScaleHeight();
|
2015-07-14 14:47:00 +00:00
|
|
|
else if (codepoint == '\r')
|
2015-06-17 13:05:20 +00:00
|
|
|
x = ipx;
|
|
|
|
else
|
2015-07-14 14:47:00 +00:00
|
|
|
x = Font_DrawScaleChar(x, y, codeflags, codepoint);
|
2015-06-17 13:05:20 +00:00
|
|
|
}
|
|
|
|
Font_EndString(font_default);
|
|
|
|
return 0;
|
|
|
|
}
|
2011-03-31 01:14:01 +00:00
|
|
|
|
2015-10-27 15:20:15 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_StringWidth(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
qintptr_t ret;
|
|
|
|
float h = VM_FLOAT(arg[0]);
|
|
|
|
unsigned int flags = VM_LONG(arg[1]);
|
|
|
|
char *instr = VM_POINTER(arg[2]);
|
|
|
|
conchar_t buffer[2048], *str, cmask = CON_WHITEMASK;
|
|
|
|
unsigned int parseflags = 0;
|
|
|
|
float px,py;
|
|
|
|
if (qrenderer == QR_NONE)
|
|
|
|
return 0;
|
|
|
|
if (flags & 1)
|
|
|
|
cmask |= CON_2NDCHARSETTEXT;
|
|
|
|
if (flags & 2)
|
|
|
|
parseflags |= PFS_FORCEUTF8;
|
|
|
|
str = COM_ParseFunString(CON_WHITEMASK, instr, buffer, sizeof(buffer), parseflags);
|
|
|
|
|
|
|
|
Font_BeginScaledString(font_default, 0, 0, h, h, &px, &py);
|
|
|
|
px = Font_LineScaleWidth(buffer, str);
|
|
|
|
Font_EndString(NULL);
|
|
|
|
|
|
|
|
//put it back in virtual space
|
|
|
|
VM_FLOAT(ret) = (px*(float)vid.width) / (float)vid.rotpixelwidth;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_Fill(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
|
|
|
float x, y, width, height;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return 0;
|
2005-12-15 19:41:11 +00:00
|
|
|
x = VM_FLOAT(arg[0]);
|
|
|
|
y = VM_FLOAT(arg[1]);
|
|
|
|
width = VM_FLOAT(arg[2]);
|
|
|
|
height = VM_FLOAT(arg[3]);
|
2011-03-31 01:14:01 +00:00
|
|
|
|
|
|
|
R2D_FillBlock(x, y, width, height);
|
2005-12-15 19:41:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_ColourP(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2015-06-17 13:05:20 +00:00
|
|
|
int p = VM_LONG(arg[0]);
|
|
|
|
if (p<0 || p>255)
|
2005-12-15 19:41:11 +00:00
|
|
|
return false;
|
|
|
|
|
2015-06-17 13:05:20 +00:00
|
|
|
R2D_ImagePaletteColour(p, 1);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
static qintptr_t VARGS Plug_Draw_ColourPA(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
int p = VM_LONG(arg[0]);
|
|
|
|
float a = VM_FLOAT(arg[1]);
|
|
|
|
if (p<0 || p>255)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
R2D_ImagePaletteColour(p, a);
|
2011-03-31 01:14:01 +00:00
|
|
|
return 1;
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_Colour3f(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), 1);
|
|
|
|
return 1;
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Draw_Colour4f(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2011-03-31 01:14:01 +00:00
|
|
|
R2D_ImageColours(VM_FLOAT(arg[0]), VM_FLOAT(arg[1]), VM_FLOAT(arg[2]), VM_FLOAT(arg[3]));
|
|
|
|
return 1;
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_LocalSound(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return false;
|
|
|
|
|
2005-12-15 19:41:11 +00:00
|
|
|
S_LocalSound(VM_POINTER(arg[0]));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_CL_GetStats(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
2016-08-25 00:12:14 +00:00
|
|
|
int i = 0;
|
2005-12-15 19:41:11 +00:00
|
|
|
int pnum = VM_LONG(arg[0]);
|
|
|
|
unsigned int *stats = VM_POINTER(arg[1]);
|
|
|
|
int pluginstats = VM_LONG(arg[2]);
|
|
|
|
int max;
|
|
|
|
|
|
|
|
if (VM_OOB(arg[1], arg[2]*4))
|
|
|
|
return 0;
|
|
|
|
|
2013-03-31 04:21:08 +00:00
|
|
|
if (qrenderer == QR_NONE || !cls.state)
|
|
|
|
return 0;
|
2006-01-02 23:01:54 +00:00
|
|
|
|
2005-12-15 19:41:11 +00:00
|
|
|
max = pluginstats;
|
|
|
|
if (max > MAX_CL_STATS)
|
|
|
|
max = MAX_CL_STATS;
|
2016-08-25 00:12:14 +00:00
|
|
|
if (pnum < 0)
|
|
|
|
{
|
|
|
|
pnum = -pnum-1;
|
|
|
|
if (pnum < MAX_CLIENTS)
|
|
|
|
{
|
|
|
|
for (i = 0; i < max; i++)
|
|
|
|
stats[i] = cl.players[pnum].stats[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (pnum < cl.splitclients)
|
|
|
|
{
|
|
|
|
for (i = 0; i < max; i++)
|
|
|
|
{ //fill stats with the right player's stats
|
|
|
|
stats[i] = cl.playerview[pnum].stats[i];
|
|
|
|
}
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
2016-08-25 00:12:14 +00:00
|
|
|
|
|
|
|
max = i;
|
2005-12-15 19:41:11 +00:00
|
|
|
for (; i < pluginstats; i++) //plugin has too many stats (wow)
|
|
|
|
stats[i] = 0; //fill the rest.
|
|
|
|
return max;
|
|
|
|
}
|
|
|
|
|
2006-01-21 00:06:49 +00:00
|
|
|
#define PLUGMAX_SCOREBOARDNAME 64
|
|
|
|
typedef struct {
|
|
|
|
int topcolour;
|
|
|
|
int bottomcolour;
|
|
|
|
int frags;
|
|
|
|
char name[PLUGMAX_SCOREBOARDNAME];
|
|
|
|
int ping;
|
|
|
|
int pl;
|
2015-06-24 17:59:57 +00:00
|
|
|
float activetime;
|
2006-01-21 00:06:49 +00:00
|
|
|
int userid;
|
|
|
|
int spectator;
|
|
|
|
char userinfo[1024];
|
|
|
|
char team[8];
|
|
|
|
} vmplugclientinfo_t;
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_GetPlayerInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2006-01-21 00:06:49 +00:00
|
|
|
{
|
|
|
|
int i, pt;
|
|
|
|
vmplugclientinfo_t *out;
|
|
|
|
|
|
|
|
if (VM_OOB(arg[1], sizeof(vmplugclientinfo_t)))
|
|
|
|
return -1;
|
|
|
|
if (VM_LONG(arg[0]) < -1 || VM_LONG(arg[0] ) >= MAX_CLIENTS)
|
|
|
|
return -2;
|
|
|
|
|
|
|
|
i = VM_LONG(arg[0]);
|
|
|
|
out = VM_POINTER(arg[1]);
|
2007-10-05 10:46:26 +00:00
|
|
|
if (out)
|
2006-01-21 00:06:49 +00:00
|
|
|
{
|
2013-06-23 02:17:02 +00:00
|
|
|
if (i < 0)
|
2006-01-21 00:06:49 +00:00
|
|
|
{
|
2013-06-23 02:17:02 +00:00
|
|
|
if (i >= -MAX_SPLITS)
|
|
|
|
i = cl.playerview[-i-1].playernum;
|
2007-10-05 10:46:26 +00:00
|
|
|
if (i < 0)
|
|
|
|
{
|
|
|
|
memset(out, 0, sizeof(*out));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out->bottomcolour = cl.players[i].rbottomcolor;
|
|
|
|
out->topcolour = cl.players[i].rtopcolor;
|
|
|
|
out->frags = cl.players[i].frags;
|
|
|
|
Q_strncpyz(out->name, cl.players[i].name, PLUGMAX_SCOREBOARDNAME);
|
|
|
|
out->ping = cl.players[i].ping;
|
|
|
|
out->pl = cl.players[i].pl;
|
2015-06-24 17:59:57 +00:00
|
|
|
out->activetime = realtime - cl.players[i].realentertime;
|
2007-10-05 10:46:26 +00:00
|
|
|
out->userid = cl.players[i].userid;
|
|
|
|
out->spectator = cl.players[i].spectator;
|
|
|
|
Q_strncpyz(out->userinfo, cl.players[i].userinfo, sizeof(out->userinfo));
|
|
|
|
Q_strncpyz(out->team, cl.players[i].team, sizeof(out->team));
|
2006-01-21 00:06:49 +00:00
|
|
|
}
|
|
|
|
|
2013-06-23 02:17:02 +00:00
|
|
|
pt = Cam_TrackNum(&cl.playerview[0]);
|
2006-01-21 00:06:49 +00:00
|
|
|
if (pt < 0)
|
2013-06-23 02:17:02 +00:00
|
|
|
return (cl.playerview[0].playernum == i);
|
2006-01-21 00:06:49 +00:00
|
|
|
else
|
|
|
|
return pt == i;
|
|
|
|
}
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_LocalPlayerNumber(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2007-02-23 00:21:33 +00:00
|
|
|
{
|
2013-06-23 02:17:02 +00:00
|
|
|
return cl.playerview[0].playernum;
|
2007-02-23 00:21:33 +00:00
|
|
|
}
|
2015-04-21 04:12:00 +00:00
|
|
|
static qintptr_t VARGS Plug_GetLocalPlayerNumbers(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
int first = VM_LONG(arg[0]);
|
|
|
|
int count = VM_LONG(arg[1]);
|
|
|
|
int *playernums = VM_POINTER(arg[2]);
|
|
|
|
int *spectracks = VM_POINTER(arg[3]);
|
|
|
|
if (count < 0 || count > 1000) count = 0;
|
|
|
|
if (VM_OOB(arg[2], sizeof(*playernums)*count) || VM_OOB(arg[3], sizeof(*playernums)*count))
|
|
|
|
return false;
|
|
|
|
if (first < 0) first = 0;
|
|
|
|
if (first > cl.splitclients) first = cl.splitclients;
|
|
|
|
if (first+count > cl.splitclients) count = cl.splitclients-first;
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
playernums[i] = cl.playerview[i].playernum;
|
|
|
|
spectracks[i] = Cam_TrackNum(&cl.playerview[i]);
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
2007-02-23 00:21:33 +00:00
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_GetServerInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2007-02-23 00:21:33 +00:00
|
|
|
{
|
|
|
|
char *outptr = VM_POINTER(arg[0]);
|
2007-10-05 10:46:26 +00:00
|
|
|
unsigned int outlen = VM_LONG(arg[1]);
|
2015-04-21 04:12:00 +00:00
|
|
|
extern float demtime;
|
2007-02-23 00:21:33 +00:00
|
|
|
|
|
|
|
if (VM_OOB(arg[0], outlen))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Q_strncpyz(outptr, cl.serverinfo, outlen);
|
2015-09-01 04:45:15 +00:00
|
|
|
Q_strncatz(outptr, va("\\intermission\\%i", cl.intermissionmode), outlen);
|
2015-04-21 04:12:00 +00:00
|
|
|
switch(cls.demoplayback)
|
|
|
|
{
|
|
|
|
case DPB_NONE:
|
|
|
|
break;
|
|
|
|
case DPB_MVD:
|
|
|
|
case DPB_EZTV:
|
|
|
|
Q_strncatz(outptr, "\\demotype\\mvd", outlen);
|
|
|
|
break;
|
|
|
|
case DPB_QUAKEWORLD:
|
|
|
|
Q_strncatz(outptr, "\\demotype\\qw", outlen);
|
|
|
|
break;
|
|
|
|
#ifdef NQPROT
|
|
|
|
case DPB_NETQUAKE:
|
|
|
|
Q_strncatz(outptr, "\\demotype\\nq", outlen);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
#ifdef Q2CLIENT
|
|
|
|
case DPB_QUAKE2:
|
|
|
|
Q_strncatz(outptr, "\\demotype\\q2", outlen);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
Q_strncatz(outptr, va("\\demotime\\%f", demtime-cls.demostarttime), outlen);
|
2007-02-23 00:21:33 +00:00
|
|
|
|
2015-09-01 04:45:15 +00:00
|
|
|
#ifdef QUAKEHUD
|
2015-06-17 13:05:20 +00:00
|
|
|
if (cl.playerview[0].statsf[STAT_MATCHSTARTTIME])
|
2015-07-04 02:04:46 +00:00
|
|
|
Q_strncatz(outptr, va("\\matchstart\\%f", cl.playerview[0].statsf[STAT_MATCHSTARTTIME]/1000), outlen);
|
2015-09-01 04:45:15 +00:00
|
|
|
else
|
|
|
|
#endif
|
2015-06-17 13:05:20 +00:00
|
|
|
Q_strncatz(outptr, va("\\matchstart\\%f", cl.matchgametimestart), outlen);
|
|
|
|
|
2007-02-23 00:21:33 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_SetUserInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2007-02-23 00:21:33 +00:00
|
|
|
{
|
|
|
|
char *key = VM_POINTER(arg[0]);
|
|
|
|
char *value = VM_POINTER(arg[1]);
|
|
|
|
|
2010-08-14 03:17:33 +00:00
|
|
|
CL_SetInfo(0, key, value);
|
2007-02-23 00:21:33 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2005-12-15 19:41:11 +00:00
|
|
|
|
2015-04-21 04:12:00 +00:00
|
|
|
typedef struct {
|
|
|
|
int seats;
|
|
|
|
struct
|
|
|
|
{
|
2015-06-12 14:44:50 +00:00
|
|
|
float s_avg;
|
|
|
|
float s_mn;
|
|
|
|
float s_mx;
|
|
|
|
float ms_stddev;
|
|
|
|
float fr_avg;
|
|
|
|
int fr_mn;
|
|
|
|
int fr_mx;
|
2015-04-21 04:12:00 +00:00
|
|
|
} ping;
|
2015-06-12 14:44:50 +00:00
|
|
|
struct
|
|
|
|
{ //decimals
|
|
|
|
float dropped;
|
|
|
|
float choked;
|
|
|
|
float invalid;
|
|
|
|
} loss;
|
2015-04-21 04:12:00 +00:00
|
|
|
float mlatency;
|
|
|
|
float mrate;
|
|
|
|
float vlatency;
|
|
|
|
float vrate;
|
|
|
|
vec3_t speed; //player speed
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
float in_pps;
|
|
|
|
float in_bps;
|
|
|
|
float out_pps;
|
|
|
|
float out_bps;
|
|
|
|
} clrate;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
float in_pps;
|
|
|
|
float in_bps;
|
|
|
|
float out_pps;
|
|
|
|
float out_bps;
|
|
|
|
} svrate;
|
2015-06-12 14:44:50 +00:00
|
|
|
int capturing;
|
2015-04-21 04:12:00 +00:00
|
|
|
} vmnetinfo_t;
|
|
|
|
#define has(x) (((quintptr_t)&((vmnetinfo_t*)NULL)->x + sizeof(((vmnetinfo_t*)NULL)->x)) <= outlen)
|
|
|
|
//aka: misc other hud timing crap
|
|
|
|
static qintptr_t VARGS Plug_GetNetworkInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
vmnetinfo_t *outptr = VM_POINTER(arg[0]);
|
|
|
|
unsigned int outlen = VM_LONG(arg[1]);
|
|
|
|
if (VM_OOB(arg[0], outlen))
|
|
|
|
return false;
|
2015-06-12 14:44:50 +00:00
|
|
|
|
|
|
|
if (has(capturing))
|
|
|
|
{
|
2017-02-21 20:22:07 +00:00
|
|
|
#ifdef HAVE_MEDIA_ENCODER
|
dpp7: Treat 'dropped' c2s packets as choked when using dpp7 protocols. This is because the protocol provides no way to disambiguate, and I don't like false reports of packetloss (only reliables loss can be detected, and that's not frequent enough to be meaningful). Pings can still be determined with dpp7, for those few packets which are acked.
package manager: reworked to enable/disable plugins when downloaded, which can also be present-but-disabled.
package manager: display a confirmation prompt before applying changes. do not allow other changes to be made while applying. prompt may be skipped with 'pkg apply' in dedicated servers.
sv: downloads are no longer forced to lower case.
sv: added sv_demoAutoCompress cvar. set to 1 to directly record to *.mvd.gz
cl: properly support directly playing .mvd.gz files
menus: reworked to separate mouse and keyboard focus. mouse focus becomes keyboard focus only on mouse clicks. tooltips follow mouse cursors.
menus: cleaned up menu heirachy a little. now simpler.
server browser: changed 'hide *' filters to 'show *' instead. I felt it was more logical.
deluxmapping: changed to disabled, load, generate, like r_loadlit is.
render targets api now supports negative formats to mean nearest filtering, where filtering is part of texture state.
drawrotpic fixed, now batches and interacts with drawpic correctly.
drawline fixed, no interacts with draw* correctly, but still does not batch.
fixed saving games.
provide proper userinfo to nq clients, where supported.
qcc: catch string table overflows safely, giving errors instead of crashes. switch to 32bit statements if some over-sized function requires it.
qtv: some bigcoords support tweaks
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5073 fc73d0e0-1445-4013-8a0c-d673dee63da5
2017-03-21 05:27:07 +00:00
|
|
|
outptr->capturing = Media_Capturing();
|
2015-06-12 14:44:50 +00:00
|
|
|
#else
|
2017-02-21 20:22:07 +00:00
|
|
|
outptr->capturing = 0;
|
2015-06-12 14:44:50 +00:00
|
|
|
#endif
|
|
|
|
}
|
2015-04-21 04:12:00 +00:00
|
|
|
|
|
|
|
if (has(seats))
|
|
|
|
outptr->seats = cl.splitclients;
|
|
|
|
if (has(ping))
|
2015-06-12 14:44:50 +00:00
|
|
|
CL_CalcNet2 (&outptr->ping.s_avg, &outptr->ping.s_mn, &outptr->ping.s_mx, &outptr->ping.ms_stddev, &outptr->ping.fr_avg, &outptr->ping.fr_mn, &outptr->ping.fr_mx, &outptr->loss.dropped, &outptr->loss.choked, &outptr->loss.invalid);
|
2015-04-21 04:12:00 +00:00
|
|
|
|
|
|
|
if (has(mlatency))
|
|
|
|
outptr->mlatency = 0;
|
|
|
|
if (has(mrate))
|
Reworked client support for DPP5+. less code now, its much more graceful.
added waterfog command. waterfog overrides regular fog only when the view is in water.
fixed 64bit printf format specifiers. should work better on winxp64.
fixed some spec angle weirdness.
fixed viewsize 99.99 weirdness with ezhud.
fixed extra offset on the console (exhibited in 64bit builds, but not limited to).
fixed .avi playback, can now actually display frames again.
reimplemented line sparks.
fixed r_editlights_save flipping the light's pitch.
fixed issue with oggs failing to load.
fixed condump to cope with unicode properly.
made sv_bigcoords default except in quake. hexen2 kinda needs it for bsp angle precision.
fixed nq server to not stall weirdly on map changes.
fixed qwprogs svc_cdtrack not bugging out with nq clients on the server.
fixed restart command to load the last map run by the server, instead of start.bsp (when idle)
optimised d3d9 renderer a little. now uses less draw calls, especially with complex scenes. seems to get higher framerates than opengl now.
fixed d3d9 renderer to not bug out quite so much when run fullscreen (shader subsystem is now correctly initialised).
fixed a couple of bugs from font change. also now supports utf-8 in a few more places.
r_editlights_reload no longer generates rtlights inside the void. this resolves a few glitches (but should also help framerates a little).
fixed so corona-only lights won't generate shadowmaps and waste lots of time.
removed lots of #defines from qclib. I should never have made them in the first place, but I was lazy. obviously there's more left that I cba to remove yet.
fixed nested calls with variant-vectors. this fixes csaddon's light editor.
fixed qcc hc calling conventions using redundant stores.
disabled keywords can still be used by using __keyword instead.
fixed ftegccgui grep feature.
fixed motionless-dog qcc bug.
tweaked qcc warnings a little. -Wall is now a viable setting. you should be able to fix all those warnings.
fixed qw svc_intermission + dpp5+ clients bug.
fixed annoying spam about disconnecting in hexen2.
rewrote status command a little to cope with ipv6 addresses more gracefully
fixed significant stall when hibernating/debugging a server with a player sitting on it.
fixed truelightning.
fixed rocketlight overriding pflags.
fixed torches vanishing on vid_restart.
fixed issue with decal scaling.
fixed findentityfield builtin.
fixed fteqcc issue with ptr+1
fixed use of arrays inside class functions.
fixed/implemented fteqcc emulation of pointer opcodes.
added __inout keyword to fteqcc, so that it doesn't feel so horrendous.
fixed sizeof(*foo)
fixed *struct = struct;
fixed recursive structs.
fixed fteqcc warning report.
fixed sdl2 controller support, hopefully.
attempted to implement xinput, including per-player audio playback.
slightly fixed relaxed attitude to mouse focus when running fullscreen.
fixed weird warnings/errors with 'ent.arrayhead' terms. now generates sane errors.
implemented bindmaps (for csqc).
fixed crashing bug with eprint builtin.
implemented subset of music_playlist_* functionality. significant changes to music playback.
fixed some more dpcsqc compat.
fixed binds menu. now displays and accepts modifiers.
fixed issues with huge lightmaps.
fixed protocol determinism with dp clients connecting to fte servers. the initial getchallenge request now inhibits vanilla nq connection requests.
implemented support for 'dupe' userinfo key, allowing clients to request client->server packet duplication. should probably queue them tbh.
implemented sv_saveentfile command.
fixed resume after breaking inside a stepped-over function.
fixed erroneous footer after debugging.
(I wonder just how many things I broke with these fixes)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4946 fc73d0e0-1445-4013-8a0c-d673dee63da5
2015-07-26 10:56:18 +00:00
|
|
|
outptr->mrate = IN_DetermineMouseRate();
|
2015-04-21 04:12:00 +00:00
|
|
|
if (has(vlatency))
|
|
|
|
outptr->vlatency = 0;
|
|
|
|
|
|
|
|
if (has(speed))
|
|
|
|
VectorCopy(outptr->speed, r_refdef.playerview->simvel);
|
|
|
|
|
|
|
|
if (has(clrate))
|
|
|
|
NET_GetRates(cls.sockets, &outptr->clrate.in_pps, &outptr->clrate.out_pps, &outptr->clrate.in_bps, &outptr->clrate.out_bps);
|
|
|
|
if (has(svrate))
|
|
|
|
{
|
|
|
|
memset(&outptr->svrate, 0, sizeof(outptr->svrate));
|
|
|
|
#ifndef CLIENTONLY
|
|
|
|
NET_GetRates(svs.sockets, &outptr->svrate.in_pps, &outptr->svrate.out_pps, &outptr->svrate.in_bps, &outptr->svrate.out_bps);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return sizeof(vmnetinfo_t);
|
|
|
|
}
|
|
|
|
#undef has
|
|
|
|
|
2015-11-18 07:37:39 +00:00
|
|
|
static qintptr_t VARGS Plug_GetTrackerOwnFrags(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int seat = VM_LONG(arg[0]);
|
|
|
|
char *outptr = VM_POINTER(arg[1]);
|
|
|
|
size_t outlen = VM_LONG(arg[2]);
|
|
|
|
if (VM_OOB(arg[1], outlen) || !outlen)
|
|
|
|
VM_FLOAT(ret) = 0;
|
|
|
|
else
|
|
|
|
VM_FLOAT(ret) = Stats_GetLastOwnFrag(seat, outptr, outlen);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_GetLocationName(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2007-10-05 10:46:26 +00:00
|
|
|
{
|
|
|
|
float *locpoint = VM_POINTER(arg[0]);
|
|
|
|
char *locname = VM_POINTER(arg[1]);
|
|
|
|
unsigned int locnamelen = VM_LONG(arg[2]);
|
|
|
|
char *result;
|
|
|
|
|
|
|
|
if (VM_OOB(arg[1], locnamelen))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
result = TP_LocationName(locpoint);
|
|
|
|
Q_strncpyz(locname, result, locnamelen);
|
|
|
|
return VM_LONG(arg[1]);
|
|
|
|
}
|
|
|
|
|
2015-09-01 04:45:15 +00:00
|
|
|
#ifdef QUAKEHUD
|
2015-06-29 23:46:31 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
unsigned int client;
|
|
|
|
unsigned int items;
|
|
|
|
float armor;
|
|
|
|
float health;
|
|
|
|
vec3_t org;
|
|
|
|
char nick[16];
|
|
|
|
} teamplayerinfo_t;
|
|
|
|
static qintptr_t VARGS Plug_GetTeamInfo(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
teamplayerinfo_t *players = VM_POINTER(arg[0]);
|
|
|
|
size_t maxplayers = VM_LONG(arg[1]);
|
|
|
|
qboolean showenemies = VM_LONG(arg[2]);
|
|
|
|
qboolean showself = VM_LONG(arg[3]);
|
|
|
|
int count = 0;
|
|
|
|
int i;
|
|
|
|
int self;
|
|
|
|
lerpents_t *le;
|
|
|
|
player_info_t *pl;
|
|
|
|
|
|
|
|
if (VM_OOB(arg[0], maxplayers*sizeof(*players)))
|
|
|
|
return 0;
|
|
|
|
maxplayers = min(maxplayers, cl.allocated_client_slots);
|
|
|
|
|
|
|
|
Cvar_Get("ti", "1", CVAR_USERINFO, "Hacks because ktx sucks. Must be 1 in order to receive team information in ktx.");
|
|
|
|
|
|
|
|
self = cl.playerview[0].playernum;
|
|
|
|
if (cl.playerview[0].cam_state != CAM_FREECAM)
|
|
|
|
self = cl.playerview[0].cam_spec_track;
|
|
|
|
|
|
|
|
for (i = 0; i < cl.allocated_client_slots && maxplayers > 0; i++)
|
|
|
|
{
|
|
|
|
if (!*cl.players[i].name) //empty slot
|
|
|
|
continue;
|
|
|
|
if (cl.players[i].spectator) //shoo!
|
|
|
|
continue;
|
|
|
|
if (i == self && !showself)
|
|
|
|
continue;
|
|
|
|
if (!showenemies && strcmp(cl.players[i].team, cl.players[self].team))
|
|
|
|
continue;
|
|
|
|
players->client = i;
|
2015-06-30 14:05:45 +00:00
|
|
|
|
2015-06-29 23:46:31 +00:00
|
|
|
pl = &cl.players[i];
|
|
|
|
if (pl->tinfo.time > cl.time)
|
|
|
|
{ //mod is explicitly telling us this junk
|
|
|
|
players->items = pl->tinfo.items;
|
|
|
|
players->health = pl->tinfo.health;
|
|
|
|
players->armor = pl->tinfo.armour;
|
|
|
|
VectorCopy(pl->tinfo.org, players->org);
|
|
|
|
Q_strncpyz(players->nick, pl->tinfo.nick, sizeof(players->nick));
|
|
|
|
}
|
|
|
|
else if (i == self)
|
|
|
|
{ //oh hey look, its me.
|
|
|
|
players->items = cl.playerview[0].stats[STAT_ITEMS];
|
|
|
|
players->armor = cl.playerview[0].statsf[STAT_ARMOR];
|
|
|
|
players->health = cl.playerview[0].statsf[STAT_HEALTH];
|
|
|
|
Q_strncpyz(players->nick, "", sizeof(players->nick));
|
|
|
|
}
|
2015-06-30 14:05:45 +00:00
|
|
|
else if (cls.demoplayback == DPB_MVD || cls.demoplayback == DPB_EZTV)
|
2015-06-29 23:46:31 +00:00
|
|
|
{ //scrape it from the mvd (assuming there is one...
|
|
|
|
players->items = cl.players[i].stats[STAT_ITEMS];
|
|
|
|
players->armor = cl.players[i].statsf[STAT_ARMOR];
|
|
|
|
players->health = cl.players[i].statsf[STAT_HEALTH];
|
|
|
|
Q_strncpyz(players->nick, "", sizeof(players->nick));
|
|
|
|
|
|
|
|
VectorClear(players->org);
|
|
|
|
}
|
2015-06-30 14:05:45 +00:00
|
|
|
else
|
|
|
|
continue; //no stats, don't bother telling the plugin.
|
|
|
|
|
2015-06-29 23:46:31 +00:00
|
|
|
//scrape origin from interpolation, if its more valid.
|
|
|
|
if (i+1 < cl.maxlerpents && cl.lerpentssequence && cl.lerpents[i+1].sequence == cl.lerpentssequence)
|
|
|
|
{
|
|
|
|
le = &cl.lerpents[i+1];
|
|
|
|
VectorCopy(le->origin, players->org);
|
|
|
|
}
|
|
|
|
else if (cl.lerpentssequence && cl.lerpplayers[i].sequence == cl.lerpentssequence)
|
|
|
|
{
|
|
|
|
le = &cl.lerpplayers[i];
|
|
|
|
VectorCopy(le->origin, players->org);
|
|
|
|
}
|
|
|
|
|
|
|
|
players++;
|
|
|
|
maxplayers--;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return VM_LONG(count);
|
|
|
|
}
|
2015-09-01 04:45:15 +00:00
|
|
|
#endif
|
2015-10-27 15:20:15 +00:00
|
|
|
#ifdef QUAKEHUD
|
|
|
|
static qintptr_t VARGS Plug_GetWeaponStats(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
int self = VM_LONG(arg[0]);
|
|
|
|
struct wstats_s *result = VM_POINTER(arg[1]);
|
|
|
|
size_t maxresults = VM_LONG(arg[2]);
|
|
|
|
|
|
|
|
if (VM_OOB(arg[0], maxresults*sizeof(*result)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
//FIXME: we should support some way to clear this to 0 again, other than nosave.
|
|
|
|
Cvar_Get("wpsx", "1", CVAR_USERINFO|CVAR_NOSAVE, "Hacks because ktx sucks. Must be 1 in order to receive weapon stats information in ktx.");
|
|
|
|
|
|
|
|
if (self < 0)
|
|
|
|
{
|
|
|
|
unsigned int seat = (unsigned)(-self-1)%MAX_SPLITS;
|
|
|
|
self = cl.playerview[seat].playernum;
|
|
|
|
if (cl.playerview[seat].cam_state != CAM_FREECAM)
|
|
|
|
self = cl.playerview[seat].cam_spec_track;
|
|
|
|
}
|
|
|
|
if (self < 0)
|
|
|
|
return 0;
|
|
|
|
|
2016-08-25 00:12:14 +00:00
|
|
|
if (maxresults > countof(cl.players[self].weaponstats))
|
|
|
|
maxresults = countof(cl.players[self].weaponstats);
|
2015-10-27 15:20:15 +00:00
|
|
|
memcpy(result, cl.players[self].weaponstats, sizeof(*result) * maxresults);
|
|
|
|
return VM_LONG(maxresults);
|
|
|
|
}
|
|
|
|
#endif
|
2015-06-29 23:46:31 +00:00
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
|
|
|
char *name = VM_POINTER(arg[0]);
|
|
|
|
char *text = VM_POINTER(arg[1]);
|
|
|
|
console_t *con;
|
2013-06-23 02:17:02 +00:00
|
|
|
if (!name)
|
|
|
|
name = "";
|
2006-01-02 23:01:54 +00:00
|
|
|
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2013-07-13 12:14:32 +00:00
|
|
|
{
|
|
|
|
if (!*name)
|
|
|
|
{
|
|
|
|
Con_Printf("%s", text);
|
|
|
|
return 1;
|
|
|
|
}
|
2006-01-02 23:01:54 +00:00
|
|
|
return false;
|
2013-07-13 12:14:32 +00:00
|
|
|
}
|
2006-01-02 23:01:54 +00:00
|
|
|
|
2005-12-15 19:41:11 +00:00
|
|
|
con = Con_FindConsole(name);
|
|
|
|
if (!con)
|
|
|
|
{
|
2011-06-16 02:03:57 +00:00
|
|
|
con = Con_Create(name, 0);
|
2005-12-20 23:34:06 +00:00
|
|
|
Con_SetActive(con);
|
2005-12-15 19:41:11 +00:00
|
|
|
|
|
|
|
if (currentplug->conexecutecommand)
|
|
|
|
{
|
2013-06-29 21:08:09 +00:00
|
|
|
con->notif_x = 0;
|
|
|
|
con->notif_y = 8*4;
|
|
|
|
con->notif_w = vid.width;
|
|
|
|
con->notif_t = 8;
|
|
|
|
con->notif_l = 4;
|
|
|
|
con->flags |= CONF_NOTIFY;
|
2005-12-15 19:41:11 +00:00
|
|
|
con->userdata = currentplug;
|
|
|
|
con->linebuffered = Plug_SubConsoleCommand;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-10-05 20:04:11 +00:00
|
|
|
Con_PrintCon(con, text, con->parseflags);
|
2005-12-15 19:41:11 +00:00
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Con_RenameSub(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-15 19:41:11 +00:00
|
|
|
{
|
|
|
|
char *name = VM_POINTER(arg[0]);
|
|
|
|
console_t *con;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return false;
|
2005-12-15 19:41:11 +00:00
|
|
|
con = Con_FindConsole(name);
|
|
|
|
if (!con)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
Q_strncpyz(con->name, name, sizeof(con->name));
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Con_IsActive(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-20 23:34:06 +00:00
|
|
|
{
|
|
|
|
char *name = VM_POINTER(arg[0]);
|
|
|
|
console_t *con;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return false;
|
2005-12-20 23:34:06 +00:00
|
|
|
con = Con_FindConsole(name);
|
|
|
|
if (!con)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return Con_IsActive(con);
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Con_SetActive(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-20 23:34:06 +00:00
|
|
|
{
|
|
|
|
char *name = VM_POINTER(arg[0]);
|
|
|
|
console_t *con;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return false;
|
2005-12-20 23:34:06 +00:00
|
|
|
con = Con_FindConsole(name);
|
|
|
|
if (!con)
|
2011-06-16 02:03:57 +00:00
|
|
|
con = Con_Create(name, 0);
|
2005-12-15 19:41:11 +00:00
|
|
|
|
2005-12-20 23:34:06 +00:00
|
|
|
Con_SetActive(con);
|
|
|
|
return true;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Con_Destroy(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-20 23:34:06 +00:00
|
|
|
{
|
|
|
|
char *name = VM_POINTER(arg[0]);
|
|
|
|
console_t *con;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return false;
|
2005-12-20 23:34:06 +00:00
|
|
|
con = Con_FindConsole(name);
|
|
|
|
if (!con)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Con_Destroy(con);
|
|
|
|
return true;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Con_NameForNum(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2005-12-20 23:34:06 +00:00
|
|
|
{
|
|
|
|
char num = VM_LONG(arg[0]);
|
|
|
|
char *buffer = VM_POINTER(arg[1]);
|
|
|
|
int buffersize = VM_LONG(arg[2]);
|
2013-05-03 04:28:08 +00:00
|
|
|
if (VM_OOB(arg[1], buffersize) || buffersize < 1)
|
2005-12-20 23:34:06 +00:00
|
|
|
return false;
|
2010-02-06 01:25:04 +00:00
|
|
|
if (qrenderer == QR_NONE)
|
2006-01-02 23:01:54 +00:00
|
|
|
return false;
|
2005-12-20 23:34:06 +00:00
|
|
|
|
|
|
|
return Con_NameForNum(num, buffer, buffersize);
|
|
|
|
}
|
2005-12-15 19:41:11 +00:00
|
|
|
|
2015-04-14 23:12:17 +00:00
|
|
|
static qintptr_t VARGS Plug_Con_GetConsoleFloat(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
char *conname = VM_POINTER(arg[0]);
|
|
|
|
char *attrib = VM_POINTER(arg[1]);
|
|
|
|
int retbuf;
|
|
|
|
float ret;
|
|
|
|
console_t *con = Con_FindConsole(conname);
|
|
|
|
ret = -1;
|
|
|
|
|
|
|
|
if (!con)
|
|
|
|
ret = -1;
|
|
|
|
else if (!strcmp(attrib, "unseen"))
|
|
|
|
ret = con->unseentext;
|
|
|
|
else if (!strcmp(attrib, "markup"))
|
|
|
|
{
|
|
|
|
if (con->parseflags & PFS_NOMARKUP)
|
|
|
|
ret = 0;
|
|
|
|
else if (con->parseflags & PFS_KEEPMARKUP)
|
|
|
|
ret = 2;
|
|
|
|
else
|
|
|
|
ret = 1;
|
|
|
|
}
|
|
|
|
else if (!strcmp(attrib, "forceutf8"))
|
|
|
|
ret = (con->parseflags&PFS_FORCEUTF8)?true:false;
|
|
|
|
else if (!strcmp(attrib, "hidden"))
|
|
|
|
ret = (con->flags & CONF_HIDDEN)?true:false;
|
|
|
|
else if (!strcmp(attrib, "iswindow"))
|
|
|
|
ret = (con->flags & CONF_ISWINDOW)?true:false;
|
2016-07-12 00:40:13 +00:00
|
|
|
else if (!strcmp(attrib, "maxlines"))
|
|
|
|
ret = con->maxlines;
|
2015-04-14 23:12:17 +00:00
|
|
|
else if (!strcmp(attrib, "wnd_x"))
|
|
|
|
ret = con->wnd_x;
|
|
|
|
else if (!strcmp(attrib, "wnd_y"))
|
|
|
|
ret = con->wnd_y;
|
|
|
|
else if (!strcmp(attrib, "wnd_w"))
|
|
|
|
ret = con->wnd_w;
|
|
|
|
else if (!strcmp(attrib, "wnd_h"))
|
|
|
|
ret = con->wnd_h;
|
|
|
|
else if (!strcmp(attrib, "linecount"))
|
|
|
|
ret = con->linecount;
|
|
|
|
|
|
|
|
VM_FLOAT(retbuf) = ret;
|
|
|
|
return retbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static qintptr_t VARGS Plug_Con_SetConsoleFloat(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
char *conname = VM_POINTER(arg[0]);
|
|
|
|
char *attrib = VM_POINTER(arg[1]);
|
|
|
|
float val = VM_FLOAT(arg[2]);
|
|
|
|
console_t *con = Con_FindConsole(conname);
|
|
|
|
|
|
|
|
if (!con)
|
|
|
|
{
|
|
|
|
con = Con_Create(conname, 0);
|
|
|
|
if (!con)
|
|
|
|
return -1;
|
|
|
|
con->userdata = currentplug;
|
|
|
|
con->linebuffered = Plug_SubConsoleCommand;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcmp(attrib, "unseen"))
|
|
|
|
con->unseentext = !!val;
|
|
|
|
else if (!strcmp(attrib, "markup"))
|
|
|
|
{
|
|
|
|
int cur = val;
|
|
|
|
con->parseflags &= ~(PFS_NOMARKUP|PFS_KEEPMARKUP);
|
|
|
|
if (cur == 0)
|
|
|
|
con->parseflags |= PFS_NOMARKUP;
|
|
|
|
else if (cur == 2)
|
|
|
|
con->parseflags |= PFS_KEEPMARKUP;
|
|
|
|
}
|
|
|
|
else if (!strcmp(attrib, "forceutf8"))
|
|
|
|
con->parseflags = (con->parseflags & ~PFS_FORCEUTF8) | (val?PFS_FORCEUTF8:0);
|
|
|
|
else if (!strcmp(attrib, "hidden"))
|
|
|
|
con->flags = (con->flags & ~CONF_HIDDEN) | (val?CONF_HIDDEN:0);
|
|
|
|
else if (!strcmp(attrib, "iswindow"))
|
|
|
|
{
|
|
|
|
con->flags = (con->flags & ~CONF_ISWINDOW) | (val?CONF_ISWINDOW:0);
|
2016-07-12 00:40:13 +00:00
|
|
|
con->flags = (con->flags & ~CONF_NOTIFY) | (val>1?CONF_NOTIFY:0);
|
2015-04-14 23:12:17 +00:00
|
|
|
if (con_curwindow == con && !(con->flags & CONF_ISWINDOW))
|
|
|
|
con_curwindow = NULL;
|
|
|
|
else if (!con_curwindow && (con->flags & CONF_ISWINDOW))
|
|
|
|
con_curwindow = con;
|
|
|
|
}
|
2016-07-12 00:40:13 +00:00
|
|
|
else if (!strcmp(attrib, "maxlines"))
|
|
|
|
con->maxlines = val;
|
2015-04-14 23:12:17 +00:00
|
|
|
else if (!strcmp(attrib, "wnd_x"))
|
|
|
|
con->wnd_x = val;
|
|
|
|
else if (!strcmp(attrib, "wnd_y"))
|
|
|
|
con->wnd_y = val;
|
|
|
|
else if (!strcmp(attrib, "wnd_w"))
|
|
|
|
con->wnd_w = val;
|
|
|
|
else if (!strcmp(attrib, "wnd_h"))
|
|
|
|
con->wnd_h = val;
|
|
|
|
else if (!strcmp(attrib, "linebuffered"))
|
|
|
|
{
|
|
|
|
con->userdata = currentplug;
|
2016-07-12 00:40:13 +00:00
|
|
|
if (val == 2)
|
|
|
|
con->linebuffered = NULL;//Con_Navigate;
|
|
|
|
else if (val == 1)
|
|
|
|
con->linebuffered = Plug_SubConsoleCommand;
|
|
|
|
else
|
|
|
|
con->linebuffered = NULL;
|
2015-04-14 23:12:17 +00:00
|
|
|
}
|
|
|
|
else if (!strcmp(attrib, "linecount"))
|
|
|
|
{
|
|
|
|
if (val == 0)
|
2016-07-12 00:40:13 +00:00
|
|
|
{
|
|
|
|
int pfl = con->parseflags;
|
2015-04-14 23:12:17 +00:00
|
|
|
Con_ClearCon(con);
|
2016-07-12 00:40:13 +00:00
|
|
|
con->parseflags = pfl;
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static qintptr_t VARGS Plug_Con_GetConsoleString(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
const char *conname = VM_POINTER(arg[0]);
|
|
|
|
const char *attrib = VM_POINTER(arg[1]);
|
2015-08-22 02:59:01 +00:00
|
|
|
char *value = VM_POINTER(arg[2]);
|
2015-04-14 23:12:17 +00:00
|
|
|
size_t size = VM_LONG(arg[3]);
|
|
|
|
console_t *con = Con_FindConsole(conname);
|
|
|
|
|
|
|
|
if (VM_OOB(arg[2], arg[3]))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!con)
|
|
|
|
return 0;
|
|
|
|
else if (!strcmp(attrib, "footer"))
|
|
|
|
;
|
2015-08-22 02:59:01 +00:00
|
|
|
else if (!strcmp(attrib, "title"))
|
|
|
|
{
|
|
|
|
Q_strncpyz(value, con->title, size);
|
|
|
|
}
|
2016-07-12 00:40:13 +00:00
|
|
|
else if (!strcmp(attrib, "prompt"))
|
|
|
|
{
|
|
|
|
Q_strncpyz(value, con->prompt, size);
|
|
|
|
}
|
2015-08-22 02:59:01 +00:00
|
|
|
else if (!strcmp(attrib, "backimage"))
|
|
|
|
{
|
|
|
|
if (con->backshader)
|
|
|
|
Q_strncpyz(value, con->backshader->name, size);
|
|
|
|
else
|
|
|
|
Q_strncpyz(value, con->backimage, size);
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static qintptr_t VARGS Plug_Con_SetConsoleString(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
const char *conname = VM_POINTER(arg[0]);
|
|
|
|
const char *attrib = VM_POINTER(arg[1]);
|
|
|
|
const char *value = VM_POINTER(arg[2]);
|
|
|
|
console_t *con = Con_FindConsole(conname);
|
|
|
|
|
|
|
|
if (!con)
|
|
|
|
{
|
|
|
|
con = Con_Create(conname, 0);
|
|
|
|
if (!con)
|
|
|
|
return -1;
|
|
|
|
con->userdata = currentplug;
|
|
|
|
con->linebuffered = Plug_SubConsoleCommand;
|
|
|
|
}
|
|
|
|
if (!con)
|
|
|
|
return 0;
|
|
|
|
else if (!strcmp(attrib, "footer"))
|
|
|
|
Con_Footerf(con, false, "%s", value);
|
|
|
|
else if (!strcmp(attrib, "title"))
|
|
|
|
Q_strncpyz(con->title, value, sizeof(con->title));
|
2016-07-12 00:40:13 +00:00
|
|
|
else if (!strcmp(attrib, "prompt"))
|
|
|
|
Q_strncpyz(con->prompt, value, sizeof(con->prompt));
|
2015-08-22 02:59:01 +00:00
|
|
|
else if (!strcmp(attrib, "backimage"))
|
|
|
|
{
|
|
|
|
Q_strncpyz(con->backimage, value, sizeof(con->backimage));
|
|
|
|
if (con->backshader)
|
|
|
|
R_UnloadShader(con->backshader);
|
|
|
|
}
|
|
|
|
else if (!strcmp(attrib, "backvideomap"))
|
|
|
|
{
|
|
|
|
Q_strncpyz(con->backimage, "", sizeof(con->backimage));
|
|
|
|
if (con->backshader)
|
|
|
|
R_UnloadShader(con->backshader);
|
2016-07-12 00:40:13 +00:00
|
|
|
if (qrenderer != QR_NONE)
|
|
|
|
con->backshader = R_RegisterCustom(va("consolevid_%s", con->name), SUF_NONE, Shader_DefaultCinematic, value);
|
|
|
|
else
|
|
|
|
con->backshader = NULL;
|
2015-08-22 02:59:01 +00:00
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static qintptr_t VARGS Plug_S_RawAudio(void *offset, quintptr_t mask, const qintptr_t *arg)
|
2013-05-03 04:28:08 +00:00
|
|
|
{
|
|
|
|
int sourceid = VM_LONG(arg[0]);
|
|
|
|
qbyte *data = VM_POINTER(arg[1]);
|
|
|
|
int speed = VM_LONG(arg[2]);
|
|
|
|
int samples = VM_LONG(arg[3]);
|
|
|
|
int channels = VM_LONG(arg[4]);
|
|
|
|
int width = VM_LONG(arg[5]);
|
2013-05-31 01:20:41 +00:00
|
|
|
int volume = VM_FLOAT(arg[6]);
|
2013-05-03 04:28:08 +00:00
|
|
|
|
|
|
|
int datasize = samples * channels * width;
|
|
|
|
|
|
|
|
if (VM_OOB(arg[1], datasize) || datasize < 1)
|
|
|
|
return false;
|
|
|
|
|
2013-05-31 01:20:41 +00:00
|
|
|
S_RawAudio(sourceid, data, speed, samples, channels, width, volume);
|
2013-05-03 04:28:08 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2005-12-15 19:41:11 +00:00
|
|
|
|
2014-03-30 08:55:06 +00:00
|
|
|
#include "com_mesh.h"
|
2014-05-16 01:34:58 +00:00
|
|
|
|
|
|
|
#ifdef SKELETALMODELS
|
2015-04-14 23:12:17 +00:00
|
|
|
static int QDECL Plug_RegisterModelFormatText(const char *formatname, char *magictext, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize))
|
2014-05-16 01:34:58 +00:00
|
|
|
{
|
|
|
|
void *module = currentplug;
|
|
|
|
return Mod_RegisterModelFormatText(module, formatname, magictext, load);
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static int QDECL Plug_RegisterModelFormatMagic(const char *formatname, unsigned int magic, qboolean (QDECL *load) (struct model_s *mod, void *buffer, size_t fsize))
|
2014-05-16 01:34:58 +00:00
|
|
|
{
|
|
|
|
void *module = currentplug;
|
|
|
|
return Mod_RegisterModelFormatMagic(module, formatname, magic, load);
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static void QDECL Plug_UnRegisterModelFormat(int idx)
|
2014-05-16 01:34:58 +00:00
|
|
|
{
|
|
|
|
void *module = currentplug;
|
|
|
|
Mod_UnRegisterModelFormat(module, idx);
|
|
|
|
}
|
2015-04-14 23:12:17 +00:00
|
|
|
static void QDECL Plug_UnRegisterAllModelFormats(void)
|
2014-05-16 01:34:58 +00:00
|
|
|
{
|
|
|
|
void *module = currentplug;
|
|
|
|
Mod_UnRegisterAllModelFormats(module);
|
|
|
|
}
|
|
|
|
#endif
|
2014-03-30 08:55:06 +00:00
|
|
|
qintptr_t VARGS Plug_Mod_GetPluginModelFuncs(void *offset, quintptr_t mask, const qintptr_t *arg)
|
|
|
|
{
|
|
|
|
#ifdef SKELETALMODELS
|
|
|
|
static modplugfuncs_t funcs =
|
|
|
|
{
|
2014-05-16 01:34:58 +00:00
|
|
|
MODPLUGFUNCS_VERSION,
|
|
|
|
|
|
|
|
Plug_RegisterModelFormatText,
|
|
|
|
Plug_RegisterModelFormatMagic,
|
|
|
|
Plug_UnRegisterModelFormat,
|
|
|
|
Plug_UnRegisterAllModelFormats,
|
2014-03-30 08:55:06 +00:00
|
|
|
ZG_Malloc,
|
|
|
|
|
|
|
|
R_ConcatTransforms,
|
|
|
|
Matrix3x4_Invert_Simple,
|
2015-02-02 08:01:53 +00:00
|
|
|
VectorAngles,
|
|
|
|
AngleVectors,
|
2014-03-30 08:55:06 +00:00
|
|
|
GenMatrixPosQuat4Scale,
|
2015-02-02 08:01:53 +00:00
|
|
|
COM_StripExtension,
|
2016-07-12 00:40:13 +00:00
|
|
|
Alias_ForceConvertBoneData,
|
|
|
|
|
|
|
|
Terr_GetTerrainFuncs
|
2014-03-30 08:55:06 +00:00
|
|
|
};
|
2014-05-16 01:34:58 +00:00
|
|
|
if (VM_LONG(arg[0]) >= sizeof(funcs))
|
2014-03-30 08:55:06 +00:00
|
|
|
return (qintptr_t)&funcs;
|
|
|
|
else
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-12-15 19:41:11 +00:00
|
|
|
void Plug_Client_Init(void)
|
|
|
|
{
|
2006-01-02 23:01:54 +00:00
|
|
|
Plug_RegisterBuiltin("CL_GetStats", Plug_CL_GetStats, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Menu_Control", Plug_Menu_Control, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Key_GetKeyCode", Plug_Key_GetKeyCode, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
|
2013-11-21 23:02:28 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_LoadImageData", Plug_Draw_LoadImageData, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Draw_LoadImageShader", Plug_Draw_LoadImageShader, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Draw_LoadImage", Plug_Draw_LoadImagePic, PLUG_BIF_NEEDSRENDERER);
|
2006-01-02 23:01:54 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_Image", Plug_Draw_Image, PLUG_BIF_NEEDSRENDERER);
|
2015-04-21 04:12:00 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_ImageSize", Plug_Draw_ImageSize, PLUG_BIF_NEEDSRENDERER);
|
2006-01-02 23:01:54 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_Character", Plug_Draw_Character, PLUG_BIF_NEEDSRENDERER);
|
2015-06-17 13:05:20 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_CharacterH", Plug_Draw_CharacterH, PLUG_BIF_NEEDSRENDERER);
|
2013-11-21 23:02:28 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_String", Plug_Draw_String, PLUG_BIF_NEEDSRENDERER);
|
2015-06-17 13:05:20 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_StringH", Plug_Draw_StringH, PLUG_BIF_NEEDSRENDERER);
|
2015-10-27 15:20:15 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_StringWidth", Plug_Draw_StringWidth, PLUG_BIF_NEEDSRENDERER);
|
2006-01-02 23:01:54 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_Fill", Plug_Draw_Fill, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Draw_Line", Plug_Draw_Line, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Draw_Colourp", Plug_Draw_ColourP, PLUG_BIF_NEEDSRENDERER);
|
2015-06-17 13:05:20 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_Colourpa", Plug_Draw_ColourPA, PLUG_BIF_NEEDSRENDERER);
|
2006-01-02 23:01:54 +00:00
|
|
|
Plug_RegisterBuiltin("Draw_Colour3f", Plug_Draw_Colour3f, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Draw_Colour4f", Plug_Draw_Colour4f, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
|
|
|
|
Plug_RegisterBuiltin("Con_SubPrint", Plug_Con_SubPrint, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Con_RenameSub", Plug_Con_RenameSub, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Con_IsActive", Plug_Con_IsActive, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Con_SetActive", Plug_Con_SetActive, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Con_Destroy", Plug_Con_Destroy, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Con_NameForNum", Plug_Con_NameForNum, PLUG_BIF_NEEDSRENDERER);
|
2015-04-14 23:12:17 +00:00
|
|
|
Plug_RegisterBuiltin("Con_GetConsoleFloat", Plug_Con_GetConsoleFloat, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Con_SetConsoleFloat", Plug_Con_SetConsoleFloat, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Con_GetConsoleString", Plug_Con_GetConsoleString, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("Con_SetConsoleString", Plug_Con_SetConsoleString, PLUG_BIF_NEEDSRENDERER);
|
2006-01-02 23:01:54 +00:00
|
|
|
|
|
|
|
Plug_RegisterBuiltin("LocalSound", Plug_LocalSound, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("SCR_CenterPrint", Plug_SCR_CenterPrint, PLUG_BIF_NEEDSRENDERER);
|
2006-01-21 00:06:49 +00:00
|
|
|
|
2015-09-01 04:45:15 +00:00
|
|
|
#ifdef QUAKEHUD
|
2015-06-29 23:46:31 +00:00
|
|
|
Plug_RegisterBuiltin("GetTeamInfo", Plug_GetTeamInfo, PLUG_BIF_NEEDSRENDERER);
|
2015-10-27 15:20:15 +00:00
|
|
|
Plug_RegisterBuiltin("GetWeaponStats", Plug_GetWeaponStats, PLUG_BIF_NEEDSRENDERER);
|
2015-09-01 04:45:15 +00:00
|
|
|
#endif
|
2007-10-05 10:46:26 +00:00
|
|
|
Plug_RegisterBuiltin("GetLocationName", Plug_GetLocationName, PLUG_BIF_NEEDSRENDERER);
|
2006-01-21 00:06:49 +00:00
|
|
|
Plug_RegisterBuiltin("GetPlayerInfo", Plug_GetPlayerInfo, PLUG_BIF_NEEDSRENDERER);
|
2007-02-23 00:21:33 +00:00
|
|
|
Plug_RegisterBuiltin("LocalPlayerNumber", Plug_LocalPlayerNumber, PLUG_BIF_NEEDSRENDERER);
|
2015-04-21 04:12:00 +00:00
|
|
|
Plug_RegisterBuiltin("GetLocalPlayerNumbers", Plug_GetLocalPlayerNumbers, PLUG_BIF_NEEDSRENDERER);
|
2007-02-23 00:21:33 +00:00
|
|
|
Plug_RegisterBuiltin("GetServerInfo", Plug_GetServerInfo, PLUG_BIF_NEEDSRENDERER);
|
|
|
|
Plug_RegisterBuiltin("SetUserInfo", Plug_SetUserInfo, PLUG_BIF_NEEDSRENDERER);
|
2015-06-12 14:44:50 +00:00
|
|
|
Plug_RegisterBuiltin("GetNetworkInfo", Plug_GetNetworkInfo, PLUG_BIF_NEEDSRENDERER);
|
2015-11-18 07:37:39 +00:00
|
|
|
Plug_RegisterBuiltin("GetTrackerOwnFrags", Plug_GetTrackerOwnFrags, PLUG_BIF_NEEDSRENDERER);
|
2013-05-03 04:28:08 +00:00
|
|
|
|
|
|
|
Plug_RegisterBuiltin("S_RawAudio", Plug_S_RawAudio, PLUG_BIF_NEEDSRENDERER);
|
2014-03-30 08:55:06 +00:00
|
|
|
|
|
|
|
Plug_RegisterBuiltin("Mod_GetPluginModelFuncs", Plug_Mod_GetPluginModelFuncs, PLUG_BIF_NEEDSRENDERER|PLUG_BIF_DLLONLY);
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Plug_Client_Close(plugin_t *plug)
|
|
|
|
{
|
|
|
|
Plug_FreePlugImages(plug);
|
|
|
|
|
|
|
|
|
|
|
|
if (menuplug == plug)
|
|
|
|
{
|
|
|
|
menuplug = NULL;
|
2015-07-14 14:47:00 +00:00
|
|
|
Key_Dest_Remove(kdm_emenu);
|
2005-12-15 19:41:11 +00:00
|
|
|
}
|
|
|
|
if (protocolclientplugin == plug)
|
|
|
|
{
|
|
|
|
protocolclientplugin = NULL;
|
|
|
|
if (cls.protocol == CP_PLUGIN)
|
|
|
|
cls.protocol = CP_UNKNOWN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-31 04:21:08 +00:00
|
|
|
void Plug_Client_Shutdown(void)
|
|
|
|
{
|
|
|
|
BZ_Free(pluginimagearray);
|
|
|
|
pluginimagearray = NULL;
|
|
|
|
pluginimagearraylen = 0;
|
|
|
|
}
|
2005-12-15 19:41:11 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|