Add ReadInt+WriteInt qc builtins in csqc+ssqc respectively, add some extra docs for some other builtins.

Try to mimic dp's console background cvars, so we don't need to add so many files to run xonotic properly.
Don't bother trying to recognised xonotic automatically for now, it won't work well without extra fmf stuff anyway.
Try to fix up rotated 'wrbrushes' stuff. Untested.


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5592 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2019-12-16 17:36:00 +00:00
parent eddf5dc6d1
commit 630678f6e3
8 changed files with 167 additions and 37 deletions

View File

@ -598,7 +598,7 @@ ifeq ($(FTE_TARGET),vc)
GNUC_FUNCS=
else
WARNINGFLAGS=-Wall -Wno-pointer-sign -Wno-unknown-pragmas -Wno-format-zero-length -Wno-strict-aliasing #-Wcast-align
GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp
# GNUC_FUNCS= -Dstrnicmp=strncasecmp -Dstricmp=strcasecmp
endif
SDL_INCLUDES=

View File

@ -5176,7 +5176,7 @@ void Media_Init(void)
#endif
Cmd_AddCommandD("capture", Media_RecordFilm_f, "Captures realtime action to a named video file. Check the capture* cvars to control driver/codecs/rates.");
Cmd_AddCommandD("capturedemo", Media_RecordDemo_f, "Capture a nemed demo to a named video file. Demo capturing can be performed offscreen, allowing arbitrary video sizes, or smooth captures on underpowered hardware.");
Cmd_AddCommandD("capturedemo", Media_RecordDemo_f, "capuuredemo foo.dem foo.avi - Captures a named demo to a named video file.\nDemo capturing is performed offscreen when possible, allowing arbitrary video sizes or smooth captures on underpowered hardware.");
Cmd_AddCommandD("capturestop", Media_StopRecordFilm_f, "Aborts the current video capture.");
Cmd_AddCommandD("capturepause", Media_CapturePause_f, "Pauses the video capture, allowing you to avoid capturing uninteresting parts. This is a toggle, so reuse the same command to resume capturing again.");

View File

