2 // Basically every vm builtin cmd should be in here.
3 // All 3 builtin and extension lists can be found here
4 // cause large (I think they will) parts are from pr_cmds the same copyright like in pr_cmds
9 ============================================================================
13 checkextension(string)
18 sprint(float clientnum,...[string])
19 centerprint(...[string])
20 vector normalize(vector)
22 float vectoyaw(vector)
23 vector vectoangles(vector)
27 cvar_set (string,string)
33 float stof(...[string])
36 entity find(entity start, .string field, string match)
38 entity findfloat(entity start, .float field, float match)
39 entity findentity(entity start, .entity field, entity match)
41 entity findchain(.string field, string match)
43 entity findchainfloat(.string field, float match)
44 entity findchainentity(.string field, entity match)
46 string precache_file(string)
47 string precache_sound (string sample)
55 entity nextent(entity)
60 float registercvar (string name, string value, float flags)
61 float min(float a, float b, ...[float])
62 float max(float a, float b, ...[float])
63 float bound(float min, float value, float max)
64 float pow(float a, float b)
65 copyentity(entity src, entity dst)
66 float fopen(string filename, float mode)
68 string fgets(float fhandle)
69 fputs(float fhandle, string s)
70 float strlen(string s)
71 string strcat(string,string,...[string])
72 string substring(string s, float start, float length)
74 string strzone(string s)
76 float tokenize(string s)
81 clientcommand(float client, string s) (for client and menu)
82 changelevel(string map)
83 localsound(string sample)
86 loadfromdata(string data)
87 loadfromfile(string file)
88 float mod(float val, float m)
89 const string str_cvar (string)
93 float search_begin(string pattern, float caseinsensitive, float quiet)
94 void search_end(float handle)
95 float search_getsize(float handle)
96 string search_getfilename(float handle, float num)
98 string chr(float ascii)
100 perhaps only : Menu : WriteMsg
101 ===============================
103 WriteByte(float data, float dest, float desto)
104 WriteChar(float data, float dest, float desto)
105 WriteShort(float data, float dest, float desto)
106 WriteLong(float data, float dest, float desto)
107 WriteAngle(float data, float dest, float desto)
108 WriteCoord(float data, float dest, float desto)
109 WriteString(string data, float dest, float desto)
110 WriteEntity(entity data, float dest, float desto)
112 Client & Menu : draw functions
113 ===============================
115 float iscachedpic(string pic)
116 string precache_pic(string pic)
118 float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
119 float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
120 float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
121 float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
122 drawsetcliparea(float x, float y, float width, float height)
124 vector getimagesize(string pic)
127 ==============================================================================
131 setkeydest(float dest)
133 setmousetarget(float target)
134 float getmousetarget(void)
136 callfunction(...,string function_name)
137 writetofile(float fhandle, entity ent)
138 float isfunction(string function_name)
139 vector getresolution(float number)
140 string keynumtostring(float keynum)
141 string findkeysforcommand(string command)
142 float gethostcachevalue(float type)
143 string gethostcachestring(float type, float hostnr)
148 #include "quakedef.h"
149 #include "progdefs.h"
150 #include "clprogdefs.h"
151 #include "mprogdefs.h"
153 //============================================================================
154 // nice helper macros
156 #ifndef VM_NOPARMCHECK
157 #define VM_SAFEPARMCOUNT(p,f) if(prog->argc != p) PRVM_ERROR(#f " wrong parameter count (" #p " expected ) !\n")
159 #define VM_SAFEPARMCOUNT(p,f)
162 #define VM_RETURN_EDICT(e) (((int *)prog->globals)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
164 #define VM_STRINGS_MEMPOOL vm_strings_mempool[PRVM_GetProgNr()]
166 #define e10 0,0,0,0,0,0,0,0,0,0
167 #define e100 e10,e10,e10,e10,e10,e10,e10,e10,e10,e10
168 #define e1000 e100,e100,e100,e100,e100,e100,e100,e100,e100,e100
170 //============================================================================
173 // string zone mempool
174 mempool_t *vm_strings_mempool[PRVM_MAXPROGS];
176 // temp string handling
177 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
178 #define VM_STRINGTEMP_BUFFERS 16
179 #define VM_STRINGTEMP_LENGTH 4096
180 static char vm_string_temp[VM_STRINGTEMP_BUFFERS][VM_STRINGTEMP_LENGTH];
181 static int vm_string_tempindex = 0;
184 #define MAX_QC_CVARS 128 * PRVM_MAXPROGS
185 cvar_t vm_qc_cvar[MAX_QC_CVARS];
186 int vm_currentqc_cvar;
189 #define MAX_VMFILES 256
190 #define MAX_PRVMFILES MAX_VMFILES * PRVM_MAXPROGS
191 #define VM_FILES ((qfile_t**)(vm_files + PRVM_GetProgNr() * MAX_VMFILES))
193 qfile_t *vm_files[MAX_PRVMFILES];
195 // qc fs search handling
196 #define MAX_VMSEARCHES 128
197 #define TOTAL_VMSEARCHES MAX_VMSEARCHES * PRVM_MAXPROGS
198 #define VM_SEARCHLIST ((fssearch_t**)(vm_fssearchlist + PRVM_GetProgNr() * MAX_VMSEARCHES))
200 fssearch_t *vm_fssearchlist[TOTAL_VMSEARCHES];
202 static char *VM_GetTempString(void)
205 s = vm_string_temp[vm_string_tempindex];
206 vm_string_tempindex = (vm_string_tempindex + 1) % VM_STRINGTEMP_BUFFERS;
210 void VM_CheckEmptyString (char *s)
213 PRVM_ERROR ("%s: Bad string", PRVM_NAME);
216 //============================================================================
219 void VM_VarString(int first, char *out, int outlength)
225 outend = out + outlength - 1;
226 for (i = first;i < prog->argc && out < outend;i++)
228 s = PRVM_G_STRING((OFS_PARM0+i*3));
229 while (out < outend && *s)
239 returns true if the extension is supported by the server
241 checkextension(extensionname)
245 // kind of helper function
246 static qboolean checkextension(char *name)
252 for (e = prog->extensionstring;*e;e++)
259 while (*e && *e != ' ')
261 if (e - start == len)
262 if (!strncasecmp(start, name, len))
270 void VM_checkextension (void)
272 VM_SAFEPARMCOUNT(1,VM_checkextension);
274 PRVM_G_FLOAT(OFS_RETURN) = checkextension(PRVM_G_STRING(OFS_PARM0));
281 This is a TERMINAL error, which will kill off the entire prog.
290 char string[VM_STRINGTEMP_LENGTH];
292 VM_VarString(0, string, sizeof(string));
293 Con_Printf("======%S ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
296 ed = PRVM_G_EDICT(prog->self->ofs);
300 PRVM_ERROR ("%s: Program error", PRVM_NAME);
307 Dumps out self, then an error message. The program is aborted and self is
308 removed, but the level can continue.
313 void VM_objerror (void)
316 char string[VM_STRINGTEMP_LENGTH];
318 VM_VarString(0, string, sizeof(string));
319 Con_Printf("======%s OBJECT ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
322 ed = PRVM_G_EDICT (prog->self->ofs);
328 // objerror has to display the object fields -> else call
329 PRVM_ERROR ("VM_objecterror: self not defined !\n");
334 VM_print (actually used only by client and menu)
343 char string[VM_STRINGTEMP_LENGTH];
345 VM_VarString(0, string, sizeof(string));
353 broadcast print to everyone on server
358 void VM_bprint (void)
360 char string[VM_STRINGTEMP_LENGTH];
364 Con_Printf("VM_bprint: game is not server(%s) !\n", PRVM_NAME);
368 VM_VarString(0, string, sizeof(string));
369 SV_BroadcastPrint(string);
374 VM_sprint (menu & client but only if server.active == true)
376 single print to a specific client
378 sprint(float clientnum,...[string])
381 void VM_sprint (void)
385 char string[VM_STRINGTEMP_LENGTH];
387 //find client for this entity
388 clientnum = PRVM_G_FLOAT(OFS_PARM0);
389 if (!sv.active || clientnum < 0 || clientnum >= svs.maxclients || !svs.clients[clientnum].active)
391 Con_Printf("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME);
395 client = svs.clients + clientnum;
396 if (!client->netconnection)
398 VM_VarString(1, string, sizeof(string));
399 MSG_WriteChar(&client->message,svc_print);
400 MSG_WriteString(&client->message, string);
407 single print to the screen
409 centerprint(clientent, value)
412 void VM_centerprint (void)
414 char string[VM_STRINGTEMP_LENGTH];
416 VM_VarString(0, string, sizeof(string));
417 SCR_CenterPrint(string);
424 vector normalize(vector)
427 void VM_normalize (void)
433 VM_SAFEPARMCOUNT(1,VM_normalize);
435 value1 = PRVM_G_VECTOR(OFS_PARM0);
437 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
441 newvalue[0] = newvalue[1] = newvalue[2] = 0;
445 newvalue[0] = value1[0] * new;
446 newvalue[1] = value1[1] * new;
447 newvalue[2] = value1[2] * new;
450 VectorCopy (newvalue, PRVM_G_VECTOR(OFS_RETURN));
465 VM_SAFEPARMCOUNT(1,VM_vlen);
467 value1 = PRVM_G_VECTOR(OFS_PARM0);
469 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
472 PRVM_G_FLOAT(OFS_RETURN) = new;
479 float vectoyaw(vector)
482 void VM_vectoyaw (void)
487 VM_SAFEPARMCOUNT(1,VM_vectoyaw);
489 value1 = PRVM_G_VECTOR(OFS_PARM0);
491 if (value1[1] == 0 && value1[0] == 0)
495 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
500 PRVM_G_FLOAT(OFS_RETURN) = yaw;
508 vector vectoangles(vector)
511 void VM_vectoangles (void)
517 VM_SAFEPARMCOUNT(1,VM_vectoangles);
519 value1 = PRVM_G_VECTOR(OFS_PARM0);
521 if (value1[1] == 0 && value1[0] == 0)
531 // LordHavoc: optimized a bit
534 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
538 else if (value1[1] > 0)
543 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
544 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
549 PRVM_G_FLOAT(OFS_RETURN+0) = pitch;
550 PRVM_G_FLOAT(OFS_RETURN+1) = yaw;
551 PRVM_G_FLOAT(OFS_RETURN+2) = 0;
558 Returns a number from 0<= num < 1
563 void VM_random (void)
567 VM_SAFEPARMCOUNT(0,VM_random);
569 num = (rand ()&0x7fff) / ((float)0x7fff);
571 PRVM_G_FLOAT(OFS_RETURN) = num;
578 Each entity can have eight independant sound sources, like voice,
581 Channel 0 is an auto-allocate channel, the others override anything
582 already running on that entity/channel pair.
584 An attenuation of 0 will play full volume everywhere in the level.
585 Larger attenuations will drop off.
598 entity = G_EDICT(OFS_PARM0);
599 channel = G_FLOAT(OFS_PARM1);
600 sample = G_STRING(OFS_PARM2);
601 volume = G_FLOAT(OFS_PARM3) * 255;
602 attenuation = G_FLOAT(OFS_PARM4);
604 if (volume < 0 || volume > 255)
605 Host_Error ("SV_StartSound: volume = %i", volume);
607 if (attenuation < 0 || attenuation > 4)
608 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
610 if (channel < 0 || channel > 7)
611 Host_Error ("SV_StartSound: channel = %i", channel);
613 SV_StartSound (entity, channel, sample, volume, attenuation);
621 localsound(string sample)
624 void VM_localsound(void)
628 VM_SAFEPARMCOUNT(1,VM_localsound);
630 s = PRVM_G_STRING(OFS_PARM0);
632 if(!S_GetCached(s, true))
634 Con_Printf("VM_localsound: %s : %s not cached !\n", PRVM_NAME, s);
635 PRVM_G_FLOAT(OFS_RETURN) = -4;
639 S_LocalSound(s, true);
640 PRVM_G_FLOAT(OFS_RETURN) = 1;
652 PRVM_ERROR ("%s: break statement", PRVM_NAME);
655 //============================================================================
661 Sends text over to the client's execution buffer
663 [localcmd (string) or]
667 void VM_localcmd (void)
669 VM_SAFEPARMCOUNT(1,VM_localcmd);
671 Cbuf_AddText(PRVM_G_STRING(OFS_PARM0));
683 VM_SAFEPARMCOUNT(1,VM_cvar);
685 PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0));
692 const string str_cvar (string)
695 void VM_str_cvar(void)
698 const char *cvar_string;
699 VM_SAFEPARMCOUNT(1,VM_str_cvar);
701 name = PRVM_G_STRING(OFS_PARM0);
704 PRVM_ERROR("VM_str_cvar: %s: null string\n", PRVM_NAME);
706 VM_CheckEmptyString(name);
708 out = VM_GetTempString();
710 cvar_string = Cvar_VariableString(name);
712 strcpy(out, cvar_string);
714 PRVM_G_INT(OFS_PARM0) = PRVM_SetString(out);
721 void cvar_set (string,string)
724 void VM_cvar_set (void)
726 VM_SAFEPARMCOUNT(2,VM_cvar_set);
728 Cvar_Set(PRVM_G_STRING(OFS_PARM0), PRVM_G_STRING(OFS_PARM1));
738 void VM_dprint (void)
740 char string[VM_STRINGTEMP_LENGTH];
741 if (developer.integer)
743 VM_VarString(0, string, sizeof(string));
744 Con_Printf("%s: %s", PRVM_NAME, string);
761 VM_SAFEPARMCOUNT(1, VM_ftos);
763 v = PRVM_G_FLOAT(OFS_PARM0);
765 s = VM_GetTempString();
766 if ((float)((int)v) == v)
767 sprintf(s, "%i", (int)v);
770 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
785 VM_SAFEPARMCOUNT(1,VM_fabs);
787 v = PRVM_G_FLOAT(OFS_PARM0);
788 PRVM_G_FLOAT(OFS_RETURN) = fabs(v);
803 VM_SAFEPARMCOUNT(1,VM_vtos);
805 s = VM_GetTempString();
806 sprintf (s, "'%5.1f %5.1f %5.1f'", PRVM_G_VECTOR(OFS_PARM0)[0], PRVM_G_VECTOR(OFS_PARM0)[1], PRVM_G_VECTOR(OFS_PARM0)[2]);
807 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
822 VM_SAFEPARMCOUNT(1, VM_etos);
824 s = VM_GetTempString();
825 sprintf (s, "entity %i", PRVM_G_EDICTNUM(OFS_PARM0));
826 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
833 float stof(...[string])
838 char string[VM_STRINGTEMP_LENGTH];
839 VM_VarString(0, string, sizeof(string));
840 PRVM_G_FLOAT(OFS_RETURN) = atof(string);
854 prog->xfunction->builtinsprofile += 20;
855 ed = PRVM_ED_Alloc();
867 void VM_remove (void)
870 prog->xfunction->builtinsprofile += 20;
872 VM_SAFEPARMCOUNT(1, VM_remove);
874 ed = PRVM_G_EDICT(OFS_PARM0);
875 // if (ed == prog->edicts)
876 // PRVM_ERROR ("remove: tried to remove world\n");
877 // if (PRVM_NUM_FOR_EDICT(ed) <= sv.maxclients)
878 // Host_Error("remove: tried to remove a client\n");
886 entity find(entity start, .string field, string match)
897 VM_SAFEPARMCOUNT(3,VM_find);
899 e = PRVM_G_EDICTNUM(OFS_PARM0);
900 f = PRVM_G_INT(OFS_PARM1);
901 s = PRVM_G_STRING(OFS_PARM2);
905 // return reserved edict 0 (could be used for whatever the prog wants)
906 VM_RETURN_EDICT(prog->edicts);
910 for (e++ ; e < prog->num_edicts ; e++)
912 prog->xfunction->builtinsprofile++;
913 ed = PRVM_EDICT_NUM(e);
916 t = PRVM_E_STRING(ed,f);
926 VM_RETURN_EDICT(prog->edicts);
933 entity findfloat(entity start, .float field, float match)
934 entity findentity(entity start, .entity field, entity match)
937 // LordHavoc: added this for searching float, int, and entity reference fields
938 void VM_findfloat (void)
945 VM_SAFEPARMCOUNT(3,VM_findfloat);
947 e = PRVM_G_EDICTNUM(OFS_PARM0);
948 f = PRVM_G_INT(OFS_PARM1);
949 s = PRVM_G_FLOAT(OFS_PARM2);
951 for (e++ ; e < prog->num_edicts ; e++)
953 prog->xfunction->builtinsprofile++;
954 ed = PRVM_EDICT_NUM(e);
957 if (PRVM_E_FLOAT(ed,f) == s)
964 VM_RETURN_EDICT(prog->edicts);
971 entity findchain(.string field, string match)
974 int PRVM_ED_FindFieldOffset(const char *field);
975 // chained search for strings in entity fields
976 // entity(.string field, string match) findchain = #402;
977 void VM_findchain (void)
983 prvm_edict_t *ent, *chain;
985 VM_SAFEPARMCOUNT(2,VM_findchain);
987 // is the same like !(prog->flag & PRVM_FE_CHAIN) - even if the operator precedence is another
988 if(!prog->flag & PRVM_FE_CHAIN)
989 PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
991 chain_of = PRVM_ED_FindFieldOffset ("chain");
993 chain = prog->edicts;
995 f = PRVM_G_INT(OFS_PARM0);
996 s = PRVM_G_STRING(OFS_PARM1);
999 VM_RETURN_EDICT(prog->edicts);
1003 ent = PRVM_NEXT_EDICT(prog->edicts);
1004 for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
1006 prog->xfunction->builtinsprofile++;
1009 t = PRVM_E_STRING(ent,f);
1015 PRVM_E_FLOAT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
1019 VM_RETURN_EDICT(chain);
1026 entity findchainfloat(.string field, float match)
1027 entity findchainentity(.string field, entity match)
1030 // LordHavoc: chained search for float, int, and entity reference fields
1031 // entity(.string field, float match) findchainfloat = #403;
1032 void VM_findchainfloat (void)
1038 prvm_edict_t *ent, *chain;
1040 VM_SAFEPARMCOUNT(2, VM_findchainfloat);
1042 if(!prog->flag & PRVM_FE_CHAIN)
1043 PRVM_ERROR("VM_findchainfloat: %s doesnt have a chain field !\n", PRVM_NAME);
1045 chain_of = PRVM_ED_FindFieldOffset ("chain");
1047 chain = (prvm_edict_t *)prog->edicts;
1049 f = PRVM_G_INT(OFS_PARM0);
1050 s = PRVM_G_FLOAT(OFS_PARM1);
1052 ent = PRVM_NEXT_EDICT(prog->edicts);
1053 for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
1055 prog->xfunction->builtinsprofile++;
1058 if (E_FLOAT(ent,f) != s)
1061 PRVM_E_FLOAT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
1065 VM_RETURN_EDICT(chain);
1072 string precache_file(string)
1075 void VM_precache_file (void)
1076 { // precache_file is only used to copy files with qcc, it does nothing
1077 VM_SAFEPARMCOUNT(1,VM_precache_file);
1079 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1086 used instead of the other VM_precache_* functions in the builtin list
1090 void VM_precache_error (void)
1092 PRVM_ERROR ("PF_Precache_*: Precache can only be done in spawn functions");
1099 string precache_sound (string sample)
1102 void VM_precache_sound (void)
1106 VM_SAFEPARMCOUNT(1, VM_precache_sound);
1108 s = PRVM_G_STRING(OFS_PARM0);
1109 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1110 VM_CheckEmptyString (s);
1112 if(S_GetCached(s, true))
1114 Con_Printf("VM_precache_sound: %s already cached (%s)\n", s, PRVM_NAME);
1118 if(!S_PrecacheSound(s,true, true))
1119 Con_Printf("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
1129 void VM_coredump (void)
1131 VM_SAFEPARMCOUNT(0,VM_coredump);
1133 Cbuf_AddText("prvm_edicts ");
1134 Cbuf_AddText(PRVM_NAME);
1145 void PRVM_StackTrace(void);
1146 void VM_stackdump (void)
1148 VM_SAFEPARMCOUNT(0, VM_stackdump);
1163 VM_SAFEPARMCOUNT(0, VM_crash);
1165 PRVM_ERROR("Crash called by %s\n",PRVM_NAME);
1175 void VM_traceon (void)
1177 VM_SAFEPARMCOUNT(0,VM_traceon);
1189 void VM_traceoff (void)
1191 VM_SAFEPARMCOUNT(0,VM_traceoff);
1193 prog->trace = false;
1203 void VM_eprint (void)
1205 VM_SAFEPARMCOUNT(1,VM_eprint);
1207 PRVM_ED_PrintNum (PRVM_G_EDICTNUM(OFS_PARM0));
1221 VM_SAFEPARMCOUNT(1,VM_rint);
1223 f = PRVM_G_FLOAT(OFS_PARM0);
1225 PRVM_G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1227 PRVM_G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1237 void VM_floor (void)
1239 VM_SAFEPARMCOUNT(1,VM_floor);
1241 PRVM_G_FLOAT(OFS_RETURN) = floor(PRVM_G_FLOAT(OFS_PARM0));
1253 VM_SAFEPARMCOUNT(1,VM_ceil);
1255 PRVM_G_FLOAT(OFS_RETURN) = ceil(PRVM_G_FLOAT(OFS_PARM0));
1263 entity nextent(entity)
1266 void VM_nextent (void)
1271 i = PRVM_G_EDICTNUM(OFS_PARM0);
1274 prog->xfunction->builtinsprofile++;
1276 if (i == prog->num_edicts)
1278 VM_RETURN_EDICT(prog->edicts);
1281 ent = PRVM_EDICT_NUM(i);
1284 VM_RETURN_EDICT(ent);
1291 ===============================================================================
1294 used only for client and menu
1295 severs uses VM_SV_...
1297 Write*(* data, float type, float to)
1299 ===============================================================================
1302 #define MSG_BROADCAST 0 // unreliable to all
1303 #define MSG_ONE 1 // reliable to one (msg_entity)
1304 #define MSG_ALL 2 // reliable to all
1305 #define MSG_INIT 3 // write to the init string
1307 sizebuf_t *VM_WriteDest (void)
1313 PRVM_ERROR("VM_WriteDest: game is not server (%s)\n", PRVM_NAME);
1315 dest = G_FLOAT(OFS_PARM1);
1319 return &sv.datagram;
1322 destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
1323 if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active)
1324 PRVM_ERROR("VM_clientcommand: %s: invalid client !\n", PRVM_NAME);
1326 return &svs.clients[destclient].message;
1329 return &sv.reliable_datagram;
1335 PRVM_ERROR ("WriteDest: bad destination");
1342 void VM_WriteByte (void)
1344 MSG_WriteByte (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1347 void VM_WriteChar (void)
1349 MSG_WriteChar (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1352 void VM_WriteShort (void)
1354 MSG_WriteShort (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1357 void VM_WriteLong (void)
1359 MSG_WriteLong (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1362 void VM_WriteAngle (void)
1364 MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1367 void VM_WriteCoord (void)
1369 MSG_WriteDPCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1372 void VM_WriteString (void)
1374 MSG_WriteString (VM_WriteDest(), PRVM_G_STRING(OFS_PARM0));
1377 void VM_WriteEntity (void)
1379 MSG_WriteShort (VM_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
1382 //=============================================================================
1389 changelevel(string map)
1392 void VM_changelevel (void)
1396 VM_SAFEPARMCOUNT(1, VM_changelevel);
1400 Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME);
1404 // make sure we don't issue two changelevels
1405 if (svs.changelevel_issued)
1407 svs.changelevel_issued = true;
1409 s = G_STRING(OFS_PARM0);
1410 Cbuf_AddText (va("changelevel %s\n",s));
1422 VM_SAFEPARMCOUNT(1,VM_sin);
1423 PRVM_G_FLOAT(OFS_RETURN) = sin(PRVM_G_FLOAT(OFS_PARM0));
1434 VM_SAFEPARMCOUNT(1,VM_cos);
1435 PRVM_G_FLOAT(OFS_RETURN) = cos(PRVM_G_FLOAT(OFS_PARM0));
1447 VM_SAFEPARMCOUNT(1,VM_sqrt);
1448 PRVM_G_FLOAT(OFS_RETURN) = sqrt(PRVM_G_FLOAT(OFS_PARM0));
1455 Returns a vector of length < 1 and > 0
1460 void VM_randomvec (void)
1465 VM_SAFEPARMCOUNT(0, VM_randomvec);
1470 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1471 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1472 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1474 while (DotProduct(temp, temp) >= 1);
1475 VectorCopy (temp, PRVM_G_VECTOR(OFS_RETURN));
1478 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1479 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1480 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1481 // length returned always > 0
1482 length = (rand()&32766 + 1) * (1.0 / 32767.0) / VectorLength(temp);
1483 VectorScale(temp,length, temp);*/
1484 //VectorCopy(temp, PRVM_G_VECTOR(OFS_RETURN));
1487 //=============================================================================
1493 float registercvar (string name, string value, float flags)
1496 void VM_registercvar (void)
1502 VM_SAFEPARMCOUNT(3,VM_registercvar);
1504 name = PRVM_G_STRING(OFS_PARM0);
1505 value = PRVM_G_STRING(OFS_PARM1);
1506 flags = PRVM_G_FLOAT(OFS_PARM2);
1507 PRVM_G_FLOAT(OFS_RETURN) = 0;
1509 if(flags > CVAR_MAXFLAGSVAL)
1512 // first check to see if it has already been defined
1513 if (Cvar_FindVar (name))
1516 // check for overlap with a command
1517 if (Cmd_Exists (name))
1519 Con_Printf("VM_registercvar: %s is a command\n", name);
1523 if (vm_currentqc_cvar >= MAX_QC_CVARS)
1524 PRVM_ERROR ("VM_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
1526 // copy the name and value
1527 variable = &vm_qc_cvar[vm_currentqc_cvar++];
1528 variable->flags = flags;
1529 variable->name = Z_Malloc (strlen(name)+1);
1530 strcpy (variable->name, name);
1531 variable->string = Z_Malloc (strlen(value)+1);
1532 strcpy (variable->string, value);
1533 variable->value = atof (value);
1535 Cvar_RegisterVariable(variable);
1536 PRVM_G_FLOAT(OFS_RETURN) = 1; // success
1543 returns the minimum of two supplied floats
1545 float min(float a, float b, ...[float])
1550 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1551 if (prog->argc == 2)
1552 PRVM_G_FLOAT(OFS_RETURN) = min(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
1553 else if (prog->argc >= 3)
1556 float f = PRVM_G_FLOAT(OFS_PARM0);
1557 for (i = 1;i < prog->argc;i++)
1558 if (PRVM_G_FLOAT((OFS_PARM0+i*3)) < f)
1559 f = PRVM_G_FLOAT((OFS_PARM0+i*3));
1560 PRVM_G_FLOAT(OFS_RETURN) = f;
1563 PRVM_ERROR("VM_min: %s must supply at least 2 floats\n", PRVM_NAME);
1570 returns the maximum of two supplied floats
1572 float max(float a, float b, ...[float])
1577 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1578 if (prog->argc == 2)
1579 PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
1580 else if (prog->argc >= 3)
1583 float f = PRVM_G_FLOAT(OFS_PARM0);
1584 for (i = 1;i < prog->argc;i++)
1585 if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f)
1586 f = PRVM_G_FLOAT((OFS_PARM0+i*3));
1587 G_FLOAT(OFS_RETURN) = f;
1590 PRVM_ERROR("VM_max: %s must supply at least 2 floats\n", PRVM_NAME);
1597 returns number bounded by supplied range
1599 float bound(float min, float value, float max)
1602 void VM_bound (void)
1604 VM_SAFEPARMCOUNT(3,VM_bound);
1605 PRVM_G_FLOAT(OFS_RETURN) = bound(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1), PRVM_G_FLOAT(OFS_PARM2));
1612 returns a raised to power b
1614 float pow(float a, float b)
1619 VM_SAFEPARMCOUNT(2,VM_pow);
1620 PRVM_G_FLOAT(OFS_RETURN) = pow(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
1627 copies data from one entity to another
1629 copyentity(entity src, entity dst)
1632 void VM_copyentity (void)
1634 prvm_edict_t *in, *out;
1635 VM_SAFEPARMCOUNT(2,VM_copyentity);
1636 in = PRVM_G_EDICT(OFS_PARM0);
1637 out = PRVM_G_EDICT(OFS_PARM1);
1638 memcpy(out->v, in->v, prog->progs->entityfields * 4);
1645 sets the color of a client and broadcasts the update to all connected clients
1647 setcolor(clientent, value)
1650 /*void PF_setcolor (void)
1656 entnum = G_EDICTNUM(OFS_PARM0);
1657 i = G_FLOAT(OFS_PARM1);
1659 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1661 Con_Print("tried to setcolor a non-client\n");
1665 client = svs.clients + entnum-1;
1666 if ((val = GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
1669 client->old_colors = i;
1670 client->edict->v->team = (i & 15) + 1;
1672 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1673 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
1674 MSG_WriteByte (&sv.reliable_datagram, i);
1677 void VM_Files_Init(void)
1679 memset(VM_FILES, 0, sizeof(qfile_t*[MAX_VMFILES]));
1682 void VM_Files_CloseAll(void)
1685 for (i = 0;i < MAX_VMFILES;i++)
1688 FS_Close(VM_FILES[i]);
1689 //VM_FILES[i] = NULL;
1691 memset(VM_FILES,0,sizeof(qfile_t*[MAX_VMFILES])); // this should be faster (is it ?)
1698 float fopen(string filename, float mode)
1701 // float(string filename, float mode) fopen = #110;
1702 // opens a file inside quake/gamedir/data/ (mode is FILE_READ, FILE_APPEND, or FILE_WRITE),
1703 // returns fhandle >= 0 if successful, or fhandle < 0 if unable to open file for any reason
1707 char *modestring, *filename;
1709 VM_SAFEPARMCOUNT(2,VM_fopen);
1711 for (filenum = 0;filenum < MAX_VMFILES;filenum++)
1712 if (VM_FILES[filenum] == NULL)
1714 if (filenum >= MAX_VMFILES)
1716 Con_Printf("VM_fopen: %s ran out of file handles (%i)\n", PRVM_NAME, MAX_VMFILES);
1717 PRVM_G_FLOAT(OFS_RETURN) = -2;
1720 mode = PRVM_G_FLOAT(OFS_PARM1);
1723 case 0: // FILE_READ
1726 case 1: // FILE_APPEND
1729 case 2: // FILE_WRITE
1733 Con_Printf("VM_fopen: %s no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode);
1734 PRVM_G_FLOAT(OFS_RETURN) = -3;
1737 filename = PRVM_G_STRING(OFS_PARM0);
1738 // .. is parent directory on many platforms
1739 // / is parent directory on Amiga
1740 // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea)
1741 // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
1742 if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
1744 Con_Printf("VM_fopen: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
1745 PRVM_G_FLOAT(OFS_RETURN) = -4;
1748 VM_FILES[filenum] = FS_Open(va("data/%s", filename), modestring, false);
1749 if (VM_FILES[filenum] == NULL && mode == 0)
1750 VM_FILES[filenum] = FS_Open(va("%s", filename), modestring, false);
1752 if (VM_FILES[filenum] == NULL)
1753 PRVM_G_FLOAT(OFS_RETURN) = -1;
1755 PRVM_G_FLOAT(OFS_RETURN) = filenum;
1762 fclose(float fhandle)
1765 //void(float fhandle) fclose = #111; // closes a file
1766 void VM_fclose(void)
1770 VM_SAFEPARMCOUNT(1,VM_fclose);
1772 filenum = PRVM_G_FLOAT(OFS_PARM0);
1773 if (filenum < 0 || filenum >= MAX_VMFILES)
1775 Con_Printf("VM_fclose: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
1778 if (VM_FILES[filenum] == NULL)
1780 Con_Printf("VM_fclose: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
1783 FS_Close(VM_FILES[filenum]);
1784 VM_FILES[filenum] = NULL;
1791 string fgets(float fhandle)
1794 //string(float fhandle) fgets = #112; // reads a line of text from the file and returns as a tempstring
1798 static char string[VM_STRINGTEMP_LENGTH];
1801 VM_SAFEPARMCOUNT(1,VM_fgets);
1803 filenum = PRVM_G_FLOAT(OFS_PARM0);
1804 if (filenum < 0 || filenum >= MAX_VMFILES)
1806 Con_Printf("VM_fgets: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
1809 if (VM_FILES[filenum] == NULL)
1811 Con_Printf("VM_fgets: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
1817 c = FS_Getc(VM_FILES[filenum]);
1818 if (c == '\r' || c == '\n' || c < 0)
1820 if (end < VM_STRINGTEMP_LENGTH - 1)
1824 // remove \n following \r
1826 c = FS_Getc(VM_FILES[filenum]);
1827 if (developer.integer)
1828 Con_Printf("fgets: %s: %s\n", PRVM_NAME, string);
1830 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string);
1832 PRVM_G_INT(OFS_RETURN) = 0;
1839 fputs(float fhandle, string s)
1842 //void(float fhandle, string s) fputs = #113; // writes a line of text to the end of the file
1846 char string[VM_STRINGTEMP_LENGTH];
1849 VM_SAFEPARMCOUNT(2,VM_fputs);
1851 filenum = PRVM_G_FLOAT(OFS_PARM0);
1852 if (filenum < 0 || filenum >= MAX_VMFILES)
1854 Con_Printf("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
1857 if (VM_FILES[filenum] == NULL)
1859 Con_Printf("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
1862 VM_VarString(1, string, sizeof(string));
1863 if ((stringlength = strlen(string)))
1864 FS_Write(VM_FILES[filenum], string, stringlength);
1865 if (developer.integer)
1866 Con_Printf("fputs: %s: %s\n", PRVM_NAME, string);
1873 float strlen(string s)
1876 //float(string s) strlen = #114; // returns how many characters are in a string
1877 void VM_strlen(void)
1881 VM_SAFEPARMCOUNT(1,VM_strlen);
1883 s = PRVM_G_STRING(OFS_PARM0);
1885 PRVM_G_FLOAT(OFS_RETURN) = strlen(s);
1887 PRVM_G_FLOAT(OFS_RETURN) = 0;
1894 string strcat(string,string,...[string])
1897 //string(string s1, string s2) strcat = #115;
1898 // concatenates two strings (for example "abc", "def" would return "abcdef")
1899 // and returns as a tempstring
1900 void VM_strcat(void)
1905 PRVM_ERROR("VM_strcat wrong parameter count (min. 2 expected ) !\n");
1907 s = VM_GetTempString();
1908 VM_VarString(0, s, VM_STRINGTEMP_LENGTH);
1909 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
1916 string substring(string s, float start, float length)
1919 // string(string s, float start, float length) substring = #116;
1920 // returns a section of a string as a tempstring
1921 void VM_substring(void)
1923 int i, start, length;
1926 VM_SAFEPARMCOUNT(3,VM_substring);
1928 string = VM_GetTempString();
1929 s = PRVM_G_STRING(OFS_PARM0);
1930 start = PRVM_G_FLOAT(OFS_PARM1);
1931 length = PRVM_G_FLOAT(OFS_PARM2);
1934 for (i = 0;i < start && *s;i++, s++);
1935 for (i = 0;i < VM_STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++)
1938 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string);
1945 vector stov(string s)
1948 //vector(string s) stov = #117; // returns vector value from a string
1951 char string[VM_STRINGTEMP_LENGTH];
1953 VM_SAFEPARMCOUNT(1,VM_stov);
1955 VM_VarString(0, string, sizeof(string));
1956 Math_atov(string, PRVM_G_VECTOR(OFS_RETURN));
1963 string strzone(string s)
1966 //string(string s) strzone = #118; // makes a copy of a string into the string zone and returns it, this is often used to keep around a tempstring for longer periods of time (tempstrings are replaced often)
1967 void VM_strzone(void)
1971 VM_SAFEPARMCOUNT(1,VM_strzone);
1973 in = PRVM_G_STRING(OFS_PARM0);
1974 out = Mem_Alloc(VM_STRINGS_MEMPOOL, strlen(in) + 1);
1976 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(out);
1986 //void(string s) strunzone = #119; // removes a copy of a string from the string zone (you can not use that string again or it may crash!!!)
1987 void VM_strunzone(void)
1989 VM_SAFEPARMCOUNT(1,VM_strunzone);
1991 Mem_Free(PRVM_G_STRING(OFS_PARM0));
1996 VM_command (used by client and menu)
1998 clientcommand(float client, string s) (for client and menu)
2001 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
2002 //this function originally written by KrimZon, made shorter by LordHavoc
2003 void VM_clcommand (void)
2005 client_t *temp_client;
2008 VM_SAFEPARMCOUNT(2,VM_clcommand);
2010 i = PRVM_G_FLOAT(OFS_PARM0);
2011 if (!sv.active || i < 0 || i >= svs.maxclients || !svs.clients[i].active)
2013 Con_Printf("VM_clientcommand: %s: invalid client/server is not active !\n", PRVM_NAME);
2017 temp_client = host_client;
2018 host_client = svs.clients + i;
2019 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2020 host_client = temp_client;
2028 float tokenize(string s)
2031 //float(string s) tokenize = #441;
2032 // takes apart a string into individal words (access them with argv), returns how many
2033 // this function originally written by KrimZon, made shorter by LordHavoc
2034 static char **tokens = NULL;
2035 static int max_tokens, num_tokens = 0;
2036 void VM_tokenize (void)
2041 VM_SAFEPARMCOUNT(1,VM_tokenize);
2043 str = PRVM_G_STRING(OFS_PARM0);
2048 for (i=0;i<num_tokens;i++)
2054 tokens = Z_Malloc(strlen(str) * sizeof(char *));
2055 max_tokens = strlen(str);
2057 for (p = str;COM_ParseToken(&p, false) && num_tokens < max_tokens;num_tokens++)
2059 tokens[num_tokens] = Z_Malloc(strlen(com_token) + 1);
2060 strcpy(tokens[num_tokens], com_token);
2063 PRVM_G_FLOAT(OFS_RETURN) = num_tokens;
2070 string argv(float n)
2073 //string(float n) argv = #442;
2074 // returns a word from the tokenized string (returns nothing for an invalid index)
2075 // this function originally written by KrimZon, made shorter by LordHavoc
2080 VM_SAFEPARMCOUNT(1,VM_argv);
2082 token_num = PRVM_G_FLOAT(OFS_PARM0);
2083 if (token_num >= 0 && token_num < num_tokens)
2084 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tokens[token_num]);
2086 PRVM_G_INT(OFS_RETURN) = PRVM_SetString("");
2090 //void(entity e, entity tagentity, string tagname) setattachment = #443; // attachs e to a tag on tagentity (note: use "" to attach to entity origin/angles instead of a tag)
2091 void PF_setattachment (void)
2093 edict_t *e = G_EDICT(OFS_PARM0);
2094 edict_t *tagentity = G_EDICT(OFS_PARM1);
2095 char *tagname = G_STRING(OFS_PARM2);
2100 if (tagentity == NULL)
2101 tagentity = sv.edicts;
2103 v = GETEDICTFIELDVALUE(e, eval_tag_entity);
2105 v->edict = EDICT_TO_PROG(tagentity);
2107 v = GETEDICTFIELDVALUE(e, eval_tag_index);
2110 if (tagentity != NULL && tagentity != sv.edicts && tagname && tagname[0])
2112 modelindex = (int)tagentity->v->modelindex;
2113 if (modelindex >= 0 && modelindex < MAX_MODELS)
2115 model = sv.models[modelindex];
2116 if (model->data_overridetagnamesforskin && (unsigned int)tagentity->v->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames)
2117 for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++)
2118 if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name))
2120 // FIXME: use a model function to get tag info (need to handle skeletal)
2121 if (v->_float == 0 && model->alias.aliasnum_tags)
2122 for (i = 0;i < model->alias.aliasnum_tags;i++)
2123 if (!strcmp(tagname, model->alias.aliasdata_tags[i].name))
2126 Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity), model->name);
2129 Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", NUM_FOR_EDICT(e), NUM_FOR_EDICT(tagentity), tagname, tagname, NUM_FOR_EDICT(tagentity));
2140 void VM_isserver(void)
2142 VM_SAFEPARMCOUNT(0,VM_serverstate);
2144 PRVM_G_FLOAT(OFS_RETURN) = sv.active;
2154 void VM_clientcount(void)
2156 VM_SAFEPARMCOUNT(0,VM_clientcount);
2158 PRVM_G_FLOAT(OFS_RETURN) = svs.maxclients;
2168 void VM_clientstate(void)
2170 VM_SAFEPARMCOUNT(0,VM_clientstate);
2172 PRVM_G_FLOAT(OFS_RETURN) = cls.state;
2179 float getostype(void)
2181 */ // not used at the moment -> not included in the common list
2182 void VM_getostype(void)
2184 VM_SAFEPARMCOUNT(0,VM_getostype);
2189 OS_MAC - not supported
2193 PRVM_G_FLOAT(OFS_RETURN) = 0;
2195 PRVM_G_FLOAT(OFS_RETURN) = 2;
2197 PRVM_G_FLOAT(OFS_RETURN) = 1;
2205 vector getmousepos()
2208 void VM_getmousepos(void)
2211 VM_SAFEPARMCOUNT(0,VM_getmousepos);
2213 PRVM_G_VECTOR(OFS_RETURN)[0] = in_mouse_x;
2214 PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y;
2215 PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
2225 void VM_gettime(void)
2227 VM_SAFEPARMCOUNT(0,VM_gettime);
2229 PRVM_G_FLOAT(OFS_RETURN) = (float) *prog->time;
2236 loadfromdata(string data)
2239 void VM_loadfromdata(void)
2241 VM_SAFEPARMCOUNT(1,VM_loadentsfromfile);
2243 PRVM_ED_LoadFromFile(PRVM_G_STRING(OFS_PARM0));
2250 loadfromfile(string file)
2253 void VM_loadfromfile(void)
2258 VM_SAFEPARMCOUNT(1,VM_loadfromfile);
2260 filename = PRVM_G_STRING(OFS_PARM0);
2261 // .. is parent directory on many platforms
2262 // / is parent directory on Amiga
2263 // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea)
2264 // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
2265 if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
2267 Con_Printf("VM_loadfromfile: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
2268 PRVM_G_FLOAT(OFS_RETURN) = -4;
2272 // not conform with VM_fopen
2273 data = FS_LoadFile(filename, tempmempool, false);
2275 PRVM_G_FLOAT(OFS_RETURN) = -1;
2277 PRVM_ED_LoadFromFile(data);
2288 float mod(float val, float m)
2291 void VM_modulo(void)
2294 VM_SAFEPARMCOUNT(2,VM_module);
2296 val = (int) PRVM_G_FLOAT(OFS_PARM0);
2297 m = (int) PRVM_G_FLOAT(OFS_PARM1);
2299 PRVM_G_FLOAT(OFS_RETURN) = (float) (val % m);
2302 void VM_Search_Init(void)
2304 memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES]));
2307 void VM_Search_Reset(void)
2310 // reset the fssearch list
2311 for(i = 0; i < MAX_VMSEARCHES; i++)
2312 if(VM_SEARCHLIST[i])
2313 FS_FreeSearch(VM_SEARCHLIST[i]);
2314 memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES]));
2321 float search_begin(string pattern, float caseinsensitive, float quiet)
2324 void VM_search_begin(void)
2328 int caseinsens, quiet;
2330 VM_SAFEPARMCOUNT(3, VM_search_begin);
2332 pattern = PRVM_G_STRING(OFS_PARM0);
2334 VM_CheckEmptyString(pattern);
2336 caseinsens = PRVM_G_FLOAT(OFS_PARM1);
2337 quiet = PRVM_G_FLOAT(OFS_PARM2);
2339 for(handle = 0; handle < MAX_VMSEARCHES; handle++)
2340 if(!VM_SEARCHLIST[handle])
2343 if(handle >= MAX_VMSEARCHES)
2345 Con_Printf("VM_search_begin: %s ran out of search handles (%i)\n", PRVM_NAME, MAX_VMSEARCHES);
2346 PRVM_G_FLOAT(OFS_RETURN) = -2;
2350 if(!(VM_SEARCHLIST[handle] = FS_Search(pattern,caseinsens, quiet)))
2351 PRVM_G_FLOAT(OFS_RETURN) = -1;
2353 PRVM_G_FLOAT(OFS_RETURN) = handle;
2360 void search_end(float handle)
2363 void VM_search_end(void)
2366 VM_SAFEPARMCOUNT(1, VM_search_end);
2368 handle = PRVM_G_FLOAT(OFS_PARM0);
2370 if(handle < 0 || handle >= MAX_VMSEARCHES)
2372 Con_Printf("VM_search_end: invalid handle %i used in %s\n", handle, PRVM_NAME);
2375 if(VM_SEARCHLIST[handle] == NULL)
2377 Con_Printf("VM_search_end: no such handle %i in %s\n", handle, PRVM_NAME);
2381 FS_FreeSearch(VM_SEARCHLIST[handle]);
2382 VM_SEARCHLIST[handle] = NULL;
2389 float search_getsize(float handle)
2392 void VM_search_getsize(void)
2395 VM_SAFEPARMCOUNT(1, VM_M_search_getsize);
2397 handle = PRVM_G_FLOAT(OFS_PARM0);
2399 if(handle < 0 || handle >= MAX_VMSEARCHES)
2401 Con_Printf("VM_search_getsize: invalid handle %i used in %s\n", handle, PRVM_NAME);
2404 if(VM_SEARCHLIST[handle] == NULL)
2406 Con_Printf("VM_search_getsize: no such handle %i in %s\n", handle, PRVM_NAME);
2410 PRVM_G_FLOAT(OFS_RETURN) = VM_SEARCHLIST[handle]->numfilenames;
2415 VM_search_getfilename
2417 string search_getfilename(float handle, float num)
2420 void VM_search_getfilename(void)
2422 int handle, filenum;
2424 VM_SAFEPARMCOUNT(2, VM_search_getfilename);
2426 handle = PRVM_G_FLOAT(OFS_PARM0);
2427 filenum = PRVM_G_FLOAT(OFS_PARM1);
2429 if(handle < 0 || handle >= MAX_VMSEARCHES)
2431 Con_Printf("VM_search_getfilename: invalid handle %i used in %s\n", handle, PRVM_NAME);
2434 if(VM_SEARCHLIST[handle] == NULL)
2436 Con_Printf("VM_search_getfilename: no such handle %i in %s\n", handle, PRVM_NAME);
2439 if(filenum < 0 || filenum >= VM_SEARCHLIST[handle]->numfilenames)
2441 Con_Printf("VM_search_getfilename: invalid filenum %i in %s\n", filenum, PRVM_NAME);
2445 tmp = VM_GetTempString();
2446 strcpy(tmp, VM_SEARCHLIST[handle]->filenames[filenum]);
2448 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
2455 string chr(float ascii)
2461 VM_SAFEPARMCOUNT(1, VM_chr);
2463 tmp = VM_GetTempString();
2464 tmp[0] = (unsigned char) PRVM_G_FLOAT(OFS_PARM0);
2467 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
2470 //=============================================================================
2471 // Draw builtins (client & menu)
2477 float iscachedpic(string pic)
2480 void VM_iscachedpic(void)
2482 VM_SAFEPARMCOUNT(1,VM_iscachedpic);
2484 // drawq hasnt such a function, thus always return true
2485 PRVM_G_FLOAT(OFS_RETURN) = TRUE;
2492 string precache_pic(string pic)
2495 void VM_precache_pic(void)
2499 VM_SAFEPARMCOUNT(1, VM_precache_pic);
2501 s = PRVM_G_STRING(OFS_PARM0);
2502 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
2505 PRVM_ERROR ("VM_precache_pic: %s: NULL\n", PRVM_NAME);
2507 VM_CheckEmptyString (s);
2509 if(!Draw_CachePic(s))
2510 PRVM_G_INT(OFS_RETURN) = PRVM_SetString("");
2520 void VM_freepic(void)
2524 VM_SAFEPARMCOUNT(1,VM_freepic);
2526 s = PRVM_G_STRING(OFS_PARM0);
2529 PRVM_ERROR ("VM_freepic: %s: NULL\n");
2531 VM_CheckEmptyString (s);
2540 float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
2543 void VM_drawcharacter(void)
2545 float *pos,*scale,*rgb;
2548 VM_SAFEPARMCOUNT(6,VM_drawcharacter);
2550 character = (char) PRVM_G_FLOAT(OFS_PARM1);
2553 Con_Printf("VM_drawcharacter: %s passed null character !\n",PRVM_NAME);
2554 PRVM_G_FLOAT(OFS_RETURN) = -1;
2558 pos = PRVM_G_VECTOR(OFS_PARM0);
2559 scale = PRVM_G_VECTOR(OFS_PARM2);
2560 rgb = PRVM_G_VECTOR(OFS_PARM3);
2561 flag = (int)PRVM_G_FLOAT(OFS_PARM5);
2563 if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
2565 Con_Printf("VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
2566 PRVM_G_FLOAT(OFS_RETURN) = -2;
2570 if(pos[2] || scale[2])
2571 Con_Printf("VM_drawcharacter: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
2573 if(!scale[0] || !scale[1])
2575 Con_Printf("VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
2576 PRVM_G_FLOAT(OFS_RETURN) = -3;
2580 DrawQ_String (pos[0], pos[1], &character, 1, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
2581 PRVM_G_FLOAT(OFS_RETURN) = 1;
2588 float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
2591 void VM_drawstring(void)
2593 float *pos,*scale,*rgb;
2596 VM_SAFEPARMCOUNT(6,VM_drawstring);
2598 string = PRVM_G_STRING(OFS_PARM1);
2601 Con_Printf("VM_drawstring: %s passed null string !\n",PRVM_NAME);
2602 PRVM_G_FLOAT(OFS_RETURN) = -1;
2606 VM_CheckEmptyString(string);
2608 pos = PRVM_G_VECTOR(OFS_PARM0);
2609 scale = PRVM_G_VECTOR(OFS_PARM2);
2610 rgb = PRVM_G_VECTOR(OFS_PARM3);
2611 flag = (int)PRVM_G_FLOAT(OFS_PARM5);
2613 if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
2615 Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
2616 PRVM_G_FLOAT(OFS_RETURN) = -2;
2620 if(!scale[0] || !scale[1])
2622 Con_Printf("VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
2623 PRVM_G_FLOAT(OFS_RETURN) = -3;
2627 if(pos[2] || scale[2])
2628 Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
2630 DrawQ_String (pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
2631 PRVM_G_FLOAT(OFS_RETURN) = 1;
2637 float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
2640 void VM_drawpic(void)
2643 float *size, *pos, *rgb;
2646 VM_SAFEPARMCOUNT(6,VM_drawpic);
2648 pic = PRVM_G_STRING(OFS_PARM1);
2652 Con_Printf("VM_drawpic: %s passed null picture name !\n", PRVM_NAME);
2653 PRVM_G_FLOAT(OFS_RETURN) = -1;
2657 VM_CheckEmptyString (pic);
2659 // is pic cached ? no function yet for that
2662 Con_Printf("VM_drawpic: %s: %s not cached !\n", PRVM_NAME, pic);
2663 PRVM_G_FLOAT(OFS_RETURN) = -4;
2667 pos = PRVM_G_VECTOR(OFS_PARM0);
2668 size = PRVM_G_VECTOR(OFS_PARM2);
2669 rgb = PRVM_G_VECTOR(OFS_PARM3);
2670 flag = (int) PRVM_G_FLOAT(OFS_PARM5);
2672 if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
2674 Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
2675 PRVM_G_FLOAT(OFS_RETURN) = -2;
2679 if(pos[2] || size[2])
2680 Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
2682 DrawQ_Pic(pos[0], pos[1], pic, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
2683 PRVM_G_FLOAT(OFS_RETURN) = 1;
2690 float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
2693 void VM_drawfill(void)
2695 float *size, *pos, *rgb;
2698 VM_SAFEPARMCOUNT(5,VM_drawfill);
2701 pos = PRVM_G_VECTOR(OFS_PARM0);
2702 size = PRVM_G_VECTOR(OFS_PARM1);
2703 rgb = PRVM_G_VECTOR(OFS_PARM2);
2704 flag = (int) PRVM_G_FLOAT(OFS_PARM4);
2706 if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
2708 Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
2709 PRVM_G_FLOAT(OFS_RETURN) = -2;
2713 if(pos[2] || size[2])
2714 Con_Printf("VM_drawstring: z value%c from %s discarded\n",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
2716 DrawQ_Pic(pos[0], pos[1], 0, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM3), flag);
2717 PRVM_G_FLOAT(OFS_RETURN) = 1;
2724 drawsetcliparea(float x, float y, float width, float height)
2727 void VM_drawsetcliparea(void)
2730 VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
2732 x = bound(0,PRVM_G_FLOAT(OFS_PARM0),vid.conwidth);
2733 y = bound(0,PRVM_G_FLOAT(OFS_PARM1),vid.conheight);
2734 w = bound(0,PRVM_G_FLOAT(OFS_PARM2),(vid.conwidth - x));
2735 h = bound(0,PRVM_G_FLOAT(OFS_PARM3),(vid.conheight - y));
2737 DrawQ_SetClipArea(x,y,w,h);
2742 VM_drawresetcliparea
2747 void VM_drawresetcliparea(void)
2749 VM_SAFEPARMCOUNT(0,VM_drawresetcliparea);
2751 DrawQ_ResetClipArea();
2758 vector getimagesize(string pic)
2761 void VM_getimagesize(void)
2766 VM_SAFEPARMCOUNT(1,VM_getimagesize);
2768 p = PRVM_G_STRING(OFS_PARM0);
2771 PRVM_ERROR("VM_getimagepos: %s passed null picture name !\n", PRVM_NAME);
2773 VM_CheckEmptyString (p);
2775 pic = Draw_CachePic (p);
2777 PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width;
2778 PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height;
2779 PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
2782 void VM_Cmd_Init(void)
2784 // only init the stuff for the current prog
2785 VM_STRINGS_MEMPOOL = Mem_AllocPool(va("vm_stringsmempool[%s]",PRVM_NAME), 0, NULL);
2790 void VM_Cmd_Reset(void)
2792 //Mem_EmptyPool(VM_STRINGS_MEMPOOL);
2793 Mem_FreePool(&VM_STRINGS_MEMPOOL);
2795 VM_Files_CloseAll();
2798 //============================================================================
2801 char *vm_sv_extensions =
2804 prvm_builtin_t vm_sv_builtins[] = {
2805 0 // to be consistent with the old vm
2808 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
2810 void VM_SV_Cmd_Init(void)
2814 void VM_SV_Cmd_Reset(void)
2818 //============================================================================
2821 char *vm_cl_extensions =
2824 prvm_builtin_t vm_cl_builtins[] = {
2825 0 // to be consistent with the old vm
2828 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
2830 void VM_CL_Cmd_Init(void)
2834 void VM_CL_Cmd_Reset(void)
2838 //============================================================================
2841 char *vm_m_extensions =
2848 setmousetarget(float target)
2851 void VM_M_setmousetarget(void)
2853 VM_SAFEPARMCOUNT(1, VM_M_setmousetarget);
2855 switch((int)PRVM_G_FLOAT(OFS_PARM0))
2858 in_client_mouse = false;
2861 in_client_mouse = true;
2864 PRVM_ERROR("VM_M_setmousetarget: wrong destination %i !\n",PRVM_G_FLOAT(OFS_PARM0));
2872 float getmousetarget
2875 void VM_M_getmousetarget(void)
2877 VM_SAFEPARMCOUNT(0,VM_M_getmousetarget);
2880 PRVM_G_FLOAT(OFS_RETURN) = 2;
2882 PRVM_G_FLOAT(OFS_RETURN) = 1;
2891 setkeydest(float dest)
2894 void VM_M_setkeydest(void)
2896 VM_SAFEPARMCOUNT(1,VM_M_setkeydest);
2898 switch((int)PRVM_G_FLOAT(OFS_PARM0))
2902 key_dest = key_game;
2906 key_dest = key_menu;
2910 // key_dest = key_message
2913 PRVM_ERROR("VM_M_setkeydest: wrong destination %i !\n",prog->globals[OFS_PARM0]);
2924 void VM_M_getkeydest(void)
2926 VM_SAFEPARMCOUNT(0,VM_M_getkeydest);
2928 // key_game = 0, key_message = 1, key_menu = 2, unknown = 3
2932 PRVM_G_FLOAT(OFS_RETURN) = 0;
2935 PRVM_G_FLOAT(OFS_RETURN) = 2;
2939 // PRVM_G_FLOAT(OFS_RETURN) = 1;
2942 PRVM_G_FLOAT(OFS_RETURN) = 3;
2950 callfunction(...,string function_name)
2953 mfunction_t *PRVM_ED_FindFunction (const char *name);
2954 void VM_M_callfunction(void)
2960 PRVM_ERROR("VM_M_callfunction: 1 parameter is required !\n");
2962 s = PRVM_G_STRING(OFS_PARM0 + (prog->argc - 1));
2965 PRVM_ERROR("VM_M_callfunction: null string !\n");
2967 VM_CheckEmptyString(s);
2969 func = PRVM_ED_FindFunction(s);
2972 PRVM_ERROR("VM_M_callfunciton: function %s not found !\n", s);
2973 else if (func->first_statement < 0)
2975 // negative statements are built in functions
2976 int builtinnumber = -func->first_statement;
2977 prog->xfunction->builtinsprofile++;
2978 if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
2979 prog->builtins[builtinnumber]();
2981 PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
2986 PRVM_ExecuteProgram(func - prog->functions,"");
2995 float isfunction(string function_name)
2998 mfunction_t *PRVM_ED_FindFunction (const char *name);
2999 void VM_M_isfunction(void)
3004 VM_SAFEPARMCOUNT(1, VM_M_isfunction);
3006 s = PRVM_G_STRING(OFS_PARM0);
3009 PRVM_ERROR("VM_M_isfunction: null string !\n");
3011 VM_CheckEmptyString(s);
3013 func = PRVM_ED_FindFunction(s);
3016 PRVM_G_FLOAT(OFS_RETURN) = false;
3018 PRVM_G_FLOAT(OFS_RETURN) = true;
3025 writetofile(float fhandle, entity ent)
3028 void VM_M_writetofile(void)
3033 VM_SAFEPARMCOUNT(2, VM_M_writetofile);
3035 filenum = PRVM_G_FLOAT(OFS_PARM0);
3036 if (filenum < 0 || filenum >= MAX_VMFILES)
3038 Con_Printf("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
3041 if (VM_FILES[filenum] == NULL)
3043 Con_Printf("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
3047 ent = PRVM_G_EDICT(OFS_PARM1);
3050 Con_Printf("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_EDICT_NUM(OFS_PARM1));
3054 PRVM_ED_Write (VM_FILES[filenum], ent);
3061 vector getresolution(float number)
3064 extern unsigned short video_resolutions[][2];
3065 void VM_M_getresolution(void)
3068 VM_SAFEPARMCOUNT(1, VM_getresolution);
3070 nr = PRVM_G_FLOAT(OFS_PARM0);
3073 PRVM_G_VECTOR(OFS_RETURN)[0] = video_resolutions[nr][0];
3074 PRVM_G_VECTOR(OFS_RETURN)[1] = video_resolutions[nr][1];
3075 PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
3082 string keynumtostring(float keynum)
3085 void VM_M_keynumtostring(void)
3089 VM_SAFEPARMCOUNT(1, VM_M_keynumtostring);
3091 keynum = PRVM_G_FLOAT(OFS_PARM0);
3093 tmp = VM_GetTempString();
3095 strcpy(tmp, Key_KeynumToString(keynum));
3097 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
3102 VM_M_findkeysforcommand
3104 string findkeysforcommand(string command)
3106 the returned string is an altstring
3109 #define NUMKEYS 5 // TODO: merge the constant in keys.c with this one somewhen
3111 void M_FindKeysForCommand(char *command, int *keys);
3112 void VM_M_findkeysforcommand(void)
3118 VM_SAFEPARMCOUNT(1, VM_M_findkeysforcommand);
3120 cmd = PRVM_G_STRING(OFS_PARM0);
3122 VM_CheckEmptyString(cmd);
3124 (ret = VM_GetTempString())[0] = 0;
3126 M_FindKeysForCommand(cmd, keys);
3128 for(i = 0; i < NUMKEYS; i++)
3129 ret = strcat(ret, va(" \'%i\'", keys[i]));
3131 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(ret);
3136 VM_M_gethostcachecount
3138 float gethostcachevalue(float type)
3149 void VM_M_gethostcachevalue( void )
3152 VM_SAFEPARMCOUNT ( 1, VM_M_gethostcachevalue );
3154 PRVM_G_FLOAT( OFS_RETURN ) = 0;
3156 type = PRVM_G_FLOAT( OFS_PARM0 );
3157 if( type < 0 || type > 4 )
3158 Con_Printf( "VM_M_gethostcachevalue: bad type %i!\n", type );
3162 PRVM_G_FLOAT ( OFS_RETURN ) = hostCacheCount;
3165 PRVM_G_FLOAT ( OFS_RETURN ) = masterquerycount;
3168 PRVM_G_FLOAT ( OFS_RETURN ) = masterreplycount;
3171 PRVM_G_FLOAT ( OFS_RETURN ) = serverquerycount;
3174 PRVM_G_FLOAT ( OFS_RETURN ) = serverreplycount;
3181 VM_M_gethostcachestring
3183 string gethostcachestring(float type, float hostnr)
3191 void VM_M_gethostcachestring(void)
3196 VM_SAFEPARMCOUNT(2, VM_M_gethostcachestring);
3198 PRVM_G_INT(OFS_RETURN) = 0;
3200 type = PRVM_G_FLOAT(OFS_PARM0);
3202 if(type < 0 || type > 2)
3204 Con_Print("VM_M_gethostcachestring: bad string type requested!\n");
3208 hostnr = PRVM_G_FLOAT(OFS_PARM1);
3210 if(hostnr < 0 || hostnr >= hostCacheCount)
3212 Con_Print("VM_M_gethostcachestring: bad hostnr passed!\n");
3217 PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].cname );
3218 else if( type == 1 )
3219 PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].line1 );
3221 PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].line2 );
3224 prvm_builtin_t vm_m_builtins[] = {
3225 0, // to be consistent with the old vm
3226 // common builtings (mostly)
3303 VM_search_getfilename, // 77
3319 VM_WriteEntity, // 408
3335 VM_drawresetcliparea,
3336 VM_getimagesize,// 460
3345 VM_M_setmousetarget,
3346 VM_M_getmousetarget,
3351 VM_M_keynumtostring,
3352 VM_M_findkeysforcommand,// 610
3353 VM_M_gethostcachevalue,
3354 VM_M_gethostcachestring // 612
3357 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
3359 void VM_M_Cmd_Init(void)
3364 void VM_M_Cmd_Reset(void)