33cvar_t prvm_language = {
CF_CLIENT |
CF_SERVER |
CF_ARCHIVE,
"prvm_language",
"",
"when set, loads PROGSFILE.LANGUAGENAME.po and common.LANGUAGENAME.po for string translations; when set to dump, PROGSFILE.pot is written from the strings in the progs"};
42cvar_t prvm_leaktest_follow_targetname = {
CF_CLIENT |
CF_SERVER,
"prvm_leaktest_follow_targetname",
"0",
"if set, target/targetname links are considered when leak testing; this should normally not be required, as entities created during startup - e.g. info_notnull - are never considered leaky"};
56cvar_t sv_entfields_noescapes = {
CF_SERVER,
"sv_entfields_noescapes",
"wad",
"Space-separated list of fields in which backslashes won't be parsed as escapes when loading entities from .bsp or .ent files. This is a workaround for buggy maps with unescaped backslashes used as path separators (only forward slashes are allowed in Quake VFS paths)."};
57cvar_t prvm_gameplayfix_div0is0 = {
CF_SERVER,
"prvm_gameplayfix_div0is0",
"0",
"When set to 1, floating point division by 0 will return zero instead of returning the IEEE standardized result (likely nan or inf). Other ways of getting non-finite values are not affected, and the warning will still print."};
168 if (!strcmp(str,
"server"))
170 if (!strcmp(str,
"client"))
173 if (!strcmp(str,
"menu"))
189 Con_Printf(
"%s: unknown program name\n", str);
194 Con_Printf(
"%s: program is not loaded\n", str);
290 prog->
error_cmd(
"%s: PRVM_ED_Alloc: no free edicts", prog->
name);
463 dpsnprintf (line, linelength,
"entity %i (invalid!)",
n);
529 for (
i = 0;
i < (
int)linelength - 2 && *s;)
684 if(wildcard_fieldname)
702 memcpy (tempstring2,
name,
sizeof(tempstring2)-4);
703 tempstring2[
sizeof(tempstring2)-4] = tempstring2[
sizeof(tempstring2)-3] = tempstring2[
sizeof(tempstring2)-2] =
'.';
704 tempstring2[
sizeof(tempstring2)-1] = 0;
709 dp_strlcat(tempstring,
" ",
sizeof(tempstring));
710 dp_strlcat(tempstring,
" ",
sizeof(tempstring));
715 memcpy (tempstring2,
name,
sizeof(tempstring2)-4);
716 tempstring2[
sizeof(tempstring2)-4] = tempstring2[
sizeof(tempstring2)-3] = tempstring2[
sizeof(tempstring2)-2] =
'.';
717 tempstring2[
sizeof(tempstring2)-1] = 0;
721 dp_strlcat(tempstring,
"\n",
sizeof(tempstring));
722 if (
strlen(tempstring) >=
sizeof(tempstring)/2)
780 prog->
statestring =
va(vabuf,
sizeof(vabuf),
"PRVM_ED_Write, ent=%d, name=%s",
i,
name);
804 const char *wildcard_fieldname;
808 Con_Print(
"prvm_edicts <program name> <optional field name wildcard>\n");
818 wildcard_fieldname =
NULL;
836 const char *wildcard_fieldname;
840 Con_Print(
"prvm_edict <program name> <edict number> <optional field name wildcard>\n");
858 wildcard_fieldname =
NULL;
877 Con_Print(
"prvm_count <program name>\n");
917 type &= ~DEF_SAVEGLOBAL;
927 prog->
statestring =
va(vabuf,
sizeof(vabuf),
"PRVM_ED_WriteGlobals, name=%s",
name);
949 prog->
error_cmd(
"PRVM_ED_ParseGlobals: EOF without closing brace");
960 prog->
error_cmd(
"PRVM_ED_ParseGlobals: EOF without closing brace");
966 prog->
error_cmd(
"PRVM_ED_ParseGlobals: closing brace without data");
976 prog->
error_cmd(
"PRVM_ED_ParseGlobals: parse error");
1008 for (
i = 0;
i < l;
i++)
1010 if (s[
i] ==
'\\' && s[
i+1] && parsebackslash)
1015 else if (s[
i] ==
'r')
1032 for (
i = 0;
i < 3;
i++)
1051 Con_Printf(
"PRVM_ED_ParseEpair: ev_entity reference too large (edict %u >= MAX_EDICTS %u) on %s\n", (
unsigned int)
i, prog->
limit_edicts, prog->
name);
1063 Con_DPrintf(
"PRVM_ED_ParseEpair: Bogus field name %s in %s\n", s, prog->
name);
1069 Con_DPrintf(
"PRVM_ED_ParseEpair: Can't find field %s in %s\n", s, prog->
name);
1079 Con_Printf(
"PRVM_ED_ParseEpair: Can't find function %s in %s\n", s, prog->
name);
1122 Con_Printf(
"%s program do not support GameCommand!\n", whichprogs);
1126 int restorevm_tempstringsbuf_cursize;
1168 Con_Print(
"prvm_edictget <program name> <edict number> <field> [<cvar>]\n");
1211 Con_Print(
"prvm_globalget <program name> <global> [<cvar>]\n");
1257 Con_Print(
"prvm_edictset <program name> <edict number> <field> <value>\n");
1286 qbool parsebackslash =
true;
1295 prog->
error_cmd(
"PRVM_ED_ParseEdict: EOF without closing brace");
1318 while (
n && keyname[
n-1] ==
' ')
1334 parsebackslash =
false;
1344 prog->
error_cmd(
"PRVM_ED_ParseEdict: EOF without closing brace");
1349 prog->
error_cmd(
"PRVM_ED_ParseEdict: closing brace without data");
1359 if (keyname[0] ==
'_')
1377 prog->
error_cmd(
"PRVM_ED_ParseEdict: parse error");
1402 const char *funcname;
1424 else if (
data && start)
1431 for(in = start; in <
data; )
1435 *spawndata++ =
'\t';
1515 int parsed, inhibited, spawned, died;
1579 Con_DPrintf(
"%s: %i new entities parsed, %i new inhibited, %i (%i new) spawned (whereas %i removed self, %i stayed)\n", prog->
name, parsed, inhibited, prog->
num_edicts, spawned, died, spawned - died);
1591#define PRVM_DECLARE_serverglobalfloat(x)
1592#define PRVM_DECLARE_serverglobalvector(x)
1593#define PRVM_DECLARE_serverglobalstring(x)
1594#define PRVM_DECLARE_serverglobaledict(x)
1595#define PRVM_DECLARE_serverglobalfunction(x)
1596#define PRVM_DECLARE_clientglobalfloat(x)
1597#define PRVM_DECLARE_clientglobalvector(x)
1598#define PRVM_DECLARE_clientglobalstring(x)
1599#define PRVM_DECLARE_clientglobaledict(x)
1600#define PRVM_DECLARE_clientglobalfunction(x)
1601#define PRVM_DECLARE_menuglobalfloat(x)
1602#define PRVM_DECLARE_menuglobalvector(x)
1603#define PRVM_DECLARE_menuglobalstring(x)
1604#define PRVM_DECLARE_menuglobaledict(x)
1605#define PRVM_DECLARE_menuglobalfunction(x)
1606#define PRVM_DECLARE_serverfieldfloat(x)
1607#define PRVM_DECLARE_serverfieldvector(x)
1608#define PRVM_DECLARE_serverfieldstring(x)
1609#define PRVM_DECLARE_serverfieldedict(x)
1610#define PRVM_DECLARE_serverfieldfunction(x)
1611#define PRVM_DECLARE_clientfieldfloat(x)
1612#define PRVM_DECLARE_clientfieldvector(x)
1613#define PRVM_DECLARE_clientfieldstring(x)
1614#define PRVM_DECLARE_clientfieldedict(x)
1615#define PRVM_DECLARE_clientfieldfunction(x)
1616#define PRVM_DECLARE_menufieldfloat(x)
1617#define PRVM_DECLARE_menufieldvector(x)
1618#define PRVM_DECLARE_menufieldstring(x)
1619#define PRVM_DECLARE_menufieldedict(x)
1620#define PRVM_DECLARE_menufieldfunction(x)
1621#define PRVM_DECLARE_serverfunction(x)
1622#define PRVM_DECLARE_clientfunction(x)
1623#define PRVM_DECLARE_menufunction(x)
1624#define PRVM_DECLARE_field(x) prog->fieldoffsets.x = PRVM_ED_FindFieldOffset(prog, #x);
1625#define PRVM_DECLARE_global(x) prog->globaloffsets.x = PRVM_ED_FindGlobalOffset(prog, #x);
1626#define PRVM_DECLARE_function(x) prog->funcoffsets.x = PRVM_ED_FindFunctionOffset(prog, #x);
1628#undef PRVM_DECLARE_serverglobalfloat
1629#undef PRVM_DECLARE_serverglobalvector
1630#undef PRVM_DECLARE_serverglobalstring
1631#undef PRVM_DECLARE_serverglobaledict
1632#undef PRVM_DECLARE_serverglobalfunction
1633#undef PRVM_DECLARE_clientglobalfloat
1634#undef PRVM_DECLARE_clientglobalvector
1635#undef PRVM_DECLARE_clientglobalstring
1636#undef PRVM_DECLARE_clientglobaledict
1637#undef PRVM_DECLARE_clientglobalfunction
1638#undef PRVM_DECLARE_menuglobalfloat
1639#undef PRVM_DECLARE_menuglobalvector
1640#undef PRVM_DECLARE_menuglobalstring
1641#undef PRVM_DECLARE_menuglobaledict
1642#undef PRVM_DECLARE_menuglobalfunction
1643#undef PRVM_DECLARE_serverfieldfloat
1644#undef PRVM_DECLARE_serverfieldvector
1645#undef PRVM_DECLARE_serverfieldstring
1646#undef PRVM_DECLARE_serverfieldedict
1647#undef PRVM_DECLARE_serverfieldfunction
1648#undef PRVM_DECLARE_clientfieldfloat
1649#undef PRVM_DECLARE_clientfieldvector
1650#undef PRVM_DECLARE_clientfieldstring
1651#undef PRVM_DECLARE_clientfieldedict
1652#undef PRVM_DECLARE_clientfieldfunction
1653#undef PRVM_DECLARE_menufieldfloat
1654#undef PRVM_DECLARE_menufieldvector
1655#undef PRVM_DECLARE_menufieldstring
1656#undef PRVM_DECLARE_menufieldedict
1657#undef PRVM_DECLARE_menufieldfunction
1658#undef PRVM_DECLARE_serverfunction
1659#undef PRVM_DECLARE_clientfunction
1660#undef PRVM_DECLARE_menufunction
1661#undef PRVM_DECLARE_field
1662#undef PRVM_DECLARE_global
1663#undef PRVM_DECLARE_function
1688#define PO_HASHSIZE 16384
1689typedef struct po_string_s
1709 case '\a':
if(outsize >= 2) { *out++ =
'\\'; *out++ =
'a'; outsize -= 2; }
break;
1710 case '\b':
if(outsize >= 2) { *out++ =
'\\'; *out++ =
'b'; outsize -= 2; }
break;
1711 case '\t':
if(outsize >= 2) { *out++ =
'\\'; *out++ =
't'; outsize -= 2; }
break;
1712 case '\r':
if(outsize >= 2) { *out++ =
'\\'; *out++ =
'r'; outsize -= 2; }
break;
1713 case '\n':
if(outsize >= 2) { *out++ =
'\\'; *out++ =
'n'; outsize -= 2; }
break;
1714 case '\\':
if(outsize >= 2) { *out++ =
'\\'; *out++ =
'\\'; outsize -= 2; }
break;
1715 case '"':
if(outsize >= 2) { *out++ =
'\\'; *out++ =
'"'; outsize -= 2; }
break;
1717 if(*in >= 0 && *in <= 0x1F)
1722 *out++ =
'0' + ((*in & 0700) >> 6);
1723 *out++ =
'0' + ((*in & 0070) >> 3);
1724 *out++ =
'0' + (*in & 0007) ;
1754 case 'a':
if(outsize > 0) { *out++ =
'\a'; --outsize; }
break;
1755 case 'b':
if(outsize > 0) { *out++ =
'\b'; --outsize; }
break;
1756 case 't':
if(outsize > 0) { *out++ =
'\t'; --outsize; }
break;
1757 case 'r':
if(outsize > 0) { *out++ =
'\r'; --outsize; }
break;
1758 case 'n':
if(outsize > 0) { *out++ =
'\n'; --outsize; }
break;
1759 case '\\':
if(outsize > 0) { *out++ =
'\\'; --outsize; }
break;
1760 case '"':
if(outsize > 0) { *out++ =
'"'; --outsize; }
break;
1761 case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
1765 if(*in >=
'0' && *in <=
'7')
1768 *out = (*out << 3) | (*in -
'0');
1771 if(*in >=
'0' && *in <=
'7')
1774 *out = (*out << 3) | (*in -
'0');
1785 if(outsize > 0) { *out++ = *in; --outsize; }
1812 for (
i = 0;
i < 2; ++
i)
1814 const char *
buf = (
const char *)
1826 memset(po, 0,
sizeof(*po));
1829 memset(&thisstr, 0,
sizeof(thisstr));
1837 p = strchr(p,
'\n');
1843 if(*p ==
'\r' || *p ==
'\n')
1848 if(!strncmp(p,
"msgid \"", 7))
1853 else if(!strncmp(p,
"msgstr \"", 8))
1860 p = strchr(p,
'\n');
1870 q = strchr(p,
'\n');
1877 if((
size_t)(q - p) >= (
size_t)
sizeof(inbuf))
1879 memcpy(inbuf, p, q - p - 1);
1880 inbuf[q - p - 1] =
'\0';
1882 decodedpos +=
strlen(decodedbuf + decodedpos);
1894 memcpy(thisstr.
key, decodedbuf, decodedpos + 1);
1896 else if(decodedpos > 0 && thisstr.
key)
1899 memcpy(thisstr.
value, decodedbuf, decodedpos + 1);
1903 memcpy(po->
hashtable[hashindex], &thisstr,
sizeof(thisstr));
1904 memset(&thisstr, 0,
sizeof(thisstr));
1919 if(!strcmp(str, p->
key))
1971 unsigned int *header;
1975 dp_strlcat( filename,
".lno",
sizeof( filename ) );
1997 header = (
unsigned int *) lno;
1998 if (memcmp(lno,
"LNOF", 4) == 0
2031 ddef16_t *infielddefs16;
2032 ddef32_t *infielddefs32;
2033 ddef16_t *inglobaldefs16;
2034 ddef32_t *inglobaldefs32;
2040 int requiredglobalspace;
2056 int max_safe_edicts;
2059 prog->
error_cmd(
"%s: there is already a %s program loaded!", __func__, prog->
name);
2072 prog->
error_cmd(
"%s: couldn't load \"%s\" for %s", __func__, filename, prog->
name);
2078 requiredglobalspace = 0;
2079 for (
i = 0;
i < numrequiredglobals;
i++)
2080 requiredglobalspace += required_global[
i].
type ==
ev_vector ? 3 : 1;
2093 Con_Printf(
CON_WARN "WARNING: %s: %s targets FTEQW, for which support is incomplete. Proceed at your own risk.\n", prog->
name, filename);
2095 prog->
error_cmd(
"%s: %s targets unknown engine", prog->
name, filename);
2098 prog->
error_cmd(
"%s: %s uses unsupported features.", prog->
name, filename);
2106 inglobaldefs32 = (ddef32_t *)inglobaldefs16;
2109 infielddefs32 = (ddef32_t *)infielddefs16;
2128 prog->
error_cmd(
"%s: %s strings go past end of file", prog->
name, filename);
2165 prog->
error_cmd(
"%s: out of bounds function statement (function %d) in %s", __func__,
i, prog->
name);
2193 for (
i = 0;
i < numrequiredglobals;
i++)
2213 prog->
error_cmd(
"%s: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", __func__, prog->
name);
2224 prog->
error_cmd(
"%s: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", __func__, prog->
name);
2233 for (
i = 0;
i < numrequiredfields;
i++)
2247#define remapglobal(index) (index)
2248#define remapfield(index) (index)
2258 d = u.i & 0xFF800000;
2259 if ((d == 0xFF800000) || (d == 0))
2296 prog->
error_cmd(
"%s: out of bounds IF/IFNOT (statement %d) in %s", __func__,
i, prog->
name);
2298 Con_DPrintf(
"%s: unexpected offset on binary opcode in %s\n", __func__, prog->
name);
2307 prog->
error_cmd(
"%s: out of bounds GOTO (statement %d) in %s", __func__,
i, prog->
name);
2309 Con_DPrintf(
"%s: unexpected offset on unary opcode in %s\n", __func__, prog->
name);
2316 Con_DPrintf(
"%s: unknown opcode %d at statement %d in %s\n", __func__, (
int)op,
i, prog->
name);
2454 prog->
error_cmd(
"%s: out of bounds global index (statement %d)", __func__,
i);
2467 prog->
error_cmd(
"%s: out of bounds global index (statement %d) in %s", __func__,
i, prog->
name);
2469 Con_DPrintf(
"%s: unexpected offset on binary opcode in %s\n", __func__, prog->
name);
2486 prog->
error_cmd(
"%s: out of bounds global index (statement %d) in %s", __func__,
i, prog->
name);
2488 Con_DPrintf(
"%s: unexpected offset on binary opcode in %s\n", __func__, prog->
name);
2512 prog->
error_cmd(
"%s: out of bounds global index (statement %d) in %s", __func__,
i, prog->
name);
2514 Con_DPrintf(
"%s: unexpected offset on call opcode in %s. Hexen2 format is not supported\n", __func__, prog->
name);
2524 prog->
error_cmd(
"%s: empty program in %s", __func__, prog->
name);
2533 prog->
error_cmd(
"%s: program may fall off the edge (does not end with RETURN, GOTO or DONE) in %s", __func__, prog->
name);
2544 CheckRequiredFuncs(prog, filename);
2563 if(
name && !strncmp(
name,
"dotranslate_", 12))
2572 qfile_t *
f =
FS_OpenRealFile(
va(vabuf,
sizeof(vabuf),
"%s.pot", realfilename),
"w",
false);
2573 Con_Printf(
"Dumping to %s.pot\n", realfilename);
2580 if(deftrans ? (!
name || strncmp(
name,
"notranslate_", 12)) : (
name && !strncmp(
name,
"dotranslate_", 12)))
2608 if(deftrans ? (!
name || strncmp(
name,
"notranslate_", 12)) : (
name && !strncmp(
name,
"dotranslate_", 12)))
2634 && !strncmp(
name,
"autocvar_", 9)
2647 Con_DPrintf(
"%s: no cvar for autocvar global %s in %s, creating...\n", __func__,
name, prog->
name);
2657 for (
int precision = 7; precision <= 9; ++precision) {
2659 if ((
float)atof(
buf) ==
f) {
2667 for (
i = 0;
i < 3; ++
i)
2671 for (
int precision = 7; precision <= 9; ++precision) {
2673 if ((
float)atof(
buf) ==
f) {
2674 prec[
i] = precision;
2686 Con_Printf(
"%s: invalid type of autocvar global %s in %s\n", __func__,
name, prog->
name);
2696 prog->
error_cmd(
"%s: could not create cvar for autocvar global %s in %s", __func__,
name, prog->
name);
2712 for (j = 0;j < 3;j++)
2718 val->
vector[j] = atof(s);
2730 Con_Printf(
"%s: invalid type of autocvar global %s in %s\n", __func__,
name, prog->
name);
2736 Con_Printf(
"%s: private cvar for autocvar global %s in %s\n", __func__,
name, prog->
name);
2755 Con_Printf(
"%s: reducing maximum entity count to %d to avoid address overflow in %s\n", __func__, max_safe_edicts, prog->
name);
2764 Con_Printf(
"%s: program loaded (crc %i, size %iK)%s\n", prog->
name, prog->
filecrc, (
int)(filesize/1024),
2776 int i, j, ednum, used, usedamount;
2795 Con_Print(
"prvm_fields <program name>\n");
2803 for (ednum = 0;ednum < prog->
max_edicts;ednum++)
2838 dp_strlcat(tempstring,
"string ",
sizeof(tempstring));
2841 dp_strlcat(tempstring,
"entity ",
sizeof(tempstring));
2844 dp_strlcat(tempstring,
"function ",
sizeof(tempstring));
2847 dp_strlcat(tempstring,
"field ",
sizeof(tempstring));
2850 dp_strlcat(tempstring,
"void ",
sizeof(tempstring));
2853 dp_strlcat(tempstring,
"float ",
sizeof(tempstring));
2856 dp_strlcat(tempstring,
"vector ",
sizeof(tempstring));
2859 dp_strlcat(tempstring,
"pointer ",
sizeof(tempstring));
2863 dp_strlcat(tempstring, tempstring2,
sizeof(tempstring));
2868 memcpy (tempstring2,
name,
sizeof(tempstring2)-4);
2869 tempstring2[
sizeof(tempstring2)-4] = tempstring2[
sizeof(tempstring2)-3] = tempstring2[
sizeof(tempstring2)-2] =
'.';
2870 tempstring2[
sizeof(tempstring2)-1] = 0;
2875 dp_strlcat(tempstring,
" ",
sizeof(tempstring));
2876 dpsnprintf(tempstring2,
sizeof(tempstring2),
"%5d", counts[
i]);
2877 dp_strlcat(tempstring, tempstring2,
sizeof(tempstring));
2878 dp_strlcat(tempstring,
"\n",
sizeof(tempstring));
2879 if (
strlen(tempstring) >=
sizeof(tempstring)/2)
2891 Con_Printf(
"%s: %i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", prog->
name, prog->
entityfields, used, prog->
entityfields * 4, usedamount * 4, prog->
max_edicts, prog->
entityfields * 4 * prog->
max_edicts, usedamount * 4 * prog->
max_edicts);
2898 const char *wildcard;
2909 Con_Print(
"prvm_globals <program name> <optional name wildcard>\n");
2947 Con_Printf(
"prvm_global <program name> <global name>\n" );
2971 Con_Printf(
"prvm_globalset <program name> <global name> <value>\n" );
2992 char break_statement[256];
2993 char watch_global[256];
2995 char watch_field[256];
3012 if (memcmp(o,
n, sz))
3015 char valuebuf_o[128];
3016 char valuebuf_n[128];
3019 dpsnprintf(
buf,
sizeof(
buf),
"%s: %s -> %s", text, valuebuf_o, valuebuf_n);
3120 Con_Printf(
"prvm_breakpoint <program name> <function name | statement>\n" );
3149 Con_Printf(
"prvm_globalwatchpoint <program name> <global name>\n" );
3178 Con_Printf(
"prvm_edictwatchpoint <program name> <edict number> <field name>\n" );
3206 Cmd_AddCommand(
CF_SHARED,
"prvm_childprofile",
PRVM_ChildProfile_f,
"prints execution statistics about the most used QuakeC functions in the selected VM (server, client, menu), sorted by time taken in function with child calls");
3208 Cmd_AddCommand(
CF_SHARED,
"prvm_fields",
PRVM_Fields_f,
"prints usage statistics on properties (how many entities have non-zero values) in the selected VM (server, client, menu)");
3213 Cmd_AddCommand(
CF_SHARED,
"prvm_edictget",
PRVM_ED_EdictGet_f,
"retrieves the value of a specified property of a specified entity in the selected VM (server, client menu) into a cvar or to the console");
3219 Cmd_AddCommand(
CF_SHARED,
"prvm_breakpoint",
PRVM_Breakpoint_f,
"marks a statement or function as breakpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear breakpoint");
3220 Cmd_AddCommand(
CF_SHARED,
"prvm_globalwatchpoint",
PRVM_GlobalWatchpoint_f,
"marks a global as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint");
3221 Cmd_AddCommand(
CF_SHARED,
"prvm_edictwatchpoint",
PRVM_EdictWatchpoint_f,
"marks an entity field as watchpoint (when this is executed, a stack trace is printed); to actually halt and investigate state, combine this with a gdb breakpoint on PRVM_Breakpoint, or with prvm_breakpointdump; run with just progs name to clear watchpoint");
3250 Con_DPrintf(
"\nQuakeC extensions for server and client:");
3277 prog->
error_cmd(
"PRVM_EDICT_NUM: %s: bad number %i (called at %s:%i)", prog->
name,
n, filename, fileline);
3281#define PRVM_KNOWNSTRINGBASE 0x40000000
3289 VM_Warning(prog,
"PRVM_GetString: Invalid string offset (%i < 0)\n", num);
3292 else if (num < prog->stringssize)
3301 if (num < prog->tempstringsbuf.cursize)
3314 if (num >= 0 && num < prog->numknownstrings)
3319 VM_Warning(prog,
"PRVM_GetString: Invalid zone-string offset (%i has been freed)\n", num);
3340 VM_Warning(prog,
"PRVM_GetString: Invalid constant-string offset (%i >= %i prog->stringssize)\n", num, prog->
stringssize);
3350 prog->
error_cmd(
"PRVM_ChangeEngineString: string index %i is out of bounds",
i);
3352 prog->
error_cmd(
"PRVM_ChangeEngineString: string index %i is not an engine string",
i);
3396 prog->
error_cmd(
"PRVM_SetEngineString: s in prog->strings area");
3407 Con_DPrintf(
"new engine string %p = \"%s\"\n", (
void *)s, s);
3437 prog->
error_cmd(
"PRVM_SetTempString %s: ran out of tempstring memory! (refusing to grow tempstring buffer over 256MB, cursize %i, new tempstring size %lu)\n", prog->
name, prog->
tempstringsbuf.
cursize, (
unsigned long)
size);
3484 prog->
error_cmd(
"PRVM_FreeString %s: attempt to free a NULL string", prog->
name);
3485 else if (num >= 0 && num < prog->stringssize)
3486 prog->
error_cmd(
"PRVM_FreeString %s: attempt to free a constant string", prog->
name);
3491 prog->
error_cmd(
"PRVM_FreeString %s: attempt to free a non-existent or already freed string", prog->
name);
3493 prog->
error_cmd(
"PRVM_FreeString %s: attempt to free a string owned by the engine", prog->
name);
3503 prog->
error_cmd(
"PRVM_FreeString %s: invalid string offset %i", prog->
name, num);
3679 Con_DPrintf(
"leak check used %d stages to find all references\n", stage);
3685 qbool leaked =
false;
3728 Con_Printf(
"Open string buffer handle found!\n Allocated at: %s\n", stringbuffer->
origin);
3754 Con_Printf(
"Congratulations. No leaks found.\n");
3821 Con_DPrintf(
"PRVM_GarbageCollection: Found bogus strzone reference in edict %i field %i (field name: \"%s\"), erasing reference", entityindex, d->
ofs,
PRVM_GetString(prog, d->
s_name));
3859 Con_DPrintf(
"prvm_garbagecollection_notify: %s: freeing unreferenced string %i: \"%s\"\n", prog->
name, num, prog->
knownstrings[num]);
3877 memset(gc, 0,
sizeof(*gc));
void Cmd_AddCommand(unsigned flags, const char *cmd_name, xcommand_t function, const char *description)
called by the init functions of other parts of the program to register commands and functions to call...
#define CF_SERVER
cvar/command that only the server can change/execute
static int Cmd_Argc(cmd_state_t *cmd)
static const char * Cmd_Argv(cmd_state_t *cmd, int arg)
Cmd_Argv(cmd, ) will return an empty string (not a NULL) if arg > argc, so string operations are alwa...
#define CF_CLIENT
cvar/command that only the client can change/execute
static const char * Cmd_Args(cmd_state_t *cmd)
#define CF_ARCHIVE
cvar should have its set value saved to config.cfg and persist across sessions
#define CF_PRIVATE
cvar should not be $ expanded or sent to the server under any circumstances (rcon_password,...
unsigned short CRC_Block(const unsigned char *data, size_t size)
char com_token[MAX_INPUTLINE]
char * va(char *buf, size_t buflen, const char *format,...)
qbool COM_ParseToken_Console(const char **datapointer)
qbool COM_ParseToken_Simple(const char **datapointer, qbool returnnewline, qbool parsebackslash, qbool parsecomments)
int dpsnprintf(char *buffer, size_t buffersize, const char *format,...)
Returns the number of printed characters, excluding the final '\0' or returns -1 if the buffer isn't ...
#define dp_strlcat(dst, src, dsize)
#define dp_strlcpy(dst, src, dsize)
void Con_Print(const char *msg)
Prints to all appropriate console targets, and adds timestamps.
void Con_DPrintf(const char *fmt,...)
A Con_Printf that only shows up if the "developer" cvar is set.
void Con_Printf(const char *fmt,...)
Prints to all appropriate console targets.
void Con_DPrint(const char *msg)
A Con_Print that only shows up if the "developer" cvar is set.
void Crypto_LoadKeys(void)
void Cvar_RegisterVariable(cvar_t *variable)
registers a cvar that already has the name, string, and optionally the archive elements set.
cvar_t * Cvar_Get(cvar_state_t *cvars, const char *name, const char *value, unsigned flags, const char *newdescription)
allocates a cvar by name and returns its address, or merely sets its value if it already exists.
cvar_t * Cvar_FindVar(cvar_state_t *cvars, const char *var_name, unsigned neededflags)
qbool Cvar_Readonly(cvar_t *var, const char *cmd_name)
int matchpattern(const char *in, const char *pattern, int caseinsensitive)
unsigned char * FS_LoadFile(const char *path, mempool_t *pool, qbool quiet, fs_offset_t *filesizepointer)
qfile_t * FS_OpenRealFile(const char *filepath, const char *mode, qbool quiet)
static int(ZEXPORT *qz_inflate)(z_stream *strm
void FS_StripExtension(const char *in, char *out, size_t size_out)
int FS_Close(qfile_t *file)
int FS_Printf(qfile_t *file, const char *format,...)
int FS_Print(qfile_t *file, const char *msg)
GLsizei const GLfloat * value
GLsizeiptr const GLvoid * data
GLenum GLuint GLenum GLsizei const GLchar * buf
void Host_LockSession(void)
cvar_t developer_entityparsing
#define bound(min, num, max)
const char * vm_m_extensions[]
#define PROG_SECONDARYVERSION32
#define PROG_SECONDARYVERSION16
#define PRVM_VECTOR_LOSSLESS_FORMAT
#define PRVM_FLOAT_LOSSLESS_FORMAT
#define KNOWNSTRINGFLAG_ENGINE
void PRVM_Profile_f(struct cmd_state_s *cmd)
#define PRVM_alledictstring(ed, fieldname)
void VM_Warning(prvm_prog_t *prog, const char *fmt,...) DP_FUNC_PRINTF(2)
#define PRVM_serverglobaledict(fieldname)
void PRVM_Init_Exec(prvm_prog_t *prog)
void PRVM_ChildProfile_f(struct cmd_state_s *cmd)
#define PRVM_EDICT_TO_PROG(e)
#define PRVM_MAX_OPENFILES
const char * vm_sv_extensions[]
client also uses this
#define PRVM_Alloc(buffersize)
#define PRVM_EDICT_NUM(n)
#define PRVM_clientedictstring(ed, fieldname)
#define PRVM_EDICTFIELDEDICT(ed, fieldoffset)
#define PRVM_allfunction(funcname)
#define PRVM_EDICTFIELDSTRING(ed, fieldoffset)
#define PRVM_NUM_FOR_EDICT(e)
#define PRVM_Free(buffer)
#define PRVM_clientedictfunction(ed, fieldname)
void PRVM_CallProfile_f(struct cmd_state_s *cmd)
void PRVM_PrintFunction_f(struct cmd_state_s *cmd)
@ PRVM_GC_KNOWNSTRINGS_SWEEP
#define PRVM_serverglobalfloat(fieldname)
#define PRVM_serveredictfloat(ed, fieldname)
#define PRVM_MAX_OPENSEARCHES
#define PRVM_serverfunction(funcname)
#define PRVM_clientedictfloat(ed, fieldname)
#define KNOWNSTRINGFLAG_GCPRUNE
#define PRVM_GLOBALFIELDSTRING(fieldoffset)
#define PRVM_serveredictstring(ed, fieldname)
#define PRVM_serveredictfunction(ed, fieldname)
#define PRVM_GLOBALFIELDVALUE(fieldoffset)
#define PRVM_allglobaledict(fieldname)
#define PRVM_EDICTFIELDVALUE(ed, fieldoffset)
void PRVM_PrintState(prvm_prog_t *prog, int stack_index)
#define KNOWNSTRINGFLAG_GCMARK
#define PRVM_GLOBALFIELDEDICT(fieldoffset)
#define PRVM_allglobalfloat(fieldname)
void PRVM_ShortStackTrace(prvm_prog_t *prog, char *buf, size_t bufsize)
#define VM_TEMPSTRING_MAXSIZE
static void PRVM_GameCommand_Client_f(cmd_state_t *cmd)
cvar_t prvm_reuseedicts_neverinsameframe
void PRVM_ED_LoadFromFile(prvm_prog_t *prog, const char *data)
static void PRVM_EdictWatchpoint_f(cmd_state_t *cmd)
static void PRVM_Global_f(cmd_state_t *cmd)
static void PRVM_ED_EdictSet_f(cmd_state_t *cmd)
void PRVM_ED_ClearEdict(prvm_prog_t *prog, prvm_edict_t *e)
int PRVM_SetTempString(prvm_prog_t *prog, const char *s, size_t slen)
Takes an strlen (not a buffer size).
cvar_t prvm_gameplayfix_div0is0
void PRVM_ED_CallPostspawnFunction(prvm_prog_t *prog, prvm_edict_t *ent)
void PRVM_Watchpoint(prvm_prog_t *prog, int stack_index, const char *text, etype_t type, prvm_eval_t *o, prvm_eval_t *n)
static void PRVM_GlobalSet_f(cmd_state_t *cmd)
static void PRVM_GlobalWatchpoint_f(cmd_state_t *cmd)
static void PRVM_PO_ParseString(char *out, const char *in, size_t outsize)
char * PRVM_UglyValueString(prvm_prog_t *prog, etype_t type, prvm_eval_t *val, char *line, size_t linelength)
static po_t * PRVM_PO_Load(const char *filename, const char *filename2, mempool_t *pool)
cvar_t prvm_timeprofiling
static void PRVM_FindOffsets(prvm_prog_t *prog)
void PRVM_Prog_Init(prvm_prog_t *prog, cmd_state_t *cmd)
mdef_t * PRVM_ED_FindGlobal(prvm_prog_t *prog, const char *name)
void PRVM_Prog_Load(prvm_prog_t *prog, const char *filename, unsigned char *data, fs_offset_t size, void CheckRequiredFuncs(prvm_prog_t *prog, const char *filename), int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global)
static void PRVM_GameCommand_Menu_f(cmd_state_t *cmd)
static void PRVM_NewKnownString(prvm_prog_t *prog, int i, int flags, const char *s)
#define remapglobal(index)
mfunction_t * PRVM_ED_FindFunction(prvm_prog_t *prog, const char *name)
const char * PRVM_ChangeEngineString(prvm_prog_t *prog, int i, const char *s)
int PRVM_SetEngineString(prvm_prog_t *prog, const char *s)
void PRVM_ED_PrintNum(prvm_prog_t *prog, int ent, const char *wildcard_fieldname)
static debug_data_t debug_data[PRVM_PROG_MAX]
static void PRVM_ED_PrintEdict_f(cmd_state_t *cmd)
static void PRVM_ED_GlobalGet_f(cmd_state_t *cmd)
void PRVM_ED_Write(prvm_prog_t *prog, qfile_t *f, prvm_edict_t *ed)
void PRVM_FreeString(prvm_prog_t *prog, int num)
qbool PRVM_ED_ParseEpair(prvm_prog_t *prog, prvm_edict_t *ent, mdef_t *key, const char *s, qbool parsebackslash)
void PRVM_ED_PrintEdicts_f(cmd_state_t *cmd)
const char * PRVM_ED_ParseEdict(prvm_prog_t *prog, const char *data, prvm_edict_t *ent, qbool saveload)
prvm_prog_t * PRVM_ProgFromString(const char *str)
int PRVM_AllocString(prvm_prog_t *prog, size_t bufferlength, char **pointer)
unsigned int PRVM_EDICT_NUM_ERROR(prvm_prog_t *prog, unsigned int n, const char *filename, int fileline)
const char * PRVM_GetString(prvm_prog_t *prog, int num)
prvm_eval_t * PRVM_ED_FindGlobalEval(prvm_prog_t *prog, const char *name)
void PRVM_Prog_Reset(prvm_prog_t *prog)
int prvm_type_size[8]
for consistency : I think a goal of this sub-project is to make the new vm mostly independent from th...
static mdef_t * PRVM_ED_GlobalAtOfs(prvm_prog_t *prog, unsigned int ofs)
static double prvm_reuseedicts_always_allow
static char * PRVM_ValueString(prvm_prog_t *prog, etype_t type, prvm_eval_t *val, char *line, size_t linelength)
cvar_t prvm_garbagecollection_notify
void PRVM_Breakpoint(prvm_prog_t *prog, int stack_index, const char *text)
static qbool PRVM_IsEdictRelevant(prvm_prog_t *prog, prvm_edict_t *edict)
static const char * PRVM_PO_Lookup(po_t *po, const char *str)
static void PRVM_Fields_f(cmd_state_t *cmd)
cvar_t prvm_statementprofiling
void PRVM_LeakTest(prvm_prog_t *prog)
cvar_t prvm_garbagecollection_enable
void PRVM_GarbageCollection(prvm_prog_t *prog)
prvm_prog_t * PRVM_FriendlyProgFromString(const char *str)
for console commands (prints error if name unknown and returns NULL, prints error if prog not loaded ...
void PRVM_ED_ParseGlobals(prvm_prog_t *prog, const char *data)
static void PRVM_MEM_Alloc(prvm_prog_t *prog)
cvar_t prvm_garbagecollection_scan_limit
At 50k in Xonotic with 8 bots scans take about: 24s server, 25s menu, 9s client.
void PRVM_MEM_IncreaseEdicts(prvm_prog_t *prog)
mdef_t * PRVM_ED_FindField(prvm_prog_t *prog, const char *name)
int PRVM_ED_FindGlobalOffset(prvm_prog_t *prog, const char *global)
void PRVM_ED_WriteGlobals(prvm_prog_t *prog, qfile_t *f)
#define PRVM_KNOWNSTRINGBASE
static void PRVM_GameCommand(cmd_state_t *cmd, const char *whichprogs, const char *whichcmd)
static void PRVM_LoadLNO(prvm_prog_t *prog, const char *progname)
static void PRVM_MarkReferencedEdicts(prvm_prog_t *prog)
static void PRVM_Globals_f(cmd_state_t *cmd)
static void PRVM_PO_UnparseString(char *out, const char *in, size_t outsize)
char * PRVM_GlobalString(prvm_prog_t *prog, int ofs, char *line, size_t linelength)
cvar_t prvm_breakpointdump
static void PRVM_PO_Destroy(po_t *po)
cvar_t prvm_garbagecollection_strings
cvar_t prvm_backtraceforwarnings
qbool PRVM_ED_CallSpawnFunction(prvm_prog_t *prog, prvm_edict_t *ent, const char *data, const char *start)
cvar_t sv_entfields_noescapes
char * PRVM_GlobalStringNoContents(prvm_prog_t *prog, int ofs, char *line, size_t linelength)
static void PRVM_ED_Count_f(cmd_state_t *cmd)
cvar_t prvm_leaktest_follow_targetname
cvar_t prvm_leaktest_ignore_classnames
static void PRVM_Breakpoint_f(cmd_state_t *cmd)
void PRVM_ED_Free(prvm_prog_t *prog, prvm_edict_t *ed)
static qbool PRVM_IsStringReferenced(prvm_prog_t *prog, string_t string)
void PRVM_ED_Print(prvm_prog_t *prog, prvm_edict_t *ed, const char *wildcard_fieldname)
static void PRVM_GameCommand_Server_f(cmd_state_t *cmd)
mdef_t * PRVM_ED_FieldAtOfs(prvm_prog_t *prog, unsigned int ofs)
func_t PRVM_ED_FindFunctionOffset(prvm_prog_t *prog, const char *function)
void PRVM_ED_CallPrespawnFunction(prvm_prog_t *prog, prvm_edict_t *ent)
cvar_t prvm_reuseedicts_startuptime
prvm_eval_t prvm_badvalue
static qbool PRVM_IsEdictReferenced(prvm_prog_t *prog, prvm_edict_t *edict, int mark)
static void PRVM_ED_EdictGet_f(cmd_state_t *cmd)
int PRVM_ED_FindFieldOffset(prvm_prog_t *prog, const char *field)
const char * PRVM_AllocationOrigin(prvm_prog_t *prog)
prvm_prog_t prvm_prog_list[PRVM_PROG_MAX]
static void PRVM_UpdateBreakpoints(prvm_prog_t *prog)
prvm_edict_t * PRVM_ED_Alloc(prvm_prog_t *prog)
qbool PRVM_ED_CanAlloc(prvm_prog_t *prog, prvm_edict_t *e)
#define MAX_INPUTLINE
maximum size of console commandline, QuakeC strings, and many other text processing buffers
void SV_LinkEdict(prvm_edict_t *ent)
void SV_Savegame_to(prvm_prog_t *prog, const char *name)
command interpreter state - the tokenizing and execution of commands, as well as pointers to which cv...
char break_statement[256]
uint8_t parm_size[MAX_PARMS]
uint32_t numbodylessfuncs
uint32_t blockscompressed
double realtime
the accumulated mainloop time since application started (with filtering), without any slowmo or clamp...
uint8_t parm_size[MAX_PARMS]
struct po_string_s * nextonhashchain
po_string_t * hashtable[PO_HASHSIZE]
int mark
mark for the leak detector
const char * allocation_origin
place in the code where it was allocated (for the leak detector)
union prvm_edict_t::@30 fields
qbool free
true if this edict is unused
double freetime
sv.time when the object was freed (to prevent early reuse which could mess up client interpolation or...
union prvm_edict_t::@29 priv
prvm_edict_private_t * required
int knownstrings_sweep_progress
int globals_mark_progress
int fields_mark_progress_entity
const char * statestring
printed together with backtraces
prvm_eval_t watch_global_value
int * statement_linenums
NULL if not available.
void(* reset_cmd)(struct prvm_prog_s *prog)
[INIT] used by PRVM_ResetProg
int entityfields
number of vec_t fields in progs (some variables are 3)
struct qfile_s * openfiles[PRVM_MAX_OPENFILES]
int entityfieldsarea
LadyHavoc: equal to max_edicts * entityfields (for bounds checking)
qbool loaded
used to indicate whether a prog is loaded
prvm_prog_funcoffsets_t funcoffsets
unsigned char * knownstrings_flags
int edictprivate_size
size of the engine private struct
const char * name
name of the prog, e.g. "Server", "Client" or "Menu" (used for text output)
void(* begin_increase_edicts)(struct prvm_prog_s *prog)
[INIT] used by PRVM_MEM_Increase_Edicts
void(* free_edict)(struct prvm_prog_s *prog, prvm_edict_t *ed)
[INIT] used by PRVM_ED_Free
const char ** knownstrings
void(* error_cmd)(const char *format,...) DP_FUNC_PRINTF(1) DP_FUNC_NORETURN
[INIT]
int num_edicts
copies of some vars that were former read from sv
prvm_prog_fieldoffsets_t fieldoffsets
union prvm_prog_t::@32 edictsfields
void(* count_edicts)(struct prvm_prog_s *prog)
[INIT] used by PRVM_ED_Count_f
double inittime
system time when QC initialization code finished (any entity created before is not a leak)
const char * opensearches_origin[PRVM_MAX_OPENSEARCHES]
int limit_edicts
used instead of the constant MAX_EDICTS
prvm_prog_globaloffsets_t globaloffsets
unsigned flag
flag - used to store general flags like PRVM_GE_SELF, etc.
void(* init_edict)(struct prvm_prog_s *prog, prvm_edict_t *edict)
[INIT] used by PRVM_ED_ClearEdict
double * explicit_profile
only incremented if prvm_statementprofiling is on
double * statement_profile
only incremented if prvm_statementprofiling is on
mempool_t * progs_mempool
all memory allocations related to this vm_prog (code, edicts, strings)
struct fssearch_s * opensearches[PRVM_MAX_OPENSEARCHES]
etype_t watch_global_type
memexpandablearray_t stringbuffersarray
struct cmd_state_s * console_cmd
points to the relevant console command interpreter for this vm (cmd_local or &cmd_server),...
int max_edicts
number of edicts for which space has been (should be) allocated
void * po
translation buffer (only needs to be freed on unloading progs, type is private to prvm_edict....
mstatement_t * statements
void(* ExecuteProgram)(struct prvm_prog_s *prog, func_t fnum, const char *errormessage)
pointer to one of the *VM_ExecuteProgram functions
qbool(* load_edict)(struct prvm_prog_s *prog, prvm_edict_t *ent)
[INIT] used by PRVM_ED_LoadFromFile
const char ** knownstrings_origin
sizebuf_t tempstringsbuf
buffer for storing all tempstrings created during one invocation of ExecuteProgram
int firstfreeknownstring
this is updated whenever a string is removed or added (simple optimization of the free string search)
const char * openfiles_origin[PRVM_MAX_OPENFILES]
prvm_prog_garbagecollection_state_t gc
garbage collection status
int numexplicitcoveragestatements
prvm_eval_t watch_edictfield_value
void(* init_cmd)(struct prvm_prog_s *prog)
[INIT] used by PRVM_InitProg
union prvm_prog_t::@31 globals
double profiletime
system time when last PRVM_CallProfile was called (or PRVM_Prog_Load initially)
int * statement_columnnums
NULL if not available.
void(* end_increase_edicts)(struct prvm_prog_s *prog)
[INIT]
double starttime
system time when PRVM_Prog_Load was called
int reserved_edicts
number of reserved edicts (allocated from 1)
double Sys_DirtyTime(void)
int Sys_CheckParm(const char *parm)
size_t Mem_ExpandableArray_IndexRange(const memexpandablearray_t *l)
void Mem_ExpandableArray_NewArray(memexpandablearray_t *l, mempool_t *mempool, size_t recordsize, int numrecordsperarray)
void * Mem_ExpandableArray_RecordAtIndex(const memexpandablearray_t *l, size_t index)
#define Mem_FreePool(pool)
#define Mem_Alloc(pool, size)
#define Mem_Realloc(pool, data, size)