@ -3249,6 +3249,16 @@ static void QCBUILTIN PF_ReadFloat(pubprogfuncs_t *prinst, struct globalvars_s *
}
G_FLOAT(OFS_RETURN) = MSG_ReadFloat();
}
static void QCBUILTIN PF_ReadInt(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (!csqc_mayread)
{
CSQC_Abort("PF_ReadInt is not valid at this time");
G_INT(OFS_RETURN) = -1;
return;
}
G_INT(OFS_RETURN) = MSG_ReadLong();
}
static void QCBUILTIN PF_ReadString(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -6698,6 +6708,7 @@ static struct {
{"readangle", PF_ReadAngle, 365}, // #365 float() readangle (EXT_CSQC)
{"readstring", PF_ReadString, 366}, // #366 string() readstring (EXT_CSQC)
{"readfloat", PF_ReadFloat, 367}, // #367 string() readfloat (EXT_CSQC)
{"readint", PF_ReadInt, 0}, // #0 string() readint
{"readentitynum", PF_ReadEntityNum, 368}, // #368 float() readentitynum (EXT_CSQC)
// {"readserverentitystate", PF_ReadServerEntityState, 369}, // #369 void(float flags, float simtime) readserverentitystate (EXT_CSQC_1)

View File

@ -984,6 +984,37 @@ void QDECL R2D_Conback_Callback(struct cvar_s *var, char *oldvalue)
if (*var->string)
conback = R_RegisterPic(var->string, NULL);
#ifdef HAVE_LEGACY
else if (Cvar_FindVar("scr_conalphafactor"))
{ //dp bullshit
conback = R_RegisterShader("gfx/conback", SUF_2D,
"{\n"
"nomipmaps\n"
"{\n"
"map gfx/conback\n"
"rgbgen const $scr_conbrightness\n"
"alphagen const $scr_conalphafactor\n"
"tcmod scroll $scr_conscroll_x $scr_conscroll_y\n"
"blendfunc blend\n"
"}\n"
"{\n"
"map gfx/conback2\n"
"rgbgen const $scr_conbrightness\n"
"alphagen const $scr_conalpha2factor\n"
"tcmod scroll $scr_conscroll2_x $scr_conscroll2_y\n"
"blendfunc blend\n"
"}\n"
"{\n"
"map gfx/conback3\n"
"rgbgen const $scr_conbrightness\n"
"alphagen const $scr_conalpha3factor\n"
"tcmod scroll $scr_conscroll3_x $scr_conscroll3_y\n"
"blendfunc blend\n"
"}\n"
"}\n");
}
#endif
if (!R_GetShaderSizes(conback, NULL, NULL, true))
{
conback = R_RegisterCustom("console", SUF_2D, NULL, NULL); //quake3

View File

@ -327,7 +327,7 @@ static void S_Info(void);
static void S_Shutdown_f(void);
*/
static cvar_t s_al_disable = CVARD("s_al_disable", "0", "When set, prevents initialisation of openal. Audio ouput can then fall back to platfrm-specific output which doesn't have any of the miscilaneous openal limitations or bugs.");
static cvar_t s_al_disable = CVARD("s_al_disable", "0", "0: OpenAL works (generally as the highest priority).\n1: OpenAL will be used only when a specific device is selected.\n2: Don't allow ANY use of OpenAl.\nWith OpenAL disabled, audio ouput will fall back to platform-specific output, avoiding miscilaneous third-party openal limitation bugs.");
static cvar_t s_al_debug = CVARD("s_al_debug", "0", "Enables periodic checks for OpenAL errors.");
static cvar_t s_al_use_reverb = CVARD("s_al_use_reverb", "1", "Controls whether reverb effects will be used. Set to 0 to block them. Reverb requires gamecode to configure the reverb properties, other than underwater.");
//static cvar_t s_al_max_distance = CVARFC("s_al_max_distance", "1000",0,OnChangeALSettings);
@ -1086,7 +1086,7 @@ static qboolean OpenAL_InitLibrary(void)
#endif
#ifdef OPENAL_STATIC
if (s_al_disable.ival)
if (s_al_disable.ival > 1)
return false;
return true;
#else
@ -1131,7 +1131,7 @@ static qboolean OpenAL_InitLibrary(void)
{NULL}
};
if (s_al_disable.ival)
if (s_al_disable.ival > 1)
return false;
if (COM_CheckParm("-noopenal"))
return false;
@ -1159,15 +1159,22 @@ static qboolean OpenAL_Init(soundcardinfo_t *sc, const char *devname)
if (!OpenAL_InitLibrary())
{
if (devname)
Con_Printf(SDRVNAME" library is not installed\n");
else
Con_DPrintf(SDRVNAME" library is not installed\n");
if (!s_al_disable.ival)
{
if (devname)
Con_Printf(SDRVNAME" library is not installed\n");
else
Con_DPrintf(SDRVNAME" library is not installed\n");
}
return false;
}
if (!devname || !*devname)
{
if (s_al_disable.ival)
return false; //no default device
devname = palcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
}
Q_snprintfz(sc->name, sizeof(sc->name), "%s", devname);
Con_Printf("Initiating "SDRVNAME": %s.\n", devname);
@ -1608,7 +1615,11 @@ static void *QDECL OPENAL_Capture_Init (int samplerate, const char *device)
return NULL; //enumerate nothing if al is disabled
if (!device || !*device)
{
if (s_al_disable.ival)
return NULL; //no default device
device = palcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER);
}
return palcCaptureOpenDevice(device, samplerate, AL_FORMAT_MONO16, 0.5*samplerate);
}

View File

