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_VMFILES 256
185 #define MAX_PRVMFILES MAX_VMFILES * PRVM_MAXPROGS
186 #define VM_FILES ((qfile_t**)(vm_files + PRVM_GetProgNr() * MAX_VMFILES))
188 qfile_t *vm_files[MAX_PRVMFILES];
190 // qc fs search handling
191 #define MAX_VMSEARCHES 128
192 #define TOTAL_VMSEARCHES MAX_VMSEARCHES * PRVM_MAXPROGS
193 #define VM_SEARCHLIST ((fssearch_t**)(vm_fssearchlist + PRVM_GetProgNr() * MAX_VMSEARCHES))
195 fssearch_t *vm_fssearchlist[TOTAL_VMSEARCHES];
197 static char *VM_GetTempString(void)
200 s = vm_string_temp[vm_string_tempindex];
201 vm_string_tempindex = (vm_string_tempindex + 1) % VM_STRINGTEMP_BUFFERS;
205 void VM_CheckEmptyString (char *s)
208 PRVM_ERROR ("%s: Bad string", PRVM_NAME);
211 //============================================================================
214 void VM_VarString(int first, char *out, int outlength)
220 outend = out + outlength - 1;
221 for (i = first;i < prog->argc && out < outend;i++)
223 s = PRVM_G_STRING((OFS_PARM0+i*3));
224 while (out < outend && *s)
234 returns true if the extension is supported by the server
236 checkextension(extensionname)
240 // kind of helper function
241 static qboolean checkextension(char *name)
247 for (e = prog->extensionstring;*e;e++)
254 while (*e && *e != ' ')
256 if (e - start == len)
257 if (!strncasecmp(start, name, len))
265 void VM_checkextension (void)
267 VM_SAFEPARMCOUNT(1,VM_checkextension);
269 PRVM_G_FLOAT(OFS_RETURN) = checkextension(PRVM_G_STRING(OFS_PARM0));
276 This is a TERMINAL error, which will kill off the entire prog.
285 char string[VM_STRINGTEMP_LENGTH];
287 VM_VarString(0, string, sizeof(string));
288 Con_Printf("======%S ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
291 ed = PRVM_G_EDICT(prog->self->ofs);
295 PRVM_ERROR ("%s: Program error", PRVM_NAME);
302 Dumps out self, then an error message. The program is aborted and self is
303 removed, but the level can continue.
308 void VM_objerror (void)
311 char string[VM_STRINGTEMP_LENGTH];
313 VM_VarString(0, string, sizeof(string));
314 Con_Printf("======%s OBJECT ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
317 ed = PRVM_G_EDICT (prog->self->ofs);
323 // objerror has to display the object fields -> else call
324 PRVM_ERROR ("VM_objecterror: self not defined !\n");
329 VM_print (actually used only by client and menu)
338 char string[VM_STRINGTEMP_LENGTH];
340 VM_VarString(0, string, sizeof(string));
348 broadcast print to everyone on server
353 void VM_bprint (void)
355 char string[VM_STRINGTEMP_LENGTH];
359 Con_Printf("VM_bprint: game is not server(%s) !\n", PRVM_NAME);
363 VM_VarString(0, string, sizeof(string));
364 SV_BroadcastPrint(string);
369 VM_sprint (menu & client but only if server.active == true)
371 single print to a specific client
373 sprint(float clientnum,...[string])
376 void VM_sprint (void)
380 char string[VM_STRINGTEMP_LENGTH];
382 //find client for this entity
383 clientnum = PRVM_G_FLOAT(OFS_PARM0);
384 if (!sv.active || clientnum < 0 || clientnum >= svs.maxclients || !svs.clients[clientnum].active)
386 Con_Printf("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME);
390 client = svs.clients + clientnum;
391 if (!client->netconnection)
393 VM_VarString(1, string, sizeof(string));
394 MSG_WriteChar(&client->message,svc_print);
395 MSG_WriteString(&client->message, string);
402 single print to the screen
404 centerprint(clientent, value)
407 void VM_centerprint (void)
409 char string[VM_STRINGTEMP_LENGTH];
411 VM_VarString(0, string, sizeof(string));
412 SCR_CenterPrint(string);
419 vector normalize(vector)
422 void VM_normalize (void)
428 VM_SAFEPARMCOUNT(1,VM_normalize);
430 value1 = PRVM_G_VECTOR(OFS_PARM0);
432 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
436 newvalue[0] = newvalue[1] = newvalue[2] = 0;
440 newvalue[0] = value1[0] * new;
441 newvalue[1] = value1[1] * new;
442 newvalue[2] = value1[2] * new;
445 VectorCopy (newvalue, PRVM_G_VECTOR(OFS_RETURN));
460 VM_SAFEPARMCOUNT(1,VM_vlen);
462 value1 = PRVM_G_VECTOR(OFS_PARM0);
464 new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2];
467 PRVM_G_FLOAT(OFS_RETURN) = new;
474 float vectoyaw(vector)
477 void VM_vectoyaw (void)
482 VM_SAFEPARMCOUNT(1,VM_vectoyaw);
484 value1 = PRVM_G_VECTOR(OFS_PARM0);
486 if (value1[1] == 0 && value1[0] == 0)
490 yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI);
495 PRVM_G_FLOAT(OFS_RETURN) = yaw;
503 vector vectoangles(vector)
506 void VM_vectoangles (void)
512 VM_SAFEPARMCOUNT(1,VM_vectoangles);
514 value1 = PRVM_G_VECTOR(OFS_PARM0);
516 if (value1[1] == 0 && value1[0] == 0)
526 // LordHavoc: optimized a bit
529 yaw = (atan2(value1[1], value1[0]) * 180 / M_PI);
533 else if (value1[1] > 0)
538 forward = sqrt(value1[0]*value1[0] + value1[1]*value1[1]);
539 pitch = (int) (atan2(value1[2], forward) * 180 / M_PI);
544 PRVM_G_FLOAT(OFS_RETURN+0) = pitch;
545 PRVM_G_FLOAT(OFS_RETURN+1) = yaw;
546 PRVM_G_FLOAT(OFS_RETURN+2) = 0;
553 Returns a number from 0<= num < 1
558 void VM_random (void)
562 VM_SAFEPARMCOUNT(0,VM_random);
564 num = (rand ()&0x7fff) / ((float)0x7fff);
566 PRVM_G_FLOAT(OFS_RETURN) = num;
573 Each entity can have eight independant sound sources, like voice,
576 Channel 0 is an auto-allocate channel, the others override anything
577 already running on that entity/channel pair.
579 An attenuation of 0 will play full volume everywhere in the level.
580 Larger attenuations will drop off.
593 entity = G_EDICT(OFS_PARM0);
594 channel = G_FLOAT(OFS_PARM1);
595 sample = G_STRING(OFS_PARM2);
596 volume = G_FLOAT(OFS_PARM3) * 255;
597 attenuation = G_FLOAT(OFS_PARM4);
599 if (volume < 0 || volume > 255)
600 Host_Error ("SV_StartSound: volume = %i", volume);
602 if (attenuation < 0 || attenuation > 4)
603 Host_Error ("SV_StartSound: attenuation = %f", attenuation);
605 if (channel < 0 || channel > 7)
606 Host_Error ("SV_StartSound: channel = %i", channel);
608 SV_StartSound (entity, channel, sample, volume, attenuation);
616 localsound(string sample)
619 void VM_localsound(void)
623 VM_SAFEPARMCOUNT(1,VM_localsound);
625 s = PRVM_G_STRING(OFS_PARM0);
627 if(!S_GetCached(s, true))
629 Con_Printf("VM_localsound: %s : %s not cached !\n", PRVM_NAME, s);
630 PRVM_G_FLOAT(OFS_RETURN) = -4;
634 S_LocalSound(s, true);
635 PRVM_G_FLOAT(OFS_RETURN) = 1;
647 PRVM_ERROR ("%s: break statement", PRVM_NAME);
650 //============================================================================
656 Sends text over to the client's execution buffer
658 [localcmd (string) or]
662 void VM_localcmd (void)
664 VM_SAFEPARMCOUNT(1,VM_localcmd);
666 Cbuf_AddText(PRVM_G_STRING(OFS_PARM0));
678 VM_SAFEPARMCOUNT(1,VM_cvar);
680 PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0));
687 const string str_cvar (string)
690 void VM_str_cvar(void)
693 const char *cvar_string;
694 VM_SAFEPARMCOUNT(1,VM_str_cvar);
696 name = PRVM_G_STRING(OFS_PARM0);
699 PRVM_ERROR("VM_str_cvar: %s: null string\n", PRVM_NAME);
701 VM_CheckEmptyString(name);
703 out = VM_GetTempString();
705 cvar_string = Cvar_VariableString(name);
707 strcpy(out, cvar_string);
709 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(out);
716 void cvar_set (string,string)
719 void VM_cvar_set (void)
721 VM_SAFEPARMCOUNT(2,VM_cvar_set);
723 Cvar_Set(PRVM_G_STRING(OFS_PARM0), PRVM_G_STRING(OFS_PARM1));
733 void VM_dprint (void)
735 char string[VM_STRINGTEMP_LENGTH];
736 if (developer.integer)
738 VM_VarString(0, string, sizeof(string));
739 Con_Printf("%s: %s", PRVM_NAME, string);
756 VM_SAFEPARMCOUNT(1, VM_ftos);
758 v = PRVM_G_FLOAT(OFS_PARM0);
760 s = VM_GetTempString();
761 if ((float)((int)v) == v)
762 sprintf(s, "%i", (int)v);
765 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
780 VM_SAFEPARMCOUNT(1,VM_fabs);
782 v = PRVM_G_FLOAT(OFS_PARM0);
783 PRVM_G_FLOAT(OFS_RETURN) = fabs(v);
798 VM_SAFEPARMCOUNT(1,VM_vtos);
800 s = VM_GetTempString();
801 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]);
802 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
817 VM_SAFEPARMCOUNT(1, VM_etos);
819 s = VM_GetTempString();
820 sprintf (s, "entity %i", PRVM_G_EDICTNUM(OFS_PARM0));
821 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
828 float stof(...[string])
833 char string[VM_STRINGTEMP_LENGTH];
834 VM_VarString(0, string, sizeof(string));
835 PRVM_G_FLOAT(OFS_RETURN) = atof(string);
849 prog->xfunction->builtinsprofile += 20;
850 ed = PRVM_ED_Alloc();
862 void VM_remove (void)
865 prog->xfunction->builtinsprofile += 20;
867 VM_SAFEPARMCOUNT(1, VM_remove);
869 ed = PRVM_G_EDICT(OFS_PARM0);
870 // if (ed == prog->edicts)
871 // PRVM_ERROR ("remove: tried to remove world\n");
872 // if (PRVM_NUM_FOR_EDICT(ed) <= sv.maxclients)
873 // Host_Error("remove: tried to remove a client\n");
881 entity find(entity start, .string field, string match)
892 VM_SAFEPARMCOUNT(3,VM_find);
894 e = PRVM_G_EDICTNUM(OFS_PARM0);
895 f = PRVM_G_INT(OFS_PARM1);
896 s = PRVM_G_STRING(OFS_PARM2);
900 // return reserved edict 0 (could be used for whatever the prog wants)
901 VM_RETURN_EDICT(prog->edicts);
905 for (e++ ; e < prog->num_edicts ; e++)
907 prog->xfunction->builtinsprofile++;
908 ed = PRVM_EDICT_NUM(e);
911 t = PRVM_E_STRING(ed,f);
921 VM_RETURN_EDICT(prog->edicts);
928 entity findfloat(entity start, .float field, float match)
929 entity findentity(entity start, .entity field, entity match)
932 // LordHavoc: added this for searching float, int, and entity reference fields
933 void VM_findfloat (void)
940 VM_SAFEPARMCOUNT(3,VM_findfloat);
942 e = PRVM_G_EDICTNUM(OFS_PARM0);
943 f = PRVM_G_INT(OFS_PARM1);
944 s = PRVM_G_FLOAT(OFS_PARM2);
946 for (e++ ; e < prog->num_edicts ; e++)
948 prog->xfunction->builtinsprofile++;
949 ed = PRVM_EDICT_NUM(e);
952 if (PRVM_E_FLOAT(ed,f) == s)
959 VM_RETURN_EDICT(prog->edicts);
966 entity findchain(.string field, string match)
969 int PRVM_ED_FindFieldOffset(const char *field);
970 // chained search for strings in entity fields
971 // entity(.string field, string match) findchain = #402;
972 void VM_findchain (void)
978 prvm_edict_t *ent, *chain;
980 VM_SAFEPARMCOUNT(2,VM_findchain);
982 // is the same like !(prog->flag & PRVM_FE_CHAIN) - even if the operator precedence is another
983 if(!prog->flag & PRVM_FE_CHAIN)
984 PRVM_ERROR("VM_findchain: %s doesnt have a chain field !\n", PRVM_NAME);
986 chain_of = PRVM_ED_FindFieldOffset ("chain");
988 chain = prog->edicts;
990 f = PRVM_G_INT(OFS_PARM0);
991 s = PRVM_G_STRING(OFS_PARM1);
994 VM_RETURN_EDICT(prog->edicts);
998 ent = PRVM_NEXT_EDICT(prog->edicts);
999 for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
1001 prog->xfunction->builtinsprofile++;
1004 t = PRVM_E_STRING(ent,f);
1010 PRVM_E_FLOAT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
1014 VM_RETURN_EDICT(chain);
1021 entity findchainfloat(.string field, float match)
1022 entity findchainentity(.string field, entity match)
1025 // LordHavoc: chained search for float, int, and entity reference fields
1026 // entity(.string field, float match) findchainfloat = #403;
1027 void VM_findchainfloat (void)
1033 prvm_edict_t *ent, *chain;
1035 VM_SAFEPARMCOUNT(2, VM_findchainfloat);
1037 if(!prog->flag & PRVM_FE_CHAIN)
1038 PRVM_ERROR("VM_findchainfloat: %s doesnt have a chain field !\n", PRVM_NAME);
1040 chain_of = PRVM_ED_FindFieldOffset ("chain");
1042 chain = (prvm_edict_t *)prog->edicts;
1044 f = PRVM_G_INT(OFS_PARM0);
1045 s = PRVM_G_FLOAT(OFS_PARM1);
1047 ent = PRVM_NEXT_EDICT(prog->edicts);
1048 for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
1050 prog->xfunction->builtinsprofile++;
1053 if (E_FLOAT(ent,f) != s)
1056 PRVM_E_FLOAT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
1060 VM_RETURN_EDICT(chain);
1067 string precache_file(string)
1070 void VM_precache_file (void)
1071 { // precache_file is only used to copy files with qcc, it does nothing
1072 VM_SAFEPARMCOUNT(1,VM_precache_file);
1074 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1081 used instead of the other VM_precache_* functions in the builtin list
1085 void VM_precache_error (void)
1087 PRVM_ERROR ("PF_Precache_*: Precache can only be done in spawn functions");
1094 string precache_sound (string sample)
1097 void VM_precache_sound (void)
1101 VM_SAFEPARMCOUNT(1, VM_precache_sound);
1103 s = PRVM_G_STRING(OFS_PARM0);
1104 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
1105 VM_CheckEmptyString (s);
1107 if(S_GetCached(s, true))
1109 Con_Printf("VM_precache_sound: %s already cached (%s)\n", s, PRVM_NAME);
1113 if(!S_PrecacheSound(s,true, true))
1114 Con_Printf("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
1124 void VM_coredump (void)
1126 VM_SAFEPARMCOUNT(0,VM_coredump);
1128 Cbuf_AddText("prvm_edicts ");
1129 Cbuf_AddText(PRVM_NAME);
1140 void PRVM_StackTrace(void);
1141 void VM_stackdump (void)
1143 VM_SAFEPARMCOUNT(0, VM_stackdump);
1158 VM_SAFEPARMCOUNT(0, VM_crash);
1160 PRVM_ERROR("Crash called by %s\n",PRVM_NAME);
1170 void VM_traceon (void)
1172 VM_SAFEPARMCOUNT(0,VM_traceon);
1184 void VM_traceoff (void)
1186 VM_SAFEPARMCOUNT(0,VM_traceoff);
1188 prog->trace = false;
1198 void VM_eprint (void)
1200 VM_SAFEPARMCOUNT(1,VM_eprint);
1202 PRVM_ED_PrintNum (PRVM_G_EDICTNUM(OFS_PARM0));
1216 VM_SAFEPARMCOUNT(1,VM_rint);
1218 f = PRVM_G_FLOAT(OFS_PARM0);
1220 PRVM_G_FLOAT(OFS_RETURN) = (int)(f + 0.5);
1222 PRVM_G_FLOAT(OFS_RETURN) = (int)(f - 0.5);
1232 void VM_floor (void)
1234 VM_SAFEPARMCOUNT(1,VM_floor);
1236 PRVM_G_FLOAT(OFS_RETURN) = floor(PRVM_G_FLOAT(OFS_PARM0));
1248 VM_SAFEPARMCOUNT(1,VM_ceil);
1250 PRVM_G_FLOAT(OFS_RETURN) = ceil(PRVM_G_FLOAT(OFS_PARM0));
1258 entity nextent(entity)
1261 void VM_nextent (void)
1266 i = PRVM_G_EDICTNUM(OFS_PARM0);
1269 prog->xfunction->builtinsprofile++;
1271 if (i == prog->num_edicts)
1273 VM_RETURN_EDICT(prog->edicts);
1276 ent = PRVM_EDICT_NUM(i);
1279 VM_RETURN_EDICT(ent);
1286 ===============================================================================
1289 used only for client and menu
1290 severs uses VM_SV_...
1292 Write*(* data, float type, float to)
1294 ===============================================================================
1297 #define MSG_BROADCAST 0 // unreliable to all
1298 #define MSG_ONE 1 // reliable to one (msg_entity)
1299 #define MSG_ALL 2 // reliable to all
1300 #define MSG_INIT 3 // write to the init string
1302 sizebuf_t *VM_WriteDest (void)
1308 PRVM_ERROR("VM_WriteDest: game is not server (%s)\n", PRVM_NAME);
1310 dest = G_FLOAT(OFS_PARM1);
1314 return &sv.datagram;
1317 destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
1318 if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active)
1319 PRVM_ERROR("VM_clientcommand: %s: invalid client !\n", PRVM_NAME);
1321 return &svs.clients[destclient].message;
1324 return &sv.reliable_datagram;
1330 PRVM_ERROR ("WriteDest: bad destination");
1337 void VM_WriteByte (void)
1339 MSG_WriteByte (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1342 void VM_WriteChar (void)
1344 MSG_WriteChar (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1347 void VM_WriteShort (void)
1349 MSG_WriteShort (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1352 void VM_WriteLong (void)
1354 MSG_WriteLong (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
1357 void VM_WriteAngle (void)
1359 MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
1362 void VM_WriteCoord (void)
1364 MSG_WriteCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
1367 void VM_WriteString (void)
1369 MSG_WriteString (VM_WriteDest(), PRVM_G_STRING(OFS_PARM0));
1372 void VM_WriteEntity (void)
1374 MSG_WriteShort (VM_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
1377 //=============================================================================
1384 changelevel(string map)
1387 void VM_changelevel (void)
1391 VM_SAFEPARMCOUNT(1, VM_changelevel);
1395 Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME);
1399 // make sure we don't issue two changelevels
1400 if (svs.changelevel_issued)
1402 svs.changelevel_issued = true;
1404 s = G_STRING(OFS_PARM0);
1405 Cbuf_AddText (va("changelevel %s\n",s));
1417 VM_SAFEPARMCOUNT(1,VM_sin);
1418 PRVM_G_FLOAT(OFS_RETURN) = sin(PRVM_G_FLOAT(OFS_PARM0));
1429 VM_SAFEPARMCOUNT(1,VM_cos);
1430 PRVM_G_FLOAT(OFS_RETURN) = cos(PRVM_G_FLOAT(OFS_PARM0));
1442 VM_SAFEPARMCOUNT(1,VM_sqrt);
1443 PRVM_G_FLOAT(OFS_RETURN) = sqrt(PRVM_G_FLOAT(OFS_PARM0));
1450 Returns a vector of length < 1 and > 0
1455 void VM_randomvec (void)
1460 VM_SAFEPARMCOUNT(0, VM_randomvec);
1465 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1466 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1467 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1469 while (DotProduct(temp, temp) >= 1);
1470 VectorCopy (temp, PRVM_G_VECTOR(OFS_RETURN));
1473 temp[0] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1474 temp[1] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1475 temp[2] = (rand()&32767) * (2.0 / 32767.0) - 1.0;
1476 // length returned always > 0
1477 length = (rand()&32766 + 1) * (1.0 / 32767.0) / VectorLength(temp);
1478 VectorScale(temp,length, temp);*/
1479 //VectorCopy(temp, PRVM_G_VECTOR(OFS_RETURN));
1482 //=============================================================================
1488 float registercvar (string name, string value, float flags)
1491 void VM_registercvar (void)
1496 VM_SAFEPARMCOUNT(3,VM_registercvar);
1498 name = PRVM_G_STRING(OFS_PARM0);
1499 value = PRVM_G_STRING(OFS_PARM1);
1500 flags = PRVM_G_FLOAT(OFS_PARM2);
1501 PRVM_G_FLOAT(OFS_RETURN) = 0;
1503 if(flags > CVAR_MAXFLAGSVAL)
1506 // first check to see if it has already been defined
1507 if (Cvar_FindVar (name))
1510 // check for overlap with a command
1511 if (Cmd_Exists (name))
1513 Con_Printf("VM_registercvar: %s is a command\n", name);
1517 Cvar_Get(name, value, 0);
1519 PRVM_G_FLOAT(OFS_RETURN) = 1; // success
1526 returns the minimum of two supplied floats
1528 float min(float a, float b, ...[float])
1533 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1534 if (prog->argc == 2)
1535 PRVM_G_FLOAT(OFS_RETURN) = min(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
1536 else if (prog->argc >= 3)
1539 float f = PRVM_G_FLOAT(OFS_PARM0);
1540 for (i = 1;i < prog->argc;i++)
1541 if (PRVM_G_FLOAT((OFS_PARM0+i*3)) < f)
1542 f = PRVM_G_FLOAT((OFS_PARM0+i*3));
1543 PRVM_G_FLOAT(OFS_RETURN) = f;
1546 PRVM_ERROR("VM_min: %s must supply at least 2 floats\n", PRVM_NAME);
1553 returns the maximum of two supplied floats
1555 float max(float a, float b, ...[float])
1560 // LordHavoc: 3+ argument enhancement suggested by FrikaC
1561 if (prog->argc == 2)
1562 PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
1563 else if (prog->argc >= 3)
1566 float f = PRVM_G_FLOAT(OFS_PARM0);
1567 for (i = 1;i < prog->argc;i++)
1568 if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f)
1569 f = PRVM_G_FLOAT((OFS_PARM0+i*3));
1570 G_FLOAT(OFS_RETURN) = f;
1573 PRVM_ERROR("VM_max: %s must supply at least 2 floats\n", PRVM_NAME);
1580 returns number bounded by supplied range
1582 float bound(float min, float value, float max)
1585 void VM_bound (void)
1587 VM_SAFEPARMCOUNT(3,VM_bound);
1588 PRVM_G_FLOAT(OFS_RETURN) = bound(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1), PRVM_G_FLOAT(OFS_PARM2));
1595 returns a raised to power b
1597 float pow(float a, float b)
1602 VM_SAFEPARMCOUNT(2,VM_pow);
1603 PRVM_G_FLOAT(OFS_RETURN) = pow(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
1610 copies data from one entity to another
1612 copyentity(entity src, entity dst)
1615 void VM_copyentity (void)
1617 prvm_edict_t *in, *out;
1618 VM_SAFEPARMCOUNT(2,VM_copyentity);
1619 in = PRVM_G_EDICT(OFS_PARM0);
1620 out = PRVM_G_EDICT(OFS_PARM1);
1621 memcpy(out->v, in->v, prog->progs->entityfields * 4);
1628 sets the color of a client and broadcasts the update to all connected clients
1630 setcolor(clientent, value)
1633 /*void PF_setcolor (void)
1639 entnum = G_EDICTNUM(OFS_PARM0);
1640 i = G_FLOAT(OFS_PARM1);
1642 if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
1644 Con_Print("tried to setcolor a non-client\n");
1648 client = svs.clients + entnum-1;
1649 if ((val = GETEDICTFIELDVALUE(client->edict, eval_clientcolors)))
1652 client->old_colors = i;
1653 client->edict->v->team = (i & 15) + 1;
1655 MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
1656 MSG_WriteByte (&sv.reliable_datagram, entnum - 1);
1657 MSG_WriteByte (&sv.reliable_datagram, i);
1660 void VM_Files_Init(void)
1662 memset(VM_FILES, 0, sizeof(qfile_t*[MAX_VMFILES]));
1665 void VM_Files_CloseAll(void)
1668 for (i = 0;i < MAX_VMFILES;i++)
1671 FS_Close(VM_FILES[i]);
1672 //VM_FILES[i] = NULL;
1674 memset(VM_FILES,0,sizeof(qfile_t*[MAX_VMFILES])); // this should be faster (is it ?)
1681 float fopen(string filename, float mode)
1684 // float(string filename, float mode) fopen = #110;
1685 // opens a file inside quake/gamedir/data/ (mode is FILE_READ, FILE_APPEND, or FILE_WRITE),
1686 // returns fhandle >= 0 if successful, or fhandle < 0 if unable to open file for any reason
1690 char *modestring, *filename;
1692 VM_SAFEPARMCOUNT(2,VM_fopen);
1694 for (filenum = 0;filenum < MAX_VMFILES;filenum++)
1695 if (VM_FILES[filenum] == NULL)
1697 if (filenum >= MAX_VMFILES)
1699 Con_Printf("VM_fopen: %s ran out of file handles (%i)\n", PRVM_NAME, MAX_VMFILES);
1700 PRVM_G_FLOAT(OFS_RETURN) = -2;
1703 mode = PRVM_G_FLOAT(OFS_PARM1);
1706 case 0: // FILE_READ
1709 case 1: // FILE_APPEND
1712 case 2: // FILE_WRITE
1716 Con_Printf("VM_fopen: %s no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode);
1717 PRVM_G_FLOAT(OFS_RETURN) = -3;
1720 filename = PRVM_G_STRING(OFS_PARM0);
1721 // .. is parent directory on many platforms
1722 // / is parent directory on Amiga
1723 // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea)
1724 // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
1725 if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
1727 Con_Printf("VM_fopen: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
1728 PRVM_G_FLOAT(OFS_RETURN) = -4;
1731 VM_FILES[filenum] = FS_Open(va("data/%s", filename), modestring, false);
1732 if (VM_FILES[filenum] == NULL && mode == 0)
1733 VM_FILES[filenum] = FS_Open(va("%s", filename), modestring, false);
1735 if (VM_FILES[filenum] == NULL)
1736 PRVM_G_FLOAT(OFS_RETURN) = -1;
1738 PRVM_G_FLOAT(OFS_RETURN) = filenum;
1745 fclose(float fhandle)
1748 //void(float fhandle) fclose = #111; // closes a file
1749 void VM_fclose(void)
1753 VM_SAFEPARMCOUNT(1,VM_fclose);
1755 filenum = PRVM_G_FLOAT(OFS_PARM0);
1756 if (filenum < 0 || filenum >= MAX_VMFILES)
1758 Con_Printf("VM_fclose: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
1761 if (VM_FILES[filenum] == NULL)
1763 Con_Printf("VM_fclose: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
1766 FS_Close(VM_FILES[filenum]);
1767 VM_FILES[filenum] = NULL;
1774 string fgets(float fhandle)
1777 //string(float fhandle) fgets = #112; // reads a line of text from the file and returns as a tempstring
1781 static char string[VM_STRINGTEMP_LENGTH];
1784 VM_SAFEPARMCOUNT(1,VM_fgets);
1786 filenum = PRVM_G_FLOAT(OFS_PARM0);
1787 if (filenum < 0 || filenum >= MAX_VMFILES)
1789 Con_Printf("VM_fgets: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
1792 if (VM_FILES[filenum] == NULL)
1794 Con_Printf("VM_fgets: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
1800 c = FS_Getc(VM_FILES[filenum]);
1801 if (c == '\r' || c == '\n' || c < 0)
1803 if (end < VM_STRINGTEMP_LENGTH - 1)
1807 // remove \n following \r
1809 c = FS_Getc(VM_FILES[filenum]);
1810 if (developer.integer)
1811 Con_Printf("fgets: %s: %s\n", PRVM_NAME, string);
1813 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string);
1815 PRVM_G_INT(OFS_RETURN) = 0;
1822 fputs(float fhandle, string s)
1825 //void(float fhandle, string s) fputs = #113; // writes a line of text to the end of the file
1829 char string[VM_STRINGTEMP_LENGTH];
1832 VM_SAFEPARMCOUNT(2,VM_fputs);
1834 filenum = PRVM_G_FLOAT(OFS_PARM0);
1835 if (filenum < 0 || filenum >= MAX_VMFILES)
1837 Con_Printf("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
1840 if (VM_FILES[filenum] == NULL)
1842 Con_Printf("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
1845 VM_VarString(1, string, sizeof(string));
1846 if ((stringlength = strlen(string)))
1847 FS_Write(VM_FILES[filenum], string, stringlength);
1848 if (developer.integer)
1849 Con_Printf("fputs: %s: %s\n", PRVM_NAME, string);
1856 float strlen(string s)
1859 //float(string s) strlen = #114; // returns how many characters are in a string
1860 void VM_strlen(void)
1864 VM_SAFEPARMCOUNT(1,VM_strlen);
1866 s = PRVM_G_STRING(OFS_PARM0);
1868 PRVM_G_FLOAT(OFS_RETURN) = strlen(s);
1870 PRVM_G_FLOAT(OFS_RETURN) = 0;
1877 string strcat(string,string,...[string])
1880 //string(string s1, string s2) strcat = #115;
1881 // concatenates two strings (for example "abc", "def" would return "abcdef")
1882 // and returns as a tempstring
1883 void VM_strcat(void)
1888 PRVM_ERROR("VM_strcat wrong parameter count (min. 2 expected ) !\n");
1890 s = VM_GetTempString();
1891 VM_VarString(0, s, VM_STRINGTEMP_LENGTH);
1892 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
1899 string substring(string s, float start, float length)
1902 // string(string s, float start, float length) substring = #116;
1903 // returns a section of a string as a tempstring
1904 void VM_substring(void)
1906 int i, start, length;
1909 VM_SAFEPARMCOUNT(3,VM_substring);
1911 string = VM_GetTempString();
1912 s = PRVM_G_STRING(OFS_PARM0);
1913 start = PRVM_G_FLOAT(OFS_PARM1);
1914 length = PRVM_G_FLOAT(OFS_PARM2);
1917 for (i = 0;i < start && *s;i++, s++);
1918 for (i = 0;i < VM_STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++)
1921 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string);
1928 vector stov(string s)
1931 //vector(string s) stov = #117; // returns vector value from a string
1934 char string[VM_STRINGTEMP_LENGTH];
1936 VM_SAFEPARMCOUNT(1,VM_stov);
1938 VM_VarString(0, string, sizeof(string));
1939 Math_atov(string, PRVM_G_VECTOR(OFS_RETURN));
1946 string strzone(string s)
1949 //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)
1950 void VM_strzone(void)
1954 VM_SAFEPARMCOUNT(1,VM_strzone);
1956 in = PRVM_G_STRING(OFS_PARM0);
1957 out = Mem_Alloc(VM_STRINGS_MEMPOOL, strlen(in) + 1);
1959 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(out);
1969 //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!!!)
1970 void VM_strunzone(void)
1972 VM_SAFEPARMCOUNT(1,VM_strunzone);
1974 Mem_Free(PRVM_G_STRING(OFS_PARM0));
1979 VM_command (used by client and menu)
1981 clientcommand(float client, string s) (for client and menu)
1984 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
1985 //this function originally written by KrimZon, made shorter by LordHavoc
1986 void VM_clcommand (void)
1988 client_t *temp_client;
1991 VM_SAFEPARMCOUNT(2,VM_clcommand);
1993 i = PRVM_G_FLOAT(OFS_PARM0);
1994 if (!sv.active || i < 0 || i >= svs.maxclients || !svs.clients[i].active)
1996 Con_Printf("VM_clientcommand: %s: invalid client/server is not active !\n", PRVM_NAME);
2000 temp_client = host_client;
2001 host_client = svs.clients + i;
2002 Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client);
2003 host_client = temp_client;
2011 float tokenize(string s)
2014 //float(string s) tokenize = #441;
2015 // takes apart a string into individal words (access them with argv), returns how many
2016 // this function originally written by KrimZon, made shorter by LordHavoc
2017 static char **tokens = NULL;
2018 static int max_tokens, num_tokens = 0;
2019 void VM_tokenize (void)
2024 VM_SAFEPARMCOUNT(1,VM_tokenize);
2026 str = PRVM_G_STRING(OFS_PARM0);
2031 for (i=0;i<num_tokens;i++)
2037 tokens = Z_Malloc(strlen(str) * sizeof(char *));
2038 max_tokens = strlen(str);
2040 for (p = str;COM_ParseToken(&p, false) && num_tokens < max_tokens;num_tokens++)
2042 tokens[num_tokens] = Z_Malloc(strlen(com_token) + 1);
2043 strcpy(tokens[num_tokens], com_token);
2046 PRVM_G_FLOAT(OFS_RETURN) = num_tokens;
2053 string argv(float n)
2056 //string(float n) argv = #442;
2057 // returns a word from the tokenized string (returns nothing for an invalid index)
2058 // this function originally written by KrimZon, made shorter by LordHavoc
2063 VM_SAFEPARMCOUNT(1,VM_argv);
2065 token_num = PRVM_G_FLOAT(OFS_PARM0);
2066 if (token_num >= 0 && token_num < num_tokens)
2067 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tokens[token_num]);
2069 PRVM_G_INT(OFS_RETURN) = PRVM_SetString("");
2073 //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)
2074 void PF_setattachment (void)
2076 edict_t *e = G_EDICT(OFS_PARM0);
2077 edict_t *tagentity = G_EDICT(OFS_PARM1);
2078 char *tagname = G_STRING(OFS_PARM2);
2083 if (tagentity == NULL)
2084 tagentity = sv.edicts;
2086 v = GETEDICTFIELDVALUE(e, eval_tag_entity);
2088 v->edict = EDICT_TO_PROG(tagentity);
2090 v = GETEDICTFIELDVALUE(e, eval_tag_index);
2093 if (tagentity != NULL && tagentity != sv.edicts && tagname && tagname[0])
2095 modelindex = (int)tagentity->v->modelindex;
2096 if (modelindex >= 0 && modelindex < MAX_MODELS)
2098 model = sv.models[modelindex];
2099 if (model->data_overridetagnamesforskin && (unsigned int)tagentity->v->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames)
2100 for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++)
2101 if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name))
2103 // FIXME: use a model function to get tag info (need to handle skeletal)
2104 if (v->_float == 0 && model->alias.aliasnum_tags)
2105 for (i = 0;i < model->alias.aliasnum_tags;i++)
2106 if (!strcmp(tagname, model->alias.aliasdata_tags[i].name))
2109 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);
2112 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));
2123 void VM_isserver(void)
2125 VM_SAFEPARMCOUNT(0,VM_serverstate);
2127 PRVM_G_FLOAT(OFS_RETURN) = sv.active;
2137 void VM_clientcount(void)
2139 VM_SAFEPARMCOUNT(0,VM_clientcount);
2141 PRVM_G_FLOAT(OFS_RETURN) = svs.maxclients;
2151 void VM_clientstate(void)
2153 VM_SAFEPARMCOUNT(0,VM_clientstate);
2155 PRVM_G_FLOAT(OFS_RETURN) = cls.state;
2162 float getostype(void)
2164 */ // not used at the moment -> not included in the common list
2165 void VM_getostype(void)
2167 VM_SAFEPARMCOUNT(0,VM_getostype);
2172 OS_MAC - not supported
2176 PRVM_G_FLOAT(OFS_RETURN) = 0;
2178 PRVM_G_FLOAT(OFS_RETURN) = 2;
2180 PRVM_G_FLOAT(OFS_RETURN) = 1;
2188 vector getmousepos()
2191 void VM_getmousepos(void)
2194 VM_SAFEPARMCOUNT(0,VM_getmousepos);
2196 PRVM_G_VECTOR(OFS_RETURN)[0] = in_mouse_x;
2197 PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y;
2198 PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
2208 void VM_gettime(void)
2210 VM_SAFEPARMCOUNT(0,VM_gettime);
2212 PRVM_G_FLOAT(OFS_RETURN) = (float) *prog->time;
2219 loadfromdata(string data)
2222 void VM_loadfromdata(void)
2224 VM_SAFEPARMCOUNT(1,VM_loadentsfromfile);
2226 PRVM_ED_LoadFromFile(PRVM_G_STRING(OFS_PARM0));
2233 loadfromfile(string file)
2236 void VM_loadfromfile(void)
2241 VM_SAFEPARMCOUNT(1,VM_loadfromfile);
2243 filename = PRVM_G_STRING(OFS_PARM0);
2244 // .. is parent directory on many platforms
2245 // / is parent directory on Amiga
2246 // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea)
2247 // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
2248 if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
2250 Con_Printf("VM_loadfromfile: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
2251 PRVM_G_FLOAT(OFS_RETURN) = -4;
2255 // not conform with VM_fopen
2256 data = FS_LoadFile(filename, tempmempool, false);
2258 PRVM_G_FLOAT(OFS_RETURN) = -1;
2260 PRVM_ED_LoadFromFile(data);
2271 float mod(float val, float m)
2274 void VM_modulo(void)
2277 VM_SAFEPARMCOUNT(2,VM_module);
2279 val = (int) PRVM_G_FLOAT(OFS_PARM0);
2280 m = (int) PRVM_G_FLOAT(OFS_PARM1);
2282 PRVM_G_FLOAT(OFS_RETURN) = (float) (val % m);
2285 void VM_Search_Init(void)
2287 memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES]));
2290 void VM_Search_Reset(void)
2293 // reset the fssearch list
2294 for(i = 0; i < MAX_VMSEARCHES; i++)
2295 if(VM_SEARCHLIST[i])
2296 FS_FreeSearch(VM_SEARCHLIST[i]);
2297 memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES]));
2304 float search_begin(string pattern, float caseinsensitive, float quiet)
2307 void VM_search_begin(void)
2311 int caseinsens, quiet;
2313 VM_SAFEPARMCOUNT(3, VM_search_begin);
2315 pattern = PRVM_G_STRING(OFS_PARM0);
2317 VM_CheckEmptyString(pattern);
2319 caseinsens = PRVM_G_FLOAT(OFS_PARM1);
2320 quiet = PRVM_G_FLOAT(OFS_PARM2);
2322 for(handle = 0; handle < MAX_VMSEARCHES; handle++)
2323 if(!VM_SEARCHLIST[handle])
2326 if(handle >= MAX_VMSEARCHES)
2328 Con_Printf("VM_search_begin: %s ran out of search handles (%i)\n", PRVM_NAME, MAX_VMSEARCHES);
2329 PRVM_G_FLOAT(OFS_RETURN) = -2;
2333 if(!(VM_SEARCHLIST[handle] = FS_Search(pattern,caseinsens, quiet)))
2334 PRVM_G_FLOAT(OFS_RETURN) = -1;
2336 PRVM_G_FLOAT(OFS_RETURN) = handle;
2343 void search_end(float handle)
2346 void VM_search_end(void)
2349 VM_SAFEPARMCOUNT(1, VM_search_end);
2351 handle = PRVM_G_FLOAT(OFS_PARM0);
2353 if(handle < 0 || handle >= MAX_VMSEARCHES)
2355 Con_Printf("VM_search_end: invalid handle %i used in %s\n", handle, PRVM_NAME);
2358 if(VM_SEARCHLIST[handle] == NULL)
2360 Con_Printf("VM_search_end: no such handle %i in %s\n", handle, PRVM_NAME);
2364 FS_FreeSearch(VM_SEARCHLIST[handle]);
2365 VM_SEARCHLIST[handle] = NULL;
2372 float search_getsize(float handle)
2375 void VM_search_getsize(void)
2378 VM_SAFEPARMCOUNT(1, VM_M_search_getsize);
2380 handle = PRVM_G_FLOAT(OFS_PARM0);
2382 if(handle < 0 || handle >= MAX_VMSEARCHES)
2384 Con_Printf("VM_search_getsize: invalid handle %i used in %s\n", handle, PRVM_NAME);
2387 if(VM_SEARCHLIST[handle] == NULL)
2389 Con_Printf("VM_search_getsize: no such handle %i in %s\n", handle, PRVM_NAME);
2393 PRVM_G_FLOAT(OFS_RETURN) = VM_SEARCHLIST[handle]->numfilenames;
2398 VM_search_getfilename
2400 string search_getfilename(float handle, float num)
2403 void VM_search_getfilename(void)
2405 int handle, filenum;
2407 VM_SAFEPARMCOUNT(2, VM_search_getfilename);
2409 handle = PRVM_G_FLOAT(OFS_PARM0);
2410 filenum = PRVM_G_FLOAT(OFS_PARM1);
2412 if(handle < 0 || handle >= MAX_VMSEARCHES)
2414 Con_Printf("VM_search_getfilename: invalid handle %i used in %s\n", handle, PRVM_NAME);
2417 if(VM_SEARCHLIST[handle] == NULL)
2419 Con_Printf("VM_search_getfilename: no such handle %i in %s\n", handle, PRVM_NAME);
2422 if(filenum < 0 || filenum >= VM_SEARCHLIST[handle]->numfilenames)
2424 Con_Printf("VM_search_getfilename: invalid filenum %i in %s\n", filenum, PRVM_NAME);
2428 tmp = VM_GetTempString();
2429 strcpy(tmp, VM_SEARCHLIST[handle]->filenames[filenum]);
2431 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
2438 string chr(float ascii)
2444 VM_SAFEPARMCOUNT(1, VM_chr);
2446 tmp = VM_GetTempString();
2447 tmp[0] = (unsigned char) PRVM_G_FLOAT(OFS_PARM0);
2450 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
2453 //=============================================================================
2454 // Draw builtins (client & menu)
2460 float iscachedpic(string pic)
2463 void VM_iscachedpic(void)
2465 VM_SAFEPARMCOUNT(1,VM_iscachedpic);
2467 // drawq hasnt such a function, thus always return true
2468 PRVM_G_FLOAT(OFS_RETURN) = TRUE;
2475 string precache_pic(string pic)
2478 void VM_precache_pic(void)
2482 VM_SAFEPARMCOUNT(1, VM_precache_pic);
2484 s = PRVM_G_STRING(OFS_PARM0);
2485 PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
2488 PRVM_ERROR ("VM_precache_pic: %s: NULL\n", PRVM_NAME);
2490 VM_CheckEmptyString (s);
2492 if(!Draw_CachePic(s))
2493 PRVM_G_INT(OFS_RETURN) = PRVM_SetString("");
2503 void VM_freepic(void)
2507 VM_SAFEPARMCOUNT(1,VM_freepic);
2509 s = PRVM_G_STRING(OFS_PARM0);
2512 PRVM_ERROR ("VM_freepic: %s: NULL\n");
2514 VM_CheckEmptyString (s);
2523 float drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
2526 void VM_drawcharacter(void)
2528 float *pos,*scale,*rgb;
2531 VM_SAFEPARMCOUNT(6,VM_drawcharacter);
2533 character = (char) PRVM_G_FLOAT(OFS_PARM1);
2536 Con_Printf("VM_drawcharacter: %s passed null character !\n",PRVM_NAME);
2537 PRVM_G_FLOAT(OFS_RETURN) = -1;
2541 pos = PRVM_G_VECTOR(OFS_PARM0);
2542 scale = PRVM_G_VECTOR(OFS_PARM2);
2543 rgb = PRVM_G_VECTOR(OFS_PARM3);
2544 flag = (int)PRVM_G_FLOAT(OFS_PARM5);
2546 if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
2548 Con_Printf("VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
2549 PRVM_G_FLOAT(OFS_RETURN) = -2;
2553 if(pos[2] || scale[2])
2554 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")));
2556 if(!scale[0] || !scale[1])
2558 Con_Printf("VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
2559 PRVM_G_FLOAT(OFS_RETURN) = -3;
2563 DrawQ_String (pos[0], pos[1], &character, 1, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
2564 PRVM_G_FLOAT(OFS_RETURN) = 1;
2571 float drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
2574 void VM_drawstring(void)
2576 float *pos,*scale,*rgb;
2579 VM_SAFEPARMCOUNT(6,VM_drawstring);
2581 string = PRVM_G_STRING(OFS_PARM1);
2584 Con_Printf("VM_drawstring: %s passed null string !\n",PRVM_NAME);
2585 PRVM_G_FLOAT(OFS_RETURN) = -1;
2589 VM_CheckEmptyString(string);
2591 pos = PRVM_G_VECTOR(OFS_PARM0);
2592 scale = PRVM_G_VECTOR(OFS_PARM2);
2593 rgb = PRVM_G_VECTOR(OFS_PARM3);
2594 flag = (int)PRVM_G_FLOAT(OFS_PARM5);
2596 if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
2598 Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
2599 PRVM_G_FLOAT(OFS_RETURN) = -2;
2603 if(!scale[0] || !scale[1])
2605 Con_Printf("VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
2606 PRVM_G_FLOAT(OFS_RETURN) = -3;
2610 if(pos[2] || scale[2])
2611 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")));
2613 DrawQ_String (pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
2614 PRVM_G_FLOAT(OFS_RETURN) = 1;
2620 float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
2623 void VM_drawpic(void)
2626 float *size, *pos, *rgb;
2629 VM_SAFEPARMCOUNT(6,VM_drawpic);
2631 pic = PRVM_G_STRING(OFS_PARM1);
2635 Con_Printf("VM_drawpic: %s passed null picture name !\n", PRVM_NAME);
2636 PRVM_G_FLOAT(OFS_RETURN) = -1;
2640 VM_CheckEmptyString (pic);
2642 // is pic cached ? no function yet for that
2645 Con_Printf("VM_drawpic: %s: %s not cached !\n", PRVM_NAME, pic);
2646 PRVM_G_FLOAT(OFS_RETURN) = -4;
2650 pos = PRVM_G_VECTOR(OFS_PARM0);
2651 size = PRVM_G_VECTOR(OFS_PARM2);
2652 rgb = PRVM_G_VECTOR(OFS_PARM3);
2653 flag = (int) PRVM_G_FLOAT(OFS_PARM5);
2655 if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
2657 Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
2658 PRVM_G_FLOAT(OFS_RETURN) = -2;
2662 if(pos[2] || size[2])
2663 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")));
2665 DrawQ_Pic(pos[0], pos[1], pic, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
2666 PRVM_G_FLOAT(OFS_RETURN) = 1;
2673 float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
2676 void VM_drawfill(void)
2678 float *size, *pos, *rgb;
2681 VM_SAFEPARMCOUNT(5,VM_drawfill);
2684 pos = PRVM_G_VECTOR(OFS_PARM0);
2685 size = PRVM_G_VECTOR(OFS_PARM1);
2686 rgb = PRVM_G_VECTOR(OFS_PARM2);
2687 flag = (int) PRVM_G_FLOAT(OFS_PARM4);
2689 if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
2691 Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
2692 PRVM_G_FLOAT(OFS_RETURN) = -2;
2696 if(pos[2] || size[2])
2697 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")));
2699 DrawQ_Pic(pos[0], pos[1], 0, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM3), flag);
2700 PRVM_G_FLOAT(OFS_RETURN) = 1;
2707 drawsetcliparea(float x, float y, float width, float height)
2710 void VM_drawsetcliparea(void)
2713 VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
2715 x = bound(0,PRVM_G_FLOAT(OFS_PARM0),vid.conwidth);
2716 y = bound(0,PRVM_G_FLOAT(OFS_PARM1),vid.conheight);
2717 w = bound(0,PRVM_G_FLOAT(OFS_PARM2),(vid.conwidth - x));
2718 h = bound(0,PRVM_G_FLOAT(OFS_PARM3),(vid.conheight - y));
2720 DrawQ_SetClipArea(x,y,w,h);
2725 VM_drawresetcliparea
2730 void VM_drawresetcliparea(void)
2732 VM_SAFEPARMCOUNT(0,VM_drawresetcliparea);
2734 DrawQ_ResetClipArea();
2741 vector getimagesize(string pic)
2744 void VM_getimagesize(void)
2749 VM_SAFEPARMCOUNT(1,VM_getimagesize);
2751 p = PRVM_G_STRING(OFS_PARM0);
2754 PRVM_ERROR("VM_getimagepos: %s passed null picture name !\n", PRVM_NAME);
2756 VM_CheckEmptyString (p);
2758 pic = Draw_CachePic (p);
2760 PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width;
2761 PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height;
2762 PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
2765 void VM_Cmd_Init(void)
2767 // only init the stuff for the current prog
2768 VM_STRINGS_MEMPOOL = Mem_AllocPool(va("vm_stringsmempool[%s]",PRVM_NAME), 0, NULL);
2773 void VM_Cmd_Reset(void)
2775 //Mem_EmptyPool(VM_STRINGS_MEMPOOL);
2776 Mem_FreePool(&VM_STRINGS_MEMPOOL);
2778 VM_Files_CloseAll();
2781 //============================================================================
2784 char *vm_sv_extensions =
2787 prvm_builtin_t vm_sv_builtins[] = {
2788 0 // to be consistent with the old vm
2791 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
2793 void VM_SV_Cmd_Init(void)
2797 void VM_SV_Cmd_Reset(void)
2801 //============================================================================
2804 char *vm_cl_extensions =
2807 prvm_builtin_t vm_cl_builtins[] = {
2808 0 // to be consistent with the old vm
2811 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
2813 void VM_CL_Cmd_Init(void)
2817 void VM_CL_Cmd_Reset(void)
2821 //============================================================================
2824 char *vm_m_extensions =
2831 setmousetarget(float target)
2834 void VM_M_setmousetarget(void)
2836 VM_SAFEPARMCOUNT(1, VM_M_setmousetarget);
2838 switch((int)PRVM_G_FLOAT(OFS_PARM0))
2841 in_client_mouse = false;
2844 in_client_mouse = true;
2847 PRVM_ERROR("VM_M_setmousetarget: wrong destination %i !\n",PRVM_G_FLOAT(OFS_PARM0));
2855 float getmousetarget
2858 void VM_M_getmousetarget(void)
2860 VM_SAFEPARMCOUNT(0,VM_M_getmousetarget);
2863 PRVM_G_FLOAT(OFS_RETURN) = 2;
2865 PRVM_G_FLOAT(OFS_RETURN) = 1;
2874 setkeydest(float dest)
2877 void VM_M_setkeydest(void)
2879 VM_SAFEPARMCOUNT(1,VM_M_setkeydest);
2881 switch((int)PRVM_G_FLOAT(OFS_PARM0))
2885 key_dest = key_game;
2889 key_dest = key_menu;
2893 // key_dest = key_message
2896 PRVM_ERROR("VM_M_setkeydest: wrong destination %i !\n",prog->globals[OFS_PARM0]);
2907 void VM_M_getkeydest(void)
2909 VM_SAFEPARMCOUNT(0,VM_M_getkeydest);
2911 // key_game = 0, key_message = 1, key_menu = 2, unknown = 3
2915 PRVM_G_FLOAT(OFS_RETURN) = 0;
2918 PRVM_G_FLOAT(OFS_RETURN) = 2;
2922 // PRVM_G_FLOAT(OFS_RETURN) = 1;
2925 PRVM_G_FLOAT(OFS_RETURN) = 3;
2933 callfunction(...,string function_name)
2936 mfunction_t *PRVM_ED_FindFunction (const char *name);
2937 void VM_M_callfunction(void)
2943 PRVM_ERROR("VM_M_callfunction: 1 parameter is required !\n");
2945 s = PRVM_G_STRING(OFS_PARM0 + (prog->argc - 1));
2948 PRVM_ERROR("VM_M_callfunction: null string !\n");
2950 VM_CheckEmptyString(s);
2952 func = PRVM_ED_FindFunction(s);
2955 PRVM_ERROR("VM_M_callfunciton: function %s not found !\n", s);
2956 else if (func->first_statement < 0)
2958 // negative statements are built in functions
2959 int builtinnumber = -func->first_statement;
2960 prog->xfunction->builtinsprofile++;
2961 if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
2962 prog->builtins[builtinnumber]();
2964 PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
2969 PRVM_ExecuteProgram(func - prog->functions,"");
2978 float isfunction(string function_name)
2981 mfunction_t *PRVM_ED_FindFunction (const char *name);
2982 void VM_M_isfunction(void)
2987 VM_SAFEPARMCOUNT(1, VM_M_isfunction);
2989 s = PRVM_G_STRING(OFS_PARM0);
2992 PRVM_ERROR("VM_M_isfunction: null string !\n");
2994 VM_CheckEmptyString(s);
2996 func = PRVM_ED_FindFunction(s);
2999 PRVM_G_FLOAT(OFS_RETURN) = false;
3001 PRVM_G_FLOAT(OFS_RETURN) = true;
3008 writetofile(float fhandle, entity ent)
3011 void VM_M_writetofile(void)
3016 VM_SAFEPARMCOUNT(2, VM_M_writetofile);
3018 filenum = PRVM_G_FLOAT(OFS_PARM0);
3019 if (filenum < 0 || filenum >= MAX_VMFILES)
3021 Con_Printf("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
3024 if (VM_FILES[filenum] == NULL)
3026 Con_Printf("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
3030 ent = PRVM_G_EDICT(OFS_PARM1);
3033 Con_Printf("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_EDICT_NUM(OFS_PARM1));
3037 PRVM_ED_Write (VM_FILES[filenum], ent);
3044 vector getresolution(float number)
3047 extern unsigned short video_resolutions[][2];
3048 void VM_M_getresolution(void)
3051 VM_SAFEPARMCOUNT(1, VM_getresolution);
3053 nr = PRVM_G_FLOAT(OFS_PARM0);
3056 PRVM_G_VECTOR(OFS_RETURN)[0] = video_resolutions[nr][0];
3057 PRVM_G_VECTOR(OFS_RETURN)[1] = video_resolutions[nr][1];
3058 PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
3065 string keynumtostring(float keynum)
3068 void VM_M_keynumtostring(void)
3072 VM_SAFEPARMCOUNT(1, VM_M_keynumtostring);
3074 keynum = PRVM_G_FLOAT(OFS_PARM0);
3076 tmp = VM_GetTempString();
3078 strcpy(tmp, Key_KeynumToString(keynum));
3080 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
3085 VM_M_findkeysforcommand
3087 string findkeysforcommand(string command)
3089 the returned string is an altstring
3092 #define NUMKEYS 5 // TODO: merge the constant in keys.c with this one somewhen
3094 void M_FindKeysForCommand(char *command, int *keys);
3095 void VM_M_findkeysforcommand(void)
3101 VM_SAFEPARMCOUNT(1, VM_M_findkeysforcommand);
3103 cmd = PRVM_G_STRING(OFS_PARM0);
3105 VM_CheckEmptyString(cmd);
3107 (ret = VM_GetTempString())[0] = 0;
3109 M_FindKeysForCommand(cmd, keys);
3111 for(i = 0; i < NUMKEYS; i++)
3112 ret = strcat(ret, va(" \'%i\'", keys[i]));
3114 PRVM_G_INT(OFS_RETURN) = PRVM_SetString(ret);
3119 VM_M_gethostcachecount
3121 float gethostcachevalue(float type)
3132 void VM_M_gethostcachevalue( void )
3135 VM_SAFEPARMCOUNT ( 1, VM_M_gethostcachevalue );
3137 PRVM_G_FLOAT( OFS_RETURN ) = 0;
3139 type = PRVM_G_FLOAT( OFS_PARM0 );
3140 if( type < 0 || type > 4 )
3141 Con_Printf( "VM_M_gethostcachevalue: bad type %i!\n", type );
3145 PRVM_G_FLOAT ( OFS_RETURN ) = hostCacheCount;
3148 PRVM_G_FLOAT ( OFS_RETURN ) = masterquerycount;
3151 PRVM_G_FLOAT ( OFS_RETURN ) = masterreplycount;
3154 PRVM_G_FLOAT ( OFS_RETURN ) = serverquerycount;
3157 PRVM_G_FLOAT ( OFS_RETURN ) = serverreplycount;
3164 VM_M_gethostcachestring
3166 string gethostcachestring(float type, float hostnr)
3174 void VM_M_gethostcachestring(void)
3179 VM_SAFEPARMCOUNT(2, VM_M_gethostcachestring);
3181 PRVM_G_INT(OFS_RETURN) = 0;
3183 type = PRVM_G_FLOAT(OFS_PARM0);
3185 if(type < 0 || type > 2)
3187 Con_Print("VM_M_gethostcachestring: bad string type requested!\n");
3191 hostnr = PRVM_G_FLOAT(OFS_PARM1);
3193 if(hostnr < 0 || hostnr >= hostCacheCount)
3195 Con_Print("VM_M_gethostcachestring: bad hostnr passed!\n");
3200 PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].cname );
3201 else if( type == 1 )
3202 PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].line1 );
3204 PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].line2 );
3207 prvm_builtin_t vm_m_builtins[] = {
3208 0, // to be consistent with the old vm
3209 // common builtings (mostly)
3286 VM_search_getfilename, // 77
3302 VM_WriteEntity, // 408
3318 VM_drawresetcliparea,
3319 VM_getimagesize,// 460
3328 VM_M_setmousetarget,
3329 VM_M_getmousetarget,
3334 VM_M_keynumtostring,
3335 VM_M_findkeysforcommand,// 610
3336 VM_M_gethostcachevalue,
3337 VM_M_gethostcachestring // 612
3340 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
3342 void VM_M_Cmd_Init(void)
3347 void VM_M_Cmd_Reset(void)