@ -606,11 +606,11 @@ static qboolean FS_Manifest_ParseTokens(ftemanifest_t *man)
Z_Free(man->defaultexec);
man->defaultexec = Z_StrDup(Cmd_Argv(1));
}
else if (!Q_strcasecmp(cmd, "-bind") || !Q_strcasecmp(cmd, "-set") || !Q_strcasecmp(cmd, "-seta") || !Q_strcasecmp(cmd, "-alias"))
else if (!Q_strcasecmp(cmd, "-bind") || !Q_strcasecmp(cmd, "-set") || !Q_strcasecmp(cmd, "-seta") || !Q_strcasecmp(cmd, "-alias") || !Q_strncasecmp(cmd, "-", 1))
{
Z_StrCat(&man->defaultexec, va("%s %s\n", Cmd_Argv(0)+1, Cmd_Args()));
}
else if (!Q_strcasecmp(cmd, "bind") || !Q_strcasecmp(cmd, "set") || !Q_strcasecmp(cmd, "seta") || !Q_strcasecmp(cmd, "alias"))
else if (!Q_strcasecmp(cmd, "bind") || !Q_strcasecmp(cmd, "set") || !Q_strcasecmp(cmd, "seta") || !Q_strcasecmp(cmd, "alias") || !Q_strncasecmp(cmd, "+", 1))
{
Z_StrCat(&man->defaultoverrides, va("%s %s\n", Cmd_Argv(0), Cmd_Args()));
}
@ -3354,9 +3354,9 @@ void COM_Gamedir (const char *dir, const struct gamepacks *packagespaths)
/*set some stuff so our regular qw client appears more like hexen2. sv_mintic is required to 'fix' the ravenstaff so that its projectiles don't impact upon each other*/
#define HEX2CFG "set com_parseutf8 -1\nset gl_font gfx/hexen2\nset in_builtinkeymap 0\nset_calc cl_playerclass int (random * 5) + 1\nset cl_forwardspeed 200\nset cl_backspeed 200\ncl_sidespeed 225\nset sv_maxspeed 640\ncl_run 0\nset watervis 1\nset r_lavaalpha 1\nset r_lavastyle -2\nset r_wateralpha 0.5\nset sv_pupglow 1\ngl_shaftlight 0.5\nsv_mintic 0.015\nset mod_warnmodels 0\nset cl_model_bobbing 1\nsv_sound_watersplash \"misc/hith2o.wav\"\nsv_sound_land \"fx/thngland.wav\"\nset sv_walkpitch 0\n"
/*yay q2!*/
#define Q2CFG "set v_gammainverted 1\nset com_parseutf8 0\ncom_nogamedirnativecode 0\nset sv_bigcoords 0\n"
#define Q2CFG "set v_gammainverted 1\nset com_parseutf8 0\ncom_nogamedirnativecode 0\nset sv_bigcoords 0\nsv_port "STRINGIFY(PORT_Q2SERVER)"\n"
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
#define Q3CFG "set v_gammainverted 0\nset com_parseutf8 0\ngl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_nogamedirnativecode 0\n"
#define Q3CFG "set v_gammainverted 0\nset com_parseutf8 0\ngl_overbright 2\nseta model sarge\nseta headmodel sarge\nseta handicap 100\ncom_nogamedirnativecode 0\nsv_port "STRINGIFY(PORT_Q3SERVER)"\n"
//#define RMQCFG "sv_bigcoords 1\n"
#ifdef HAVE_SSL
@ -3433,8 +3433,8 @@ const gamemode_info_t gamemode_info[] = {
{"-nehahra", "nehahra", "FTE-Quake", {"id1/pak0.pak","id1/quake.rc"},NEHCFG, {"id1", "qw", "nehahra", "*fte"}, "Quake: Seal Of Nehahra", UPDATEURL(Q1)},
//various quake-based standalone mods.
{"-nexuiz", "nexuiz", "Nexuiz", {"nexuiz.exe"}, NEXCFG, {"data", "*ftedata"},"Nexuiz"},
{"-xonotic", "xonotic", "Xonotic", {"data/xonotic-data.pk3dir",
"data/xonotic-*data*.pk3"}, XONCFG, {"data", "*ftedata"},"Xonotic", UPDATEURL(Xonotic)},
// {"-xonotic", "xonotic", "Xonotic", {"data/xonotic-data.pk3dir",
// "data/xonotic-*data*.pk3"}, XONCFG, {"data", "*ftedata"},"Xonotic", UPDATEURL(Xonotic)},
// {"-spark", "spark", "Spark", {"base/src/progs.src",
// "base/qwprogs.dat",
// "base/pak0.pak"}, DMFCFG, {"base", }, "Spark"},

View File

@ -1574,8 +1574,21 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, const framestate_t *frame
traceinfo.trace.allsolid = false;
VectorCopy(mins, traceinfo.mins);
VectorCopy(maxs, traceinfo.maxs);
VectorCopy(start, traceinfo.start);
VectorCopy(end, traceinfo.end);
if (axis)
{
traceinfo.start[0] = DotProduct(start, axis[0]);
traceinfo.start[1] = DotProduct(start, axis[1]);
traceinfo.start[2] = DotProduct(start, axis[2]);
traceinfo.end[0] = DotProduct(end, axis[0]);
traceinfo.end[1] = DotProduct(end, axis[1]);
traceinfo.end[2] = DotProduct(end, axis[2]);
}
else
{
VectorCopy(start, traceinfo.start);
VectorCopy(end, traceinfo.end);
}
traceinfo.capsule = capsule;
if (traceinfo.capsule)
@ -1603,7 +1616,7 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, const framestate_t *frame
traceinfo.maxs[2] = traceinfo.radius;
*/
traceinfo.solidcontents = hitcontentsmask;
Q1BSP_RecursiveBrushCheck(&traceinfo, model->rootnode, 0, 1, start, end);
Q1BSP_RecursiveBrushCheck(&traceinfo, model->rootnode, 0, 1, traceinfo.start, traceinfo.end);
memcpy(trace, &traceinfo.trace, sizeof(trace_t));
if (trace->fraction < 1)
{
@ -1613,6 +1626,17 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, const framestate_t *frame
if (f < 0)
f = 0;
trace->fraction = f;
if (axis)
{
vec3_t iaxis[3];
vec3_t norm;
Matrix3x3_RM_Invert_Simple((const void *)axis, iaxis);
VectorCopy(trace->plane.normal, norm);
trace->plane.normal[0] = DotProduct(norm, iaxis[0]);
trace->plane.normal[1] = DotProduct(norm, iaxis[1]);
trace->plane.normal[2] = DotProduct(norm, iaxis[2]);
}
}
VectorInterpolate(start, trace->fraction, end, trace->endpos);
return trace->fraction != 1;

View File

@ -5304,6 +5304,56 @@ void QCBUILTIN PF_WriteLong (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
}
}
void QCBUILTIN PF_WriteInt (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int dest = G_FLOAT(OFS_PARM0);
if (dest == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteLong(&csqcmsgbuffer, G_INT(OFS_PARM1));
return;
}
if (pr_nonetaccess.value)
return;
#ifdef SERVER_DEMO_PLAYBACK
if (sv.demofile)
return;
#endif
#ifdef NETPREPARSE
if (dpcompat_nopreparse.ival)
;
else if (progstype != PROG_QW)
{
NPP_NQWriteLong(dest, G_INT(OFS_PARM1));
return;
}
#ifdef NQPROT
else
{
NPP_QWWriteLong(dest, G_INT(OFS_PARM1));
return;
}
#endif
#endif
if (dest == MSG_ONE)
{
client_t *cl = Write_GetClient();
if (!cl)
return;
ClientReliableCheckBlock(cl, 4);
ClientReliableWrite_Long(cl, G_INT(OFS_PARM1));
}
else
{
if (progstype != PROG_QW)
MSG_WriteLong (NQWriteDest(dest), G_INT(OFS_PARM1));
else
MSG_WriteLong (QWWriteDest(dest), G_INT(OFS_PARM1));
}
}
void QCBUILTIN PF_WriteAngle (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
int dest = G_FLOAT(OFS_PARM0);
@ -8875,7 +8925,7 @@ static void QCBUILTIN PF_Fork(pubprogfuncs_t *prinst, struct globalvars_s *pr_gl
PR_CreateThread(prinst, 1, sv.time + sleeptime, false);
PRSV_RunThreads();
// PRSV_RunThreads();
G_FLOAT(OFS_RETURN) = 0;
}
@ -10477,13 +10527,13 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"vectoangles", PF_vectoangles, 51, 51, 51, 0, D("vector(vector fwd, optional vector up)", "Returns the angles (+x=UP) required to orient an entity to look in the given direction. The 'up' argument is required if you wish to set a roll angle, otherwise it will be limited to just monster-style turning.")},
{"WriteByte", PF_WriteByte, 52, 52, 52, 0, D("void(float to, float val)", "Writes a single byte into a network message buffer. Typically you will find a more correct alternative to writing arbitary data. 'to' should be one of the MSG_* constants. MSG_ONE must have msg_entity set first.")}, //52
{"WriteChar", PF_WriteChar, 53, 53, 53, 0, "void(float to, float val)"}, //53
{"WriteShort", PF_WriteShort, 54, 54, 54, 0, "void(float to, float val)"}, //54
{"WriteLong", PF_WriteLong, 55, 55, 55, 0, "void(float to, float val)"}, //55
{"WriteCoord", PF_WriteCoord, 56, 56, 56, 0, "void(float to, float val)"}, //56
{"WriteAngle", PF_WriteAngle, 57, 57, 57, 0, "void(float to, float val)"}, //57
{"WriteString", PF_WriteString, 58, 58, 58, 0, "void(float to, string val)"}, //58
{"WriteEntity", PF_WriteEntity, 59, 59, 59, 0, "void(float to, entity val)"}, //59
{"WriteChar", PF_WriteChar, 53, 53, 53, 0, D("void(float to, float val)", "Writes a signed value between -128 and 127.")}, //53
{"WriteShort", PF_WriteShort, 54, 54, 54, 0, D("void(float to, float val)", "Writes a signed value between -32768 and 32767. As an exception, values up to 65535 will not trigger warnings (but readshort will read the result as negative!)")}, //54
{"WriteLong", PF_WriteLong, 55, 55, 55, 0, D("void(float to, float val)", "Writes a signed 32bit integer. Note that the input argument being of float type limits the resulting integer to a mere 24 consecutive bits of validity. Use WriteInt if you want to write an entire 32bit int without data loss.")}, //55
{"WriteCoord", PF_WriteCoord, 56, 56, 56, 0, D("void(float to, float val)", "Writes a single value suitable for a map coordinate axis. The precision is not strictly specified but is assumed to be of at least 13.3 fixed-point precision (ie: +/-4k with 1/8th precision).")}, //56
{"WriteAngle", PF_WriteAngle, 57, 57, 57, 0, D("void(float to, float val)", "Writes a single value suitable for an angle axis. The precision is not strictly specified but is assumed to be 8bit, giving 256 notches instead of the assumed 360 range passed in.")}, //57
{"WriteString", PF_WriteString, 58, 58, 58, 0, D("void(float to, string val)", "Writes a variable-length null terminated string. There are length limits. The codepage is not translated, so be sure that client+server agree on whether utf-8 is being used or not (or just stick to ascii+markup).")}, //58
{"WriteEntity", PF_WriteEntity, 59, 59, 59, 0, D("void(float to, entity val)", "Writes the index of the specified entity (the network data size is not specified). This can be read clientside using the readentitynum builtin, with caveats.")}, //59
#if !defined(QUAKETC) && defined(NETPREPARSE)
{"swritebyte", PF_qtSingle_WriteByte, 0, 0, 0, 0, D("void(float val)", "A legacy of qtest - like WriteByte, except writes explicitly to the MSG_ONE target."), true}, //52
@ -10871,7 +10921,8 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
#endif
{"touchtriggers", PF_touchtriggers, 0, 0, 0, 279, D("void(optional entity ent, optional vector neworigin)", "Triggers a touch events between self and every SOLID_TRIGGER entity that it is in contact with. This should typically just be the triggers touch functions. Also optionally updates the origin of the moved entity.")},//
{"WriteFloat", PF_WriteFloat, 0, 0, 0, 280, "void(float buf, float fl)"},//
{"WriteFloat", PF_WriteFloat, 0, 0, 0, 280, D("void(float buf, float fl)", "Writes a full 32bit float without any data conversions at all, for full precision.")},//
{"WriteInt", PF_WriteInt, 0, 0, 0, 0, D("void(float buf, int fl)", "Equivelent to WriteLong, but doesn't truncate to a float first before converting back to an int.")},//
{"skel_ragupdate", PF_skel_ragedit, 0, 0, 0, 281, D("float(entity skelent, string dollcmd, float animskel)", "Updates the skeletal object attached to the entity according to its origin and other properties.\nif animskel is non-zero, the ragdoll will animate towards the bone state in the animskel skeletal object, otherwise they will pick up the model's base pose which may not give nice results.\nIf dollcmd is not set, the ragdoll will update (this should be done each frame).\nIf the doll is updated without having a valid doll, the model's default .doll will be instanciated.\ncommands:\n doll foo.doll : sets up the entity to use the named doll file\n dollstring TEXT : uses the doll file directly embedded within qc, with that extra prefix.\n cleardoll : uninstanciates the doll without destroying the skeletal object.\n animate 0.5 : specifies the strength of the ragdoll as a whole \n animatebody somebody 0.5 : specifies the strength of the ragdoll on a specific body (0 will disable ragdoll animations on that body).\n enablejoint somejoint 1 : enables (or disables) a joint. Disabling joints will allow the doll to shatter.")}, // (FTE_CSQC_RAGDOLL)
{"skel_mmap", PF_skel_mmap, 0, 0, 0, 282, D("float*(float skel)", "Map the bones in VM memory. They can then be accessed via pointers. Each bone is 12 floats, the four vectors interleaved (sadly).")},// (FTE_QC_RAGDOLL)
{"skel_set_bone_world",PF_skel_set_bone_world,0,0, 0, 283, D("void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up)", "Sets the world position of a bone within the given entity's attached skeletal object. The world position is dependant upon the owning entity's position. If no orientation argument is specified, v_forward+v_right+v_up are used for the orientation instead. If 1 is specified, it is understood as angles. If 3 are specified, they are the forawrd/right/up vectors to use.")},
@ -10996,20 +11047,22 @@ static BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"setserverkey", PF_setserverkey,0, 0, 0, 0, D("void(string key, void *ptr, optional int size)", "Changes the server's serverinfo.")},//
{"getentitytoken", PF_Fixme, 0, 0, 0, 355, D("string(optional string resetstring)", "Grab the next token in the map's entity lump.\nIf resetstring is not specified, the next token will be returned with no other sideeffects.\nIf empty, will reset from the map before returning the first token, probably {.\nIf not empty, will tokenize from that string instead.\nAlways returns tempstrings.")},//;
{"findfont", PF_Fixme, 0, 0, 0, 356, D("float(string s)", "Looks up a named font slot. Matches the actual font name as a last resort.")},//;
{"loadfont", PF_Fixme, 0, 0, 0, 357, D("float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset)", "too convoluted for me to even try to explain correct usage. Try drawfont = loadfont(\"\", \"cour\", \"16\", -1, 0, 0); to switch to the courier font (optimised for 16 virtual pixels high), if you have the freetype2 library in windows..")},
{"loadfont", PF_Fixme, 0, 0, 0, 357, D("float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset)", "too convoluted for me to even try to explain correct usage. Try drawfont = loadfont(\"\", \"cour\", \"16\", -1, 0, 0); to switch to the courier font (optimised for 16 virtual pixels high) ('cour' requires mscorefonts installed in linux). Additionally you can add \"outline=1\" as an extra token in the sizes string, to have more readable outlined fonts.")},
//358
{"sendevent", PF_Fixme, 0, 0, 0, 359, D("void(string evname, string evargs, ...)", "Invoke CSEv_evname_evargs in ssqc. evargs must be a string of initials refering to the types of the arguments to pass. v=vector, e=entity(.entnum field is sent), f=float, i=int. 6 arguments max - you can get more if you pack your floats into vectors.")},// (EXT_CSQC_1)
{"readbyte", PF_Fixme, 0, 0, 0, 360, "float()"},// (EXT_CSQC)
{"readchar", PF_Fixme, 0, 0, 0, 361, "float()"},// (EXT_CSQC)
{"readshort", PF_Fixme, 0, 0, 0, 362, "float()"},// (EXT_CSQC)
{"readlong", PF_Fixme, 0, 0, 0, 363, "float()"},// (EXT_CSQC)
{"readcoord", PF_Fixme, 0, 0, 0, 364, "float()"},// (EXT_CSQC)
{"readbyte", PF_Fixme, 0, 0, 0, 360, D("float()", "Reads an unsigned 8-bit value, pair with WriteByte.")},// (EXT_CSQC)
{"readchar", PF_Fixme, 0, 0, 0, 361, D("float()", "Reads a signed 8-bit value. Paired with WriteChar.")},// (EXT_CSQC)
{"readshort", PF_Fixme, 0, 0, 0, 362, D("float()", "Reads a signed 16-bit value. Paired with WriteShort.")},// (EXT_CSQC)
{"readlong", PF_Fixme, 0, 0, 0, 363, D("float()", "Reads a signed 32-bit value. Paired with WriteLong or WriteInt.")},// (EXT_CSQC)
{"readcoord", PF_Fixme, 0, 0, 0, 364, D("float()", "Reads a value matching the unspecified precision written ONLY by WriteCoord.")},// (EXT_CSQC)
{"readangle", PF_Fixme, 0, 0, 0, 365, "float()"},// (EXT_CSQC)
{"readstring", PF_Fixme, 0, 0, 0, 366, "string()"},// (EXT_CSQC)
{"readfloat", PF_Fixme, 0, 0, 0, 367, "float()"},// (EXT_CSQC)
{"readentitynum", PF_Fixme, 0, 0, 0, 368, "float()"},// (EXT_CSQC)
{"readangle", PF_Fixme, 0, 0, 0, 365, D("float()", "Reads a value matching the unspecified precision written ONLY by WriteAngle.")},// (EXT_CSQC)
{"readstring", PF_Fixme, 0, 0, 0, 366, D("string()", "Reads a null-terminated string.")},// (EXT_CSQC)
{"readfloat", PF_Fixme, 0, 0, 0, 367, D("float()", "Reads a float without any truncation nor conversions. Data MUST have originally been written with WriteFloat.")},// (EXT_CSQC)
{"readint", PF_Fixme, 0, 0, 0, 0, D("int()", "Reads a 32bit int without any conversions to float, otherwise interchangable with readlong.")},// (EXT_CSQC)
{"readentitynum", PF_Fixme, 0, 0, 0, 368, D("float()", "Reads the serverside index of an entity, paired with WriteEntity. There may be nothing else known about the entity yet, so the result typically needs to be saved as-is and re-looked up each frame. This can be done via getentity(NUM, GE_*) for non-csqc ents, or findentity(world,entnum,NUM) - both of which can fail due to latency.")},// (EXT_CSQC)
// {"readserverentitystate",PF_Fixme,0, 0, 0, 369, "void(float flags, float simtime)"},// (EXT_CSQC_1)
// {"readsingleentitystate",PF_Fixme,0, 0, 0, 370},