]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
Oops... It seems this malloc/free was actually intended (part of a piece of code...
[xonotic/darkplaces.git] / prvm_cmds.c
index f09fe8720a5f079a16d744e4bd2fb30088bcc541..f19deb65613ffa2d1f1eea3d1603b09f076daa3d 100644 (file)
@@ -1,11 +1,12 @@
 // AK
 // Basically every vm builtin cmd should be in here.
 // AK
 // Basically every vm builtin cmd should be in here.
-// All 3 builtin list and extension lists can be found here
-// cause large (I think they will) are from pr_cmds the same copyright like in pr_cms
+// All 3 builtin and extension lists can be found here
+// cause large (I think they will) parts are from pr_cmds the same copyright like in pr_cmds
 // also applies here
 
 
 // also applies here
 
 
-/*============================================================================
+/*
+============================================================================
 common cmd list:
 =================
 
 common cmd list:
 =================
 
@@ -13,6 +14,8 @@ common cmd list:
                error(...[string])
                objerror(...[string)
                print(...[strings])
                error(...[string])
                objerror(...[string)
                print(...[strings])
+               bprint(...[string])
+               sprint(float clientnum,...[string])
                centerprint(...[string])
 vector normalize(vector)
 float  vlen(vector)
                centerprint(...[string])
 vector normalize(vector)
 float  vlen(vector)
@@ -29,21 +32,23 @@ string      vtos(vector)
 string etos(entity)
 float  stof(...[string])
 entity spawn()
 string etos(entity)
 float  stof(...[string])
 entity spawn()
-entity remove()
+               remove(entity e)
 entity find(entity start, .string field, string match)
 
 entity find(entity start, .string field, string match)
 
-entity findfloat(entity start, .float field, string match)
-entity findentity(entity start, .entity field, string match)
+entity findfloat(entity start, .float field, float match)
+entity findentity(entity start, .entity field, entity match)
 
 entity findchain(.string field, string match)
 
 entity findchainfloat(.string field, float match)
 entity findchainentity(.string field, entity match)
 
 entity findchain(.string field, string match)
 
 entity findchainfloat(.string field, float match)
 entity findchainentity(.string field, entity match)
-
+  
+string precache_file(string)
+string precache_sound (string sample)
                coredump()
                traceon()
                traceoff()
                coredump()
                traceon()
                traceoff()
-               eprint()
+               eprint(entity e)
 float  rint(float)
 float  floor(float)
 float  ceil(float)
 float  rint(float)
 float  floor(float)
 float  ceil(float)
@@ -51,8 +56,8 @@ entity        nextent(entity)
 float  sin(float)
 float  cos(float)
 float  sqrt(float)
 float  sin(float)
 float  cos(float)
 float  sqrt(float)
-               randomvec()
-float  registercvar (string name, string value)
+vector randomvec()
+float  registercvar (string name, string value, float flags)
 float  min(float a, float b, ...[float])
 float  max(float a, float b, ...[float])
 float  bound(float min, float value, float max)
 float  min(float a, float b, ...[float])
 float  max(float a, float b, ...[float])
 float  bound(float min, float value, float max)
@@ -63,16 +68,80 @@ float       fopen(string filename, float mode)
 string fgets(float fhandle)
                fputs(float fhandle, string s)
 float  strlen(string s)
 string fgets(float fhandle)
                fputs(float fhandle, string s)
 float  strlen(string s)
-string strcat(string s1, string s2)
+string strcat(string,string,...[string])
 string substring(string s, float start, float length)
 vector stov(string s)
 string strzone(string s)
 string substring(string s, float start, float length)
 vector stov(string s)
 string strzone(string s)
-               strzone(string s)
+               strunzone(string s)
+float  tokenize(string s)
+string argv(float n)
 float  isserver()
 float  clientcount()
 float  clientstate()
                clientcommand(float client, string s) (for client and menu)
 float  isserver()
 float  clientcount()
 float  clientstate()
                clientcommand(float client, string s) (for client and menu)
-float  tokenize(string s)
+               changelevel(string map)
+               localsound(string sample)
+vector getmousepos()
+float  gettime()
+               loadfromdata(string data)
+               loadfromfile(string file)
+float  mod(float val, float m)
+const string   str_cvar (string)
+               crash()
+               stackdump()
+               
+float  search_begin(string pattern, float caseinsensitive, float quiet)
+void   search_end(float handle)
+float  search_getsize(float handle)
+string search_getfilename(float handle, float num)
+
+string chr(float ascii)
+               
+perhaps only : Menu : WriteMsg 
+===============================
+
+               WriteByte(float data, float dest, float desto)
+               WriteChar(float data, float dest, float desto)
+               WriteShort(float data, float dest, float desto)
+               WriteLong(float data, float dest, float desto)
+               WriteAngle(float data, float dest, float desto)
+               WriteCoord(float data, float dest, float desto)
+               WriteString(string data, float dest, float desto)
+               WriteEntity(entity data, float dest, float desto)
+               
+Client & Menu : draw functions 
+===============================
+
+float  iscachedpic(string pic)
+string precache_pic(string pic) 
+               freepic(string s)
+float  drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
+float  drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
+float  drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
+float  drawfill(vector position, vector size, vector rgb, float alpha, float flag)
+               drawsetcliparea(float x, float y, float width, float height)
+               drawresetcliparea()
+vector getimagesize(string pic)
+               
+
+==============================================================================
+menu cmd list:
+===============
+
+               setkeydest(float dest)
+float  getkeydest()
+               setmousetarget(float target)
+float  getmousetarget(void)
+
+               callfunction(...,string function_name)
+               writetofile(float fhandle, entity ent)
+float  isfunction(string function_name)
+vector getresolution(float number)
+string keynumtostring(float keynum)
+string findkeysforcommand(string command)
+float  gethostcachevalue(float type)
+string gethostcachestring(float type, float hostnr)
+
 
 */
 
 
 */
 
@@ -85,7 +154,7 @@ float        tokenize(string s)
 // nice helper macros
 
 #ifndef VM_NOPARMCHECK
 // nice helper macros
 
 #ifndef VM_NOPARMCHECK
-#define VM_SAFEPARMCOUNT(p,f)  if(prog->argc != p) PRVM_ERROR(#f "wrong parameter count (" #p "expected ) !\n")
+#define VM_SAFEPARMCOUNT(p,f)  if(prog->argc != p) PRVM_ERROR(#f " wrong parameter count (" #p " expected ) !\n")
 #else
 #define VM_SAFEPARMCOUNT(p,f)
 #endif
 #else
 #define VM_SAFEPARMCOUNT(p,f)
 #endif
@@ -100,34 +169,44 @@ float     tokenize(string s)
 
 //============================================================================
 // Common
 
 //============================================================================
 // Common
-cvar_t vm_zone_min_strings = {0, "prvm_zone_min_strings", "64"};
 
 
+// string zone mempool
 mempool_t *vm_strings_mempool[PRVM_MAXPROGS];
 
 mempool_t *vm_strings_mempool[PRVM_MAXPROGS];
 
-/*
-typedef struct vm_string_s
-{
-       int prog_id;
-       // here follows everything else
-       char string[0];
-} vm_string_t;
-*/
-
+// temp string handling
 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
-#define STRINGTEMP_BUFFERS 16
-#define STRINGTEMP_LENGTH 4096
-static char vm_string_temp[STRINGTEMP_BUFFERS][STRINGTEMP_LENGTH];
+#define VM_STRINGTEMP_BUFFERS 16
+#define VM_STRINGTEMP_LENGTH 4096
+static char vm_string_temp[VM_STRINGTEMP_BUFFERS][VM_STRINGTEMP_LENGTH];
 static int vm_string_tempindex = 0;
 
 static int vm_string_tempindex = 0;
 
+// qc cvar 
+#define MAX_QC_CVARS 128 * PRVM_MAXPROGS
+cvar_t vm_qc_cvar[MAX_QC_CVARS];
+int vm_currentqc_cvar;
+
+// qc file handling
+#define MAX_VMFILES            256
+#define MAX_PRVMFILES  MAX_VMFILES * PRVM_MAXPROGS
+#define VM_FILES ((qfile_t**)(vm_files + PRVM_GetProgNr() * MAX_VMFILES))
+
+qfile_t *vm_files[MAX_PRVMFILES];
+
+// qc fs search handling
+#define MAX_VMSEARCHES 128
+#define TOTAL_VMSEARCHES MAX_VMSEARCHES * PRVM_MAXPROGS
+#define VM_SEARCHLIST ((fssearch_t**)(vm_fssearchlist + PRVM_GetProgNr() * MAX_VMSEARCHES))
+
+fssearch_t *vm_fssearchlist[TOTAL_VMSEARCHES];
+
 static char *VM_GetTempString(void)
 {
        char *s;
        s = vm_string_temp[vm_string_tempindex];
 static char *VM_GetTempString(void)
 {
        char *s;
        s = vm_string_temp[vm_string_tempindex];
-       vm_string_tempindex = (vm_string_tempindex + 1) % STRINGTEMP_BUFFERS;
+       vm_string_tempindex = (vm_string_tempindex + 1) % VM_STRINGTEMP_BUFFERS;
        return s;
 }
 
        return s;
 }
 
-
 void VM_CheckEmptyString (char *s)
 {
        if (s[0] <= ' ')
 void VM_CheckEmptyString (char *s)
 {
        if (s[0] <= ' ')
@@ -144,7 +223,7 @@ void VM_VarString(int first, char *out, int outlength)
        char *outend;
 
        outend = out + outlength - 1;
        char *outend;
 
        outend = out + outlength - 1;
-       for (i = first;i < pr_argc && out < outend;i++)
+       for (i = first;i < prog->argc && out < outend;i++)
        {
                s = PRVM_G_STRING((OFS_PARM0+i*3));
                while (out < outend && *s)
        {
                s = PRVM_G_STRING((OFS_PARM0+i*3));
                while (out < outend && *s)
@@ -205,17 +284,17 @@ Dumps self.
 error(value)
 =================
 */
 error(value)
 =================
 */
-void VM_Error (void)
+void VM_error (void)
 {
        prvm_edict_t    *ed;
 {
        prvm_edict_t    *ed;
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
 
        VM_VarString(0, string, sizeof(string));
 
        VM_VarString(0, string, sizeof(string));
-       Con_Printf ("======%S ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
+       Con_Printf("======%S ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
        if(prog->self)
        {
                ed = PRVM_G_EDICT(prog->self->ofs);
        if(prog->self)
        {
                ed = PRVM_G_EDICT(prog->self->ofs);
-               PRVM_ED_Print (ed);
+               PRVM_ED_Print(ed);
        }
 
        PRVM_ERROR ("%s: Program error", PRVM_NAME);
        }
 
        PRVM_ERROR ("%s: Program error", PRVM_NAME);
@@ -234,14 +313,15 @@ objerror(value)
 void VM_objerror (void)
 {
        prvm_edict_t    *ed;
 void VM_objerror (void)
 {
        prvm_edict_t    *ed;
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
 
        VM_VarString(0, string, sizeof(string));
 
        VM_VarString(0, string, sizeof(string));
-       Con_Printf ("======%s OBJECT ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
+       Con_Printf("======%s OBJECT ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
        if(prog->self)
        {
                ed = PRVM_G_EDICT (prog->self->ofs);
        if(prog->self)
        {
                ed = PRVM_G_EDICT (prog->self->ofs);
-               PRVM_ED_Print (ed);
+               PRVM_ED_Print(ed);
+
                PRVM_ED_Free (ed);
        }
        else
                PRVM_ED_Free (ed);
        }
        else
@@ -260,12 +340,66 @@ print(string)
 */
 void VM_print (void)
 {
 */
 void VM_print (void)
 {
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
 
        VM_VarString(0, string, sizeof(string));
        Con_Print(string);
 }
 
 
        VM_VarString(0, string, sizeof(string));
        Con_Print(string);
 }
 
+/*
+=================
+VM_bprint
+
+broadcast print to everyone on server
+
+bprint(...[string])
+=================
+*/
+void VM_bprint (void)
+{
+       char string[VM_STRINGTEMP_LENGTH];
+
+       if(!sv.active)
+       {
+               Con_Printf("VM_bprint: game is not server(%s) !\n", PRVM_NAME);
+               return;
+       }
+
+       VM_VarString(0, string, sizeof(string));
+       SV_BroadcastPrint(string);
+}
+
+/*
+=================
+VM_sprint (menu & client but only if server.active == true)
+
+single print to a specific client
+
+sprint(float clientnum,...[string])
+=================
+*/
+void VM_sprint (void)
+{
+       client_t        *client;
+       int                     clientnum;
+       char string[VM_STRINGTEMP_LENGTH];
+
+       //find client for this entity
+       clientnum = PRVM_G_FLOAT(OFS_PARM0);
+       if (!sv.active  || clientnum < 0 || clientnum >= svs.maxclients || !svs.clients[clientnum].active)
+       {
+               Con_Printf("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME);
+               return;
+       }
+       
+       client = svs.clients + clientnum;
+       if (!client->netconnection)
+               return;
+       VM_VarString(1, string, sizeof(string));
+       MSG_WriteChar(&client->message,svc_print);
+       MSG_WriteString(&client->message, string);
+}
+
 /*
 =================
 VM_centerprint
 /*
 =================
 VM_centerprint
@@ -277,7 +411,7 @@ centerprint(clientent, value)
 */
 void VM_centerprint (void)
 {
 */
 void VM_centerprint (void)
 {
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
 
        VM_VarString(0, string, sizeof(string));
        SCR_CenterPrint(string);
 
        VM_VarString(0, string, sizeof(string));
        SCR_CenterPrint(string);
@@ -480,6 +614,32 @@ void PF_sound (void)
 }
 */
 
 }
 */
 
+/*
+=========
+VM_localsound
+
+localsound(string sample)
+=========
+*/
+void VM_localsound(void)
+{
+       char *s;
+       
+       VM_SAFEPARMCOUNT(1,VM_localsound);
+
+       s = PRVM_G_STRING(OFS_PARM0);
+
+       if(!S_GetCached(s))
+       {
+               Con_Printf("VM_localsound: %s : %s not cached !\n", PRVM_NAME, s);
+               PRVM_G_FLOAT(OFS_RETURN) = -4;
+               return;
+       }               
+
+       S_LocalSound(s);
+       PRVM_G_FLOAT(OFS_RETURN) = 1;
+}
+
 /*
 =================
 VM_break
 /*
 =================
 VM_break
@@ -494,11 +654,6 @@ void VM_break (void)
 
 //============================================================================
 
 
 //============================================================================
 
-int checkpvsbytes;
-qbyte checkpvs[MAX_MAP_LEAFS/8];
-
-//============================================================================
-
 /*
 =================
 VM_localcmd
 /*
 =================
 VM_localcmd
@@ -530,6 +685,35 @@ void VM_cvar (void)
        PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0));
 }
 
        PRVM_G_FLOAT(OFS_RETURN) = Cvar_VariableValue(PRVM_G_STRING(OFS_PARM0));
 }
 
+/*
+=================
+VM_str_cvar
+
+const string   str_cvar (string)
+=================
+*/
+void VM_str_cvar(void) 
+{
+       char *out, *name;
+       const char *cvar_string;
+       VM_SAFEPARMCOUNT(1,VM_str_cvar);
+
+       name = PRVM_G_STRING(OFS_PARM0);
+
+       if(!name)
+               PRVM_ERROR("VM_str_cvar: %s: null string\n", PRVM_NAME);
+
+       VM_CheckEmptyString(name);
+
+       out = VM_GetTempString(); 
+
+       cvar_string = Cvar_VariableString(name);
+       
+       strcpy(out, cvar_string);
+
+       PRVM_G_INT(OFS_PARM0) = PRVM_SetString(out);
+}
+
 /*
 =================
 VM_cvar_set
 /*
 =================
 VM_cvar_set
@@ -553,7 +737,7 @@ dprint(...[string])
 */
 void VM_dprint (void)
 {
 */
 void VM_dprint (void)
 {
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
        if (developer.integer)
        {
                VM_VarString(0, string, sizeof(string));
        if (developer.integer)
        {
                VM_VarString(0, string, sizeof(string));
@@ -651,7 +835,7 @@ float stof(...[string])
 */
 void VM_stof(void)
 {
 */
 void VM_stof(void)
 {
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
        VM_VarString(0, string, sizeof(string));
        PRVM_G_FLOAT(OFS_RETURN) = atof(string);
 }
        VM_VarString(0, string, sizeof(string));
        PRVM_G_FLOAT(OFS_RETURN) = atof(string);
 }
@@ -664,7 +848,7 @@ entity spawn()
 =========
 */
 
 =========
 */
 
-void VM_Spawn (void)
+void VM_spawn (void)
 {
        prvm_edict_t    *ed;
        prog->xfunction->builtinsprofile += 20;
 {
        prvm_edict_t    *ed;
        prog->xfunction->builtinsprofile += 20;
@@ -739,15 +923,15 @@ void VM_find (void)
                }
        }
 
                }
        }
 
-       VM_RETURN_EDICT(sv.edicts);
+       VM_RETURN_EDICT(prog->edicts);
 }
 
 /*
 =========
 VM_findfloat
 
 }
 
 /*
 =========
 VM_findfloat
 
-  entity       findfloat(entity start, .float field, string match)
-  entity       findentity(entity start, .entity field, string match)
+  entity       findfloat(entity start, .float field, float match)
+  entity       findentity(entity start, .entity field, entity match)
 =========
 */
 // LordHavoc: added this for searching float, int, and entity reference fields
 =========
 */
 // LordHavoc: added this for searching float, int, and entity reference fields
@@ -885,7 +1069,7 @@ void VM_findchainfloat (void)
 =========
 VM_precache_file
 
 =========
 VM_precache_file
 
-precache_file
+string precache_file(string)
 =========
 */
 void VM_precache_file (void)
 =========
 */
 void VM_precache_file (void)
@@ -912,32 +1096,28 @@ void VM_precache_error (void)
 =========
 VM_precache_sound
 
 =========
 VM_precache_sound
 
+string precache_sound (string sample)
 =========
 */
 =========
 */
-/*
 void VM_precache_sound (void)
 {
        char    *s;
 void VM_precache_sound (void)
 {
        char    *s;
-       int             i;
 
        VM_SAFEPARMCOUNT(1, VM_precache_sound);
 
        s = PRVM_G_STRING(OFS_PARM0);
        PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
        VM_CheckEmptyString (s);
 
        VM_SAFEPARMCOUNT(1, VM_precache_sound);
 
        s = PRVM_G_STRING(OFS_PARM0);
        PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
        VM_CheckEmptyString (s);
-
-       for (i=0 ; i < MAX_SOUNDS ; i++)
+       
+       if(S_GetCached(s))
        {
        {
-               if (!sv.sound_precache[i])
-               {
-                       sv.sound_precache[i] = s;
-                       return;
-               }
-               if (!strcmp(sv.sound_precache[i], s))
-                       return;
+               Con_Printf("VM_precache_sound: %s already cached (%s)\n", s, PRVM_NAME);
+               return;
        }
        }
-       Host_Error ("PF_precache_sound: overflow");
-}*/
+       
+       if(!S_PrecacheSound(s,true))
+               Con_Printf("VM_prache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
+}
 
 /*
 =========
 
 /*
 =========
@@ -950,7 +1130,39 @@ void VM_coredump (void)
 {
        VM_SAFEPARMCOUNT(0,VM_coredump);
 
 {
        VM_SAFEPARMCOUNT(0,VM_coredump);
 
-       PRVM_ED_PrintEdicts_f ();
+       Cbuf_AddText("prvm_edicts ");
+       Cbuf_AddText(PRVM_NAME);
+       Cbuf_AddText("\n");
+}
+
+/*
+=========
+VM_stackdump
+
+stackdump()
+=========
+*/
+void PRVM_StackTrace(void);
+void VM_stackdump (void)
+{
+       VM_SAFEPARMCOUNT(0, VM_stackdump);
+
+       PRVM_StackTrace();
+}
+
+/*
+=========
+VM_crash
+
+crash()
+=========
+*/
+
+void VM_crash(void) 
+{
+       VM_SAFEPARMCOUNT(0, VM_crash);
+
+       PRVM_ERROR("Crash called by %s\n",PRVM_NAME);
 }
 
 /*
 }
 
 /*
@@ -985,7 +1197,7 @@ void VM_traceoff (void)
 =========
 VM_eprint
 
 =========
 VM_eprint
 
-eprint()
+eprint(entity e)
 =========
 */
 void VM_eprint (void)
 =========
 */
 void VM_eprint (void)
@@ -1075,17 +1287,120 @@ void VM_nextent (void)
        }
 }
 
        }
 }
 
+/*
+===============================================================================
+MESSAGE WRITING
+
+used only for client and menu
+severs uses VM_SV_...
+
+Write*(* data, float type, float to)
+
+===============================================================================
+*/
+
+#define        MSG_BROADCAST   0               // unreliable to all
+#define        MSG_ONE                 1               // reliable to one (msg_entity)
+#define        MSG_ALL                 2               // reliable to all
+#define        MSG_INIT                3               // write to the init string
+
+sizebuf_t *VM_WriteDest (void)
+{
+       int             dest;
+       int             destclient;
+
+       if(!sv.active)
+               PRVM_ERROR("VM_WriteDest: game is not server (%s)\n", PRVM_NAME);
+
+       dest = G_FLOAT(OFS_PARM1);
+       switch (dest)
+       {
+       case MSG_BROADCAST:
+               return &sv.datagram;
+
+       case MSG_ONE:
+               destclient = (int) PRVM_G_FLOAT(OFS_PARM2);
+               if (destclient < 0 || destclient >= svs.maxclients || !svs.clients[destclient].active)
+                       PRVM_ERROR("VM_clientcommand: %s: invalid client !\n", PRVM_NAME);
+
+               return &svs.clients[destclient].message;
+
+       case MSG_ALL:
+               return &sv.reliable_datagram;
+
+       case MSG_INIT:
+               return &sv.signon;
+
+       default:
+               PRVM_ERROR ("WriteDest: bad destination");
+               break;
+       }
+
+       return NULL;
+}
+
+void VM_WriteByte (void)
+{
+       MSG_WriteByte (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_WriteChar (void)
+{
+       MSG_WriteChar (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_WriteShort (void)
+{
+       MSG_WriteShort (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_WriteLong (void)
+{
+       MSG_WriteLong (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_WriteAngle (void)
+{
+       MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_WriteCoord (void)
+{
+       MSG_WriteDPCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+}
+
+void VM_WriteString (void)
+{
+       MSG_WriteString (VM_WriteDest(), PRVM_G_STRING(OFS_PARM0));
+}
+
+void VM_WriteEntity (void)
+{
+       MSG_WriteShort (VM_WriteDest(), PRVM_G_EDICTNUM(OFS_PARM0));
+}
+
 //=============================================================================
 
 /*
 ==============
 //=============================================================================
 
 /*
 ==============
-PF_changelevel
+VM_changelevel
+server and menu
+
+changelevel(string map)
 ==============
 */
 ==============
 */
-/*void PF_changelevel (void)
+void VM_changelevel (void)
 {
        char    *s;
 
 {
        char    *s;
 
+       VM_SAFEPARMCOUNT(1, VM_changelevel);
+
+       if(!sv.active)
+       {
+               Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME); 
+               return;
+       }
+
 // make sure we don't issue two changelevels
        if (svs.changelevel_issued)
                return;
 // make sure we don't issue two changelevels
        if (svs.changelevel_issued)
                return;
@@ -1093,7 +1408,7 @@ PF_changelevel
 
        s = G_STRING(OFS_PARM0);
        Cbuf_AddText (va("changelevel %s\n",s));
 
        s = G_STRING(OFS_PARM0);
        Cbuf_AddText (va("changelevel %s\n",s));
-}*/
+}
 
 /*
 =========
 
 /*
 =========
@@ -1135,11 +1450,11 @@ void VM_sqrt (void)
 
 /*
 =================
 
 /*
 =================
-VM_RandomVec
+VM_randomvec
 
 Returns a vector of length < 1 and > 0
 
 
 Returns a vector of length < 1 and > 0
 
-randomvec()
+vector randomvec()
 =================
 */
 void VM_randomvec (void)
 =================
 */
 void VM_randomvec (void)
@@ -1166,31 +1481,34 @@ void VM_randomvec (void)
        // length returned always > 0
        length = (rand()&32766 + 1) * (1.0 / 32767.0) / VectorLength(temp);
        VectorScale(temp,length, temp);*/
        // length returned always > 0
        length = (rand()&32766 + 1) * (1.0 / 32767.0) / VectorLength(temp);
        VectorScale(temp,length, temp);*/
-       VectorCopy(temp, PRVM_G_VECTOR(OFS_RETURN));
+       //VectorCopy(temp, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 //=============================================================================
 }
 
 //=============================================================================
-#define MAX_QC_CVARS 128 * PRVM_MAXPROGS
-cvar_t vm_qc_cvar[MAX_QC_CVARS];
-int vm_currentqc_cvar;
 
 /*
 =========
 VM_registercvar
 
 
 /*
 =========
 VM_registercvar
 
-float  registercvar (string name, string value)
+float  registercvar (string name, string value, float flags)
 =========
 */
 void VM_registercvar (void)
 {
        char *name, *value;
        cvar_t *variable;
 =========
 */
 void VM_registercvar (void)
 {
        char *name, *value;
        cvar_t *variable;
+       int     flags;  
 
 
-       VM_SAFEPARMCOUNT(2,VM_registercvar);
+       VM_SAFEPARMCOUNT(3,VM_registercvar);
 
        name = PRVM_G_STRING(OFS_PARM0);
        value = PRVM_G_STRING(OFS_PARM1);
 
        name = PRVM_G_STRING(OFS_PARM0);
        value = PRVM_G_STRING(OFS_PARM1);
+       flags = PRVM_G_FLOAT(OFS_PARM2);
        PRVM_G_FLOAT(OFS_RETURN) = 0;
        PRVM_G_FLOAT(OFS_RETURN) = 0;
+
+       if(flags > CVAR_MAXFLAGSVAL)
+               return;
+
 // first check to see if it has already been defined
        if (Cvar_FindVar (name))
                return;
 // first check to see if it has already been defined
        if (Cvar_FindVar (name))
                return;
@@ -1198,7 +1516,7 @@ void VM_registercvar (void)
 // check for overlap with a command
        if (Cmd_Exists (name))
        {
 // check for overlap with a command
        if (Cmd_Exists (name))
        {
-               Con_Printf ("VM_registercvar: %s is a command\n", name);
+               Con_Printf("VM_registercvar: %s is a command\n", name);
                return;
        }
 
                return;
        }
 
@@ -1207,6 +1525,7 @@ void VM_registercvar (void)
 
 // copy the name and value
        variable = &vm_qc_cvar[vm_currentqc_cvar++];
 
 // copy the name and value
        variable = &vm_qc_cvar[vm_currentqc_cvar++];
+       variable->flags = flags;
        variable->name = Z_Malloc (strlen(name)+1);
        strcpy (variable->name, name);
        variable->string = Z_Malloc (strlen(value)+1);
        variable->name = Z_Malloc (strlen(name)+1);
        strcpy (variable->name, name);
        variable->string = Z_Malloc (strlen(value)+1);
@@ -1256,13 +1575,13 @@ float   max(float a, float b, ...[float])
 void VM_max (void)
 {
        // LordHavoc: 3+ argument enhancement suggested by FrikaC
 void VM_max (void)
 {
        // LordHavoc: 3+ argument enhancement suggested by FrikaC
-       if (pr_argc == 2)
+       if (prog->argc == 2)
                PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
                PRVM_G_FLOAT(OFS_RETURN) = max(PRVM_G_FLOAT(OFS_PARM0), PRVM_G_FLOAT(OFS_PARM1));
-       else if (pr_argc >= 3)
+       else if (prog->argc >= 3)
        {
                int i;
                float f = PRVM_G_FLOAT(OFS_PARM0);
        {
                int i;
                float f = PRVM_G_FLOAT(OFS_PARM0);
-               for (i = 1;i < pr_argc;i++)
+               for (i = 1;i < prog->argc;i++)
                        if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f)
                                f = PRVM_G_FLOAT((OFS_PARM0+i*3));
                G_FLOAT(OFS_RETURN) = f;
                        if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f)
                                f = PRVM_G_FLOAT((OFS_PARM0+i*3));
                G_FLOAT(OFS_RETURN) = f;
@@ -1339,7 +1658,7 @@ setcolor(clientent, value)
 
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
 
        if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active)
        {
-               Con_Print("tried to setcolor a non-client\n");
+               Con_Print("tried to setcolor a non-client\n");
                return;
        }
 
                return;
        }
 
@@ -1355,16 +1674,9 @@ setcolor(clientent, value)
        MSG_WriteByte (&sv.reliable_datagram, i);
 }*/
 
        MSG_WriteByte (&sv.reliable_datagram, i);
 }*/
 
-#define MAX_VMFILES            256
-#define MAX_PRVMFILES  MAX_VMFILES * PRVM_MAXPROGS
-// old #define VM_FILES(index) vm_files[PRVM_GetProgNr()+(index)]
-#define VM_FILES ((qfile_t**)(vm_files + PRVM_GetProgNr() * MAX_VMFILES))
-
-qfile_t *vm_files[MAX_PRVMFILES];
-
 void VM_Files_Init(void)
 {
 void VM_Files_Init(void)
 {
-       memset(vm_files, 0, sizeof(qfile_t*[MAX_VMFILES]));
+       memset(VM_FILES, 0, sizeof(qfile_t*[MAX_VMFILES]));
 }
 
 void VM_Files_CloseAll(void)
 }
 
 void VM_Files_CloseAll(void)
@@ -1418,7 +1730,7 @@ void VM_fopen(void)
                modestring = "wb";
                break;
        default:
                modestring = "wb";
                break;
        default:
-               Con_Printf ("VM_fopen: %s no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode);
+               Con_Printf("VM_fopen: %s no such mode %i (valid: 0 = read, 1 = append, 2 = write)\n", PRVM_NAME, mode);
                PRVM_G_FLOAT(OFS_RETURN) = -3;
                return;
        }
                PRVM_G_FLOAT(OFS_RETURN) = -3;
                return;
        }
@@ -1429,7 +1741,7 @@ void VM_fopen(void)
        // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
        if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
        {
        // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
        if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
        {
-               Con_Printf("VM_fopen: dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", filename);
+               Con_Printf("VM_fopen: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
        }
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
        }
@@ -1480,7 +1792,7 @@ string    fgets(float fhandle)
 void VM_fgets(void)
 {
        int c, end;
 void VM_fgets(void)
 {
        int c, end;
-       static char string[STRINGTEMP_LENGTH];
+       static char string[VM_STRINGTEMP_LENGTH];
        int filenum;
 
        VM_SAFEPARMCOUNT(1,VM_fgets);
        int filenum;
 
        VM_SAFEPARMCOUNT(1,VM_fgets);
@@ -1502,7 +1814,7 @@ void VM_fgets(void)
                c = FS_Getc(VM_FILES[filenum]);
                if (c == '\r' || c == '\n' || c < 0)
                        break;
                c = FS_Getc(VM_FILES[filenum]);
                if (c == '\r' || c == '\n' || c < 0)
                        break;
-               if (end < STRINGTEMP_LENGTH - 1)
+               if (end < VM_STRINGTEMP_LENGTH - 1)
                        string[end++] = c;
        }
        string[end] = 0;
                        string[end++] = c;
        }
        string[end] = 0;
@@ -1528,7 +1840,7 @@ fputs(float fhandle, string s)
 void VM_fputs(void)
 {
        int stringlength;
 void VM_fputs(void)
 {
        int stringlength;
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
        int filenum;
 
        VM_SAFEPARMCOUNT(2,VM_fputs);
        int filenum;
 
        VM_SAFEPARMCOUNT(2,VM_fputs);
@@ -1576,7 +1888,7 @@ void VM_strlen(void)
 =========
 VM_strcat
 
 =========
 VM_strcat
 
-string strcat(string s1, string s2)
+string strcat(string,string,...[string])
 =========
 */
 //string(string s1, string s2) strcat = #115;
 =========
 */
 //string(string s1, string s2) strcat = #115;
@@ -1586,10 +1898,11 @@ void VM_strcat(void)
 {
        char *s;
 
 {
        char *s;
 
-       VM_SAFEPARMCOUNT(2,VM_strcat);
-
+       if(prog->argc < 2) 
+               PRVM_ERROR("VM_strcat wrong parameter count (min. 2 expected ) !\n");
+       
        s = VM_GetTempString();
        s = VM_GetTempString();
-       VM_VarString(0, s, STRINGTEMP_LENGTH);
+       VM_VarString(0, s, VM_STRINGTEMP_LENGTH);
        PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
 }
 
        PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
 }
 
@@ -1616,7 +1929,7 @@ void VM_substring(void)
        if (!s)
                s = "";
        for (i = 0;i < start && *s;i++, s++);
        if (!s)
                s = "";
        for (i = 0;i < start && *s;i++, s++);
-       for (i = 0;i < STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++)
+       for (i = 0;i < VM_STRINGTEMP_LENGTH - 1 && *s && i < length;i++, s++)
                string[i] = *s;
        string[i] = 0;
        PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string);
                string[i] = *s;
        string[i] = 0;
        PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string);
@@ -1632,7 +1945,7 @@ vector    stov(string s)
 //vector(string s) stov = #117; // returns vector value from a string
 void VM_stov(void)
 {
 //vector(string s) stov = #117; // returns vector value from a string
 void VM_stov(void)
 {
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
 
        VM_SAFEPARMCOUNT(1,VM_stov);
 
 
        VM_SAFEPARMCOUNT(1,VM_stov);
 
@@ -1664,7 +1977,7 @@ void VM_strzone(void)
 =========
 VM_strunzone
 
 =========
 VM_strunzone
 
-strzone(string s)
+strunzone(string s)
 =========
 */
 //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!!!)
 =========
 */
 //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!!!)
@@ -1691,11 +2004,10 @@ void VM_clcommand (void)
 
        VM_SAFEPARMCOUNT(2,VM_clcommand);
 
 
        VM_SAFEPARMCOUNT(2,VM_clcommand);
 
-       //find client for this entity
        i = PRVM_G_FLOAT(OFS_PARM0);
        if (!sv.active  || i < 0 || i >= svs.maxclients || !svs.clients[i].active)
        {
        i = PRVM_G_FLOAT(OFS_PARM0);
        if (!sv.active  || i < 0 || i >= svs.maxclients || !svs.clients[i].active)
        {
-               Con_Printf("VM_clientcommand: %s: invalid client/server is not active !", PRVM_NAME);
+               Con_Printf("VM_clientcommand: %s: invalid client/server is not active !\n", PRVM_NAME);
                return;
        }
 
                return;
        }
 
@@ -1816,7 +2128,7 @@ void PF_setattachment (void)
 
 /*
 =========
 
 /*
 =========
-VM_serverstate
+VM_isserver
 
 float  isserver()
 =========
 
 float  isserver()
 =========
@@ -1856,69 +2168,733 @@ void VM_clientstate(void)
        PRVM_G_FLOAT(OFS_RETURN) = cls.state;
 }
 
        PRVM_G_FLOAT(OFS_RETURN) = cls.state;
 }
 
-void VM_Cmd_Init(void)
-{
-}
+/*
+=========
+VM_getostype
 
 
-void VM_Cmd_Reset(void)
+float  getostype(void)
+=========
+*/ // not used at the moment -> not included in the common list
+void VM_getostype(void)
 {
 {
-}
-
-//============================================================================
-// Server
+       VM_SAFEPARMCOUNT(0,VM_getostype);
 
 
-char *vm_sv_extensions =
-"";
+       /*
+       OS_WINDOWS
+       OS_LINUX
+       OS_MAC - not supported
+       */
 
 
-prvm_builtin_t vm_sv_builtins[] = {
-0  // to be consistent with the old vm
-};
+#ifdef _WIN32
+       PRVM_G_FLOAT(OFS_RETURN) = 0;
+#elif defined _MAC
+       PRVM_G_FLOAT(OFS_RETURN) = 2;
+#else
+       PRVM_G_FLOAT(OFS_RETURN) = 1;
+#endif
+}
 
 
-const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
+/*
+=========
+VM_getmousepos
 
 
-void VM_SV_Cmd_Init(void)
+vector getmousepos()
+=========
+*/
+void VM_getmousepos(void)
 {
 {
-}
 
 
-void VM_SV_Cmd_Reset(void)
-{
+       VM_SAFEPARMCOUNT(0,VM_getmousepos);
+       
+       PRVM_G_VECTOR(OFS_RETURN)[0] = in_mouse_x;
+       PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y;
+       PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
 }
 
 }
 
-//============================================================================
-// Client
+/*
+=========
+VM_gettime
 
 
-char *vm_cl_extensions =
-"";
+float  gettime(void)
+=========
+*/
+void VM_gettime(void)
+{
+       VM_SAFEPARMCOUNT(0,VM_gettime);
 
 
-prvm_builtin_t vm_cl_builtins[] = {
-0  // to be consistent with the old vm
-};
+       PRVM_G_FLOAT(OFS_RETURN) = (float) *prog->time;
+}
 
 
-const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
+/*
+=========
+VM_loadfromdata
 
 
-void VM_CL_Cmd_Init(void)
+loadfromdata(string data)
+=========
+*/
+void VM_loadfromdata(void)
 {
 {
-}
+       VM_SAFEPARMCOUNT(1,VM_loadentsfromfile);
 
 
-void VM_CL_Cmd_Reset(void)
-{
+       PRVM_ED_LoadFromFile(PRVM_G_STRING(OFS_PARM0));
 }
 
 }
 
-//============================================================================
-// Menu
-
-char *vm_m_extensions =
-"";
+/*
+=========
+VM_loadfromfile
 
 
-// void setkeydest(float dest)
-void VM_M_SetKeyDest(void)
+loadfromfile(string file)
+=========
+*/
+void VM_loadfromfile(void)
 {
 {
-       VM_SAFEPARMCOUNT(1,VM_M_SetKeyDest);
-
-       switch((int)PRVM_G_FLOAT(OFS_PARM0))
-       {
-       case 0:
-               // key_game
+       char *filename;
+       qbyte *data;
+       
+       VM_SAFEPARMCOUNT(1,VM_loadfromfile);
+       
+       filename = PRVM_G_STRING(OFS_PARM0);
+       // .. is parent directory on many platforms
+       // / is parent directory on Amiga
+       // : is root of drive on Amiga (also used as a directory separator on Mac, but / works there too, so that's a bad idea)
+       // \ is a windows-ism (so it's naughty to use it, / works on all platforms)
+       if ((filename[0] == '.' && filename[1] == '.') || filename[0] == '/' || strrchr(filename, ':') || strrchr(filename, '\\'))
+       {
+               Con_Printf("VM_loadfromfile: %s dangerous or non-portable filename \"%s\" not allowed. (contains : or \\ or begins with .. or /)\n", PRVM_NAME, filename);
+               PRVM_G_FLOAT(OFS_RETURN) = -4;
+               return;
+       }
+
+       // not conform with VM_fopen
+       data = FS_LoadFile(filename, tempmempool, false);
+       if (data == NULL)
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+       
+       PRVM_ED_LoadFromFile(data);
+
+       if(data)
+               Mem_Free(data);
+}
+
+
+/*
+=========
+VM_modulo
+
+float  mod(float val, float m)
+=========
+*/
+void VM_modulo(void)
+{
+       int val, m;
+       VM_SAFEPARMCOUNT(2,VM_module);
+
+       val = (int) PRVM_G_FLOAT(OFS_PARM0);
+       m       = (int) PRVM_G_FLOAT(OFS_PARM1);
+
+       PRVM_G_FLOAT(OFS_RETURN) = (float) (val % m);
+}
+
+void VM_Search_Init(void)
+{
+       memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES]));
+}
+
+void VM_Search_Reset(void)
+{
+       int i;
+       // reset the fssearch list
+       for(i = 0; i < MAX_VMSEARCHES; i++)
+               if(VM_SEARCHLIST[i])
+                       FS_FreeSearch(VM_SEARCHLIST[i]);
+       memset(VM_SEARCHLIST,0,sizeof(fssearch_t*[MAX_VMSEARCHES]));
+}
+
+/*
+=========
+VM_search_begin
+
+float search_begin(string pattern, float caseinsensitive, float quiet)
+=========
+*/
+void VM_search_begin(void)
+{
+       int handle;
+       char *pattern;
+       int caseinsens, quiet;
+
+       VM_SAFEPARMCOUNT(3, VM_search_begin);
+
+       pattern = PRVM_G_STRING(OFS_PARM0);
+
+       VM_CheckEmptyString(pattern);
+
+       caseinsens = PRVM_G_FLOAT(OFS_PARM1);
+       quiet = PRVM_G_FLOAT(OFS_PARM2);
+       
+       for(handle = 0; handle < MAX_VMSEARCHES; handle++)
+               if(!VM_SEARCHLIST[handle])
+                       break;
+
+       if(handle >= MAX_VMSEARCHES)
+       {
+               Con_Printf("VM_search_begin: %s ran out of search handles (%i)\n", PRVM_NAME, MAX_VMSEARCHES);
+               PRVM_G_FLOAT(OFS_RETURN) = -2;
+               return;
+       }
+
+       if(!(VM_SEARCHLIST[handle] = FS_Search(pattern,caseinsens, quiet)))
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+       else
+               PRVM_G_FLOAT(OFS_RETURN) = handle;
+}
+
+/*
+=========
+VM_search_end
+
+void   search_end(float handle)
+=========
+*/
+void VM_search_end(void)
+{
+       int handle;
+       VM_SAFEPARMCOUNT(1, VM_search_end);
+
+       handle = PRVM_G_FLOAT(OFS_PARM0);
+       
+       if(handle < 0 || handle >= MAX_VMSEARCHES)
+       {
+               Con_Printf("VM_search_end: invalid handle %i used in %s\n", handle, PRVM_NAME);
+               return;
+       }
+       if(VM_SEARCHLIST[handle] == NULL)
+       {
+               Con_Printf("VM_search_end: no such handle %i in %s\n", handle, PRVM_NAME);
+               return;
+       }
+
+       FS_FreeSearch(VM_SEARCHLIST[handle]);
+       VM_SEARCHLIST[handle] = NULL;
+}
+
+/*
+=========
+VM_search_getsize
+
+float  search_getsize(float handle)
+=========
+*/
+void VM_search_getsize(void)
+{
+       int handle;
+       VM_SAFEPARMCOUNT(1, VM_M_search_getsize);
+
+       handle = PRVM_G_FLOAT(OFS_PARM0);
+
+       if(handle < 0 || handle >= MAX_VMSEARCHES)
+       {
+               Con_Printf("VM_search_getsize: invalid handle %i used in %s\n", handle, PRVM_NAME);
+               return;
+       }
+       if(VM_SEARCHLIST[handle] == NULL)
+       {
+               Con_Printf("VM_search_getsize: no such handle %i in %s\n", handle, PRVM_NAME);
+               return;
+       }
+       
+       PRVM_G_FLOAT(OFS_RETURN) = VM_SEARCHLIST[handle]->numfilenames;
+}
+
+/*
+=========
+VM_search_getfilename
+
+string search_getfilename(float handle, float num)
+=========
+*/
+void VM_search_getfilename(void)
+{
+       int handle, filenum;
+       char *tmp;
+       VM_SAFEPARMCOUNT(2, VM_search_getfilename);
+
+       handle = PRVM_G_FLOAT(OFS_PARM0);
+       filenum = PRVM_G_FLOAT(OFS_PARM1);
+
+       if(handle < 0 || handle >= MAX_VMSEARCHES)
+       {
+               Con_Printf("VM_search_getfilename: invalid handle %i used in %s\n", handle, PRVM_NAME);
+               return;
+       }
+       if(VM_SEARCHLIST[handle] == NULL)
+       {
+               Con_Printf("VM_search_getfilename: no such handle %i in %s\n", handle, PRVM_NAME);
+               return;
+       }
+       if(filenum < 0 || filenum >= VM_SEARCHLIST[handle]->numfilenames)
+       {
+               Con_Printf("VM_search_getfilename: invalid filenum %i in %s\n", filenum, PRVM_NAME);
+               return;
+       }
+       
+       tmp = VM_GetTempString();
+       strcpy(tmp, VM_SEARCHLIST[handle]->filenames[filenum]);
+
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
+}
+
+/*
+=========
+VM_chr
+
+string chr(float ascii)
+=========
+*/
+void VM_chr(void)
+{
+       char *tmp;
+       VM_SAFEPARMCOUNT(1, VM_chr);
+
+       tmp = VM_GetTempString();
+       tmp[0] = (unsigned char) PRVM_G_FLOAT(OFS_PARM0);
+       tmp[1] = 0;
+
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
+}
+
+//=============================================================================
+// Draw builtins (client & menu)
+
+/*
+=========
+VM_iscachedpic
+
+float  iscachedpic(string pic)
+=========
+*/
+void VM_iscachedpic(void)
+{
+       VM_SAFEPARMCOUNT(1,VM_iscachedpic);
+
+       // drawq hasnt such a function, thus always return true 
+       PRVM_G_FLOAT(OFS_RETURN) = TRUE;
+}
+
+/*
+=========
+VM_precache_pic
+
+string precache_pic(string pic) 
+=========
+*/
+void VM_precache_pic(void)
+{
+       char    *s;
+       
+       VM_SAFEPARMCOUNT(1, VM_precache_pic);
+       
+       s = PRVM_G_STRING(OFS_PARM0);
+       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+       
+       if(!s)
+               PRVM_ERROR ("VM_precache_pic: %s: NULL\n", PRVM_NAME);
+
+       VM_CheckEmptyString (s);
+       
+       if(!Draw_CachePic(s))
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetString(""); 
+}
+
+/*
+=========
+VM_freepic
+
+freepic(string s)
+=========
+*/
+void VM_freepic(void)
+{
+       char *s;
+
+       VM_SAFEPARMCOUNT(1,VM_freepic);
+
+       s = PRVM_G_STRING(OFS_PARM0);
+       
+       if(!s)
+               PRVM_ERROR ("VM_freepic: %s: NULL\n");
+       
+       VM_CheckEmptyString (s);
+       
+       Draw_FreePic(s);
+}
+
+/*
+=========
+VM_drawcharacter
+
+float  drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
+=========
+*/
+void VM_drawcharacter(void)
+{
+       float *pos,*scale,*rgb;
+       char   character;
+       int flag;
+       VM_SAFEPARMCOUNT(6,VM_drawcharacter);
+
+       character = (char) PRVM_G_FLOAT(OFS_PARM1);
+       if(character == 0)
+       {
+               Con_Printf("VM_drawcharacter: %s passed null character !\n",PRVM_NAME);
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+               return;
+       }
+       
+       pos = PRVM_G_VECTOR(OFS_PARM0);
+       scale = PRVM_G_VECTOR(OFS_PARM2);
+       rgb = PRVM_G_VECTOR(OFS_PARM3);
+       flag = (int)PRVM_G_FLOAT(OFS_PARM5);
+       
+       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
+       {
+               Con_Printf("VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               PRVM_G_FLOAT(OFS_RETURN) = -2;
+               return;
+       }
+       
+       if(pos[2] || scale[2])
+               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"))); 
+
+       if(!scale[0] || !scale[1])
+       {
+               Con_Printf("VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
+               PRVM_G_FLOAT(OFS_RETURN) = -3;
+               return;
+       }
+
+       DrawQ_String (pos[0], pos[1], &character, 1, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
+       PRVM_G_FLOAT(OFS_RETURN) = 1;
+}      
+
+/*
+=========
+VM_drawstring
+
+float  drawstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
+=========
+*/
+void VM_drawstring(void)
+{
+       float *pos,*scale,*rgb;
+       char  *string;
+       int flag;
+       VM_SAFEPARMCOUNT(6,VM_drawstring);
+       
+       string = PRVM_G_STRING(OFS_PARM1);
+       if(!string)
+       {
+               Con_Printf("VM_drawstring: %s passed null string !\n",PRVM_NAME);
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+               return;
+       }
+       
+       VM_CheckEmptyString(string);
+       
+       pos = PRVM_G_VECTOR(OFS_PARM0);
+       scale = PRVM_G_VECTOR(OFS_PARM2);
+       rgb = PRVM_G_VECTOR(OFS_PARM3);
+       flag = (int)PRVM_G_FLOAT(OFS_PARM5);
+       
+       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
+       {
+               Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               PRVM_G_FLOAT(OFS_RETURN) = -2;
+               return;
+       }
+       
+       if(!scale[0] || !scale[1])
+       {
+               Con_Printf("VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
+               PRVM_G_FLOAT(OFS_RETURN) = -3;
+               return;
+       }
+
+       if(pos[2] || scale[2])
+               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"))); 
+       
+       DrawQ_String (pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
+       PRVM_G_FLOAT(OFS_RETURN) = 1;
+}
+/*
+=========
+VM_drawpic
+
+float  drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
+=========
+*/
+void VM_drawpic(void)
+{
+       char *pic;
+       float *size, *pos, *rgb;
+       int flag;
+
+       VM_SAFEPARMCOUNT(6,VM_drawpic);
+
+       pic = PRVM_G_STRING(OFS_PARM1);
+
+       if(!pic)
+       {
+               Con_Printf("VM_drawpic: %s passed null picture name !\n", PRVM_NAME);
+               PRVM_G_FLOAT(OFS_RETURN) = -1;  
+               return;
+       }
+
+       VM_CheckEmptyString (pic);
+
+       // is pic cached ? no function yet for that
+       if(!1)
+       {
+               Con_Printf("VM_drawpic: %s: %s not cached !\n", PRVM_NAME, pic);
+               PRVM_G_FLOAT(OFS_RETURN) = -4;
+               return;
+       }
+       
+       pos = PRVM_G_VECTOR(OFS_PARM0);
+       size = PRVM_G_VECTOR(OFS_PARM2);
+       rgb = PRVM_G_VECTOR(OFS_PARM3);
+       flag = (int) PRVM_G_FLOAT(OFS_PARM5);
+
+       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
+       {
+               Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               PRVM_G_FLOAT(OFS_RETURN) = -2;
+               return;
+       }
+
+       if(pos[2] || size[2])
+               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"))); 
+       
+       DrawQ_Pic(pos[0], pos[1], pic, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
+       PRVM_G_FLOAT(OFS_RETURN) = 1;
+}
+
+/*
+=========
+VM_drawfill
+
+float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
+=========
+*/
+void VM_drawfill(void)
+{
+       float *size, *pos, *rgb;
+       int flag;
+       
+       VM_SAFEPARMCOUNT(5,VM_drawfill);
+       
+       
+       pos = PRVM_G_VECTOR(OFS_PARM0);
+       size = PRVM_G_VECTOR(OFS_PARM1);
+       rgb = PRVM_G_VECTOR(OFS_PARM2);
+       flag = (int) PRVM_G_FLOAT(OFS_PARM4);
+       
+       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
+       {
+               Con_Printf("VM_drawstring: %s: wrong DRAWFLAG %i !\n",PRVM_NAME,flag);
+               PRVM_G_FLOAT(OFS_RETURN) = -2;
+               return;
+       }
+       
+       if(pos[2] || size[2])
+               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"))); 
+       
+       DrawQ_Pic(pos[0], pos[1], 0, size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM3), flag);
+       PRVM_G_FLOAT(OFS_RETURN) = 1;
+}
+
+/*
+=========
+VM_drawsetcliparea
+
+drawsetcliparea(float x, float y, float width, float height)
+=========
+*/
+void VM_drawsetcliparea(void)
+{
+       float x,y,w,h;
+       VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
+
+       x = bound(0,PRVM_G_FLOAT(OFS_PARM0),vid.conwidth);
+       y = bound(0,PRVM_G_FLOAT(OFS_PARM1),vid.conheight);
+       w = bound(0,PRVM_G_FLOAT(OFS_PARM2),(vid.conwidth  - x));
+       h = bound(0,PRVM_G_FLOAT(OFS_PARM3),(vid.conheight - y)); 
+
+       DrawQ_SetClipArea(x,y,w,h);
+}
+
+/*
+=========
+VM_drawresetcliparea
+
+drawresetcliparea()
+=========
+*/
+void VM_drawresetcliparea(void)
+{
+       VM_SAFEPARMCOUNT(0,VM_drawresetcliparea);
+
+       DrawQ_ResetClipArea();
+}
+
+/*
+=========
+VM_getimagesize
+
+vector getimagesize(string pic)
+=========
+*/
+void VM_getimagesize(void)
+{
+       char *p;
+       cachepic_t *pic;
+
+       VM_SAFEPARMCOUNT(1,VM_getimagesize);
+       
+       p = PRVM_G_STRING(OFS_PARM0);
+
+       if(!p)
+               PRVM_ERROR("VM_getimagepos: %s passed null picture name !\n", PRVM_NAME);
+       
+       VM_CheckEmptyString (p);
+
+       pic = Draw_CachePic (p);
+
+       PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width;
+       PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height;
+       PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
+}
+
+void VM_Cmd_Init(void)
+{
+       // only init the stuff for the current prog
+       VM_STRINGS_MEMPOOL = Mem_AllocPool(va("vm_stringsmempool[%s]",PRVM_NAME));
+       VM_Files_Init();
+       VM_Search_Init();
+}
+
+void VM_Cmd_Reset(void)
+{
+       //Mem_EmptyPool(VM_STRINGS_MEMPOOL);
+       Mem_FreePool(&VM_STRINGS_MEMPOOL);
+       VM_Search_Reset();
+       VM_Files_CloseAll();
+}
+
+//============================================================================
+// Server
+
+char *vm_sv_extensions =
+"";
+
+prvm_builtin_t vm_sv_builtins[] = {
+0  // to be consistent with the old vm
+};
+
+const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
+
+void VM_SV_Cmd_Init(void)
+{
+}
+
+void VM_SV_Cmd_Reset(void)
+{
+}
+
+//============================================================================
+// Client
+
+char *vm_cl_extensions =
+"";
+
+prvm_builtin_t vm_cl_builtins[] = {
+0  // to be consistent with the old vm
+};
+
+const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
+
+void VM_CL_Cmd_Init(void)
+{
+}
+
+void VM_CL_Cmd_Reset(void)
+{
+}
+
+//============================================================================
+// Menu
+
+char *vm_m_extensions =
+"";
+
+/*
+=========
+VM_M_setmousetarget
+
+setmousetarget(float target)
+=========
+*/
+void VM_M_setmousetarget(void)
+{
+       VM_SAFEPARMCOUNT(1, VM_M_setmousetarget);
+
+       switch((int)PRVM_G_FLOAT(OFS_PARM0))
+       {
+       case 1:
+               in_client_mouse = false;
+               break;
+       case 2:
+               in_client_mouse = true;
+               break;
+       default:
+               PRVM_ERROR("VM_M_setmousetarget: wrong destination %i !\n",PRVM_G_FLOAT(OFS_PARM0));
+       }
+}
+
+/*
+=========
+VM_M_getmousetarget
+
+float  getmousetarget
+=========
+*/
+void VM_M_getmousetarget(void)
+{
+       VM_SAFEPARMCOUNT(0,VM_M_getmousetarget);
+
+       if(in_client_mouse)
+               PRVM_G_FLOAT(OFS_RETURN) = 2;
+       else
+               PRVM_G_FLOAT(OFS_RETURN) = 1;
+}
+       
+
+
+/*
+=========
+VM_M_setkeydest
+
+setkeydest(float dest)
+=========
+*/
+void VM_M_setkeydest(void)
+{
+       VM_SAFEPARMCOUNT(1,VM_M_setkeydest);
+
+       switch((int)PRVM_G_FLOAT(OFS_PARM0))
+       {
+       case 0:
+               // key_game
                key_dest = key_game;
                break;
        case 2:
                key_dest = key_game;
                break;
        case 2:
@@ -1930,16 +2906,20 @@ void VM_M_SetKeyDest(void)
                // key_dest = key_message
                // break;
        default:
                // key_dest = key_message
                // break;
        default:
-               PRVM_ERROR("VM_M_SetKeyDest: wrong destination %i !\n",prog->globals[OFS_PARM0]);
+               PRVM_ERROR("VM_M_setkeydest: wrong destination %i !\n",prog->globals[OFS_PARM0]);
        }
        }
-
-       return;
 }
 
 }
 
-// float getkeydest(void)
-void VM_M_GetKeyDest(void)
+/*
+=========
+VM_M_getkeydest
+
+float  getkeydest
+=========
+*/
+void VM_M_getkeydest(void)
 {
 {
-       VM_SAFEPARMCOUNT(0,VM_M_GetKeyDest);
+       VM_SAFEPARMCOUNT(0,VM_M_getkeydest);
 
        // key_game = 0, key_message = 1, key_menu = 2, unknown = 3
        switch(key_dest)
 
        // key_game = 0, key_message = 1, key_menu = 2, unknown = 3
        switch(key_dest)
@@ -1959,20 +2939,426 @@ void VM_M_GetKeyDest(void)
        }
 }
 
        }
 }
 
+/*
+=========
+VM_M_callfunction
+
+       callfunction(...,string function_name)
+=========
+*/
+mfunction_t *PRVM_ED_FindFunction (const char *name);
+void VM_M_callfunction(void)
+{
+       mfunction_t *func;
+       char *s;
+
+       if(prog->argc == 0)
+               PRVM_ERROR("VM_M_callfunction: 1 parameter is required !\n");
+
+       s = PRVM_G_STRING(OFS_PARM0 + (prog->argc - 1));
+
+       if(!s)
+               PRVM_ERROR("VM_M_callfunction: null string !\n");
+
+       VM_CheckEmptyString(s); 
+
+       func = PRVM_ED_FindFunction(s);
+
+       if(!func)
+               PRVM_ERROR("VM_M_callfunciton: function %s not found !\n", s);
+       else if (func->first_statement < 0)
+       {
+               // negative statements are built in functions
+               int builtinnumber = -func->first_statement;
+               prog->xfunction->builtinsprofile++;
+               if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
+                       prog->builtins[builtinnumber]();
+               else
+                       PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
+       }
+       else if(func > 0)
+       {
+               prog->argc--;
+               PRVM_ExecuteProgram(func - prog->functions,"");
+               prog->argc++;
+       }
+}      
+
+/*
+=========
+VM_M_isfunction
+
+float  isfunction(string function_name)
+=========
+*/
+mfunction_t *PRVM_ED_FindFunction (const char *name);
+void VM_M_isfunction(void)
+{
+       mfunction_t *func;
+       char *s;
+       
+       VM_SAFEPARMCOUNT(1, VM_M_isfunction);
+       
+       s = PRVM_G_STRING(OFS_PARM0);
+       
+       if(!s)
+               PRVM_ERROR("VM_M_isfunction: null string !\n");
+       
+       VM_CheckEmptyString(s); 
+       
+       func = PRVM_ED_FindFunction(s);
+
+       if(!func)
+               PRVM_G_FLOAT(OFS_RETURN) = false;
+       else
+               PRVM_G_FLOAT(OFS_RETURN) = true;
+}
+
+/*
+=========
+VM_M_writetofile
+
+       writetofile(float fhandle, entity ent)
+=========
+*/
+void VM_M_writetofile(void)
+{
+       prvm_edict_t * ent;
+       int filenum;
+
+       VM_SAFEPARMCOUNT(2, VM_M_writetofile);
+
+       filenum = PRVM_G_FLOAT(OFS_PARM0);
+       if (filenum < 0 || filenum >= MAX_VMFILES)
+       {
+               Con_Printf("VM_fputs: invalid file handle %i used in %s\n", filenum, PRVM_NAME);
+               return;
+       }
+       if (VM_FILES[filenum] == NULL)
+       {
+               Con_Printf("VM_fputs: no such file handle %i (or file has been closed) in %s\n", filenum, PRVM_NAME);
+               return;
+       }
+
+       ent = PRVM_G_EDICT(OFS_PARM1);  
+       if(ent->e->free)
+       {
+               Con_Printf("VM_M_writetofile: %s: entity %i is free !\n", PRVM_NAME, PRVM_EDICT_NUM(OFS_PARM1));
+               return;
+       }
+
+       PRVM_ED_Write (VM_FILES[filenum], ent);
+}
+
+/*
+=========
+VM_M_getresolution
+
+vector getresolution(float number)
+=========
+*/
+extern unsigned short video_resolutions[][2];
+void VM_M_getresolution(void)
+{
+       int nr;
+       VM_SAFEPARMCOUNT(1, VM_getresolution);
+
+       nr = PRVM_G_FLOAT(OFS_PARM0);
+
+
+       PRVM_G_VECTOR(OFS_RETURN)[0] = video_resolutions[nr][0];
+       PRVM_G_VECTOR(OFS_RETURN)[1] = video_resolutions[nr][1];
+       PRVM_G_VECTOR(OFS_RETURN)[2] = 0;       
+}
+
+/*
+=========
+VM_M_keynumtostring
+
+string keynumtostring(float keynum)
+=========
+*/
+void VM_M_keynumtostring(void)
+{
+       int keynum;
+       char *tmp;
+       VM_SAFEPARMCOUNT(1, VM_M_keynumtostring);
+
+       keynum = PRVM_G_FLOAT(OFS_PARM0);
+
+       tmp = VM_GetTempString();
+       
+       strcpy(tmp, Key_KeynumToString(keynum));
+
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tmp);
+}
+
+/*
+=========
+VM_M_findkeysforcommand
+
+string findkeysforcommand(string command)
+
+the returned string is an altstring
+=========
+*/
+#define NUMKEYS 5 // TODO: merge the constant in keys.c with this one somewhen
+
+void M_FindKeysForCommand(char *command, int *keys);
+void VM_M_findkeysforcommand(void)
+{
+       char *cmd, *ret;
+       int keys[NUMKEYS];
+       int i;
+
+       VM_SAFEPARMCOUNT(1, VM_M_findkeysforcommand);
+
+       cmd = PRVM_G_STRING(OFS_PARM0);
+       
+       VM_CheckEmptyString(cmd);
+
+       (ret = VM_GetTempString())[0] = 0;
+       
+       M_FindKeysForCommand(cmd, keys);
+
+       for(i = 0; i < NUMKEYS; i++)
+               ret = strcat(ret, va(" \'%i\'", keys[i]));
+
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(ret);
+}
+
+/*
+=========
+VM_M_gethostcachecount
+
+float  gethostcachevalue(float type)
+=========
+*/
+/*
+       type:
+0      hostcachecount
+1      masterquerycount
+2      masterreplycount
+3      serverquerycount
+4      serverreplycount
+*/
+void VM_M_gethostcachevalue( void )
+{
+       int type;
+       VM_SAFEPARMCOUNT ( 1, VM_M_gethostcachevalue );
+
+       PRVM_G_FLOAT( OFS_RETURN ) = 0;
+
+       type = PRVM_G_FLOAT( OFS_PARM0 );
+       if( type < 0 || type > 4 )
+               Con_Printf( "VM_M_gethostcachevalue: bad type %i!\n", type );
+       else switch(type)
+       {
+       case 0:
+               PRVM_G_FLOAT ( OFS_RETURN ) = hostCacheCount;
+               return;
+       case 1:
+               PRVM_G_FLOAT ( OFS_RETURN ) = masterquerycount;
+               return;
+       case 2:
+               PRVM_G_FLOAT ( OFS_RETURN ) = masterreplycount;
+               return;
+       case 3:
+               PRVM_G_FLOAT ( OFS_RETURN ) = serverquerycount;
+               return;
+       case 4:
+               PRVM_G_FLOAT ( OFS_RETURN ) = serverreplycount;
+               return;
+       }
+}
+
+/*
+=========
+VM_M_gethostcachestring
+
+string gethostcachestring(float type, float hostnr)
+=========
+*/
+/*
+0      Get CName
+1      Get line1
+2      Get line2 
+*/
+void VM_M_gethostcachestring(void)
+{
+       int type;
+       int hostnr;
+
+       VM_SAFEPARMCOUNT(2, VM_M_gethostcachestring);
+
+       PRVM_G_INT(OFS_RETURN) = 0;
+
+       type = PRVM_G_FLOAT(OFS_PARM0);
+       
+       if(type < 0 || type > 2)
+       {
+               Con_Print("VM_M_gethostcachestring: bad string type requested!\n");
+               return;
+       }
+
+       hostnr = PRVM_G_FLOAT(OFS_PARM1);
+
+       if(hostnr < 0 || hostnr >= hostCacheCount)
+       {
+               Con_Print("VM_M_gethostcachestring: bad hostnr passed!\n");
+               return;
+       }
+
+       if( type == 0 )
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].cname );
+       else if( type == 1 )
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].line1 );
+       else
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetString( hostcache[hostnr].line2 );
+}
+
 prvm_builtin_t vm_m_builtins[] = {
 prvm_builtin_t vm_m_builtins[] = {
-0, // to be consistent with the old vm
-e1000,
-VM_M_SetKeyDest,
-VM_M_GetKeyDest
+       0, // to be consistent with the old vm
+       // common builtings (mostly)
+       VM_checkextension,
+       VM_error,
+       VM_objerror,
+       VM_print,
+       VM_bprint,
+       VM_sprint,
+       VM_centerprint,
+       VM_normalize,
+       VM_vlen,
+       VM_vectoyaw,    // #10
+       VM_vectoangles,
+       VM_random,
+       VM_localcmd,
+       VM_cvar,
+       VM_cvar_set,
+       VM_dprint,
+       VM_ftos,
+       VM_fabs,
+       VM_vtos,
+       VM_etos,                // 20
+       VM_stof,
+       VM_spawn,
+       VM_remove,
+       VM_find,
+       VM_findfloat,
+       VM_findchain,
+       VM_findchainfloat,
+       VM_precache_file,
+       VM_precache_sound,
+       VM_coredump,    // 30
+       VM_traceon,
+       VM_traceoff,
+       VM_eprint,
+       VM_rint,
+       VM_floor,
+       VM_ceil,
+       VM_nextent,
+       VM_sin,
+       VM_cos,
+       VM_sqrt,                // 40
+       VM_randomvec,
+       VM_registercvar,
+       VM_min,
+       VM_max,
+       VM_bound,
+       VM_pow,
+       VM_copyentity,
+       VM_fopen,
+       VM_fclose,
+       VM_fgets,               // 50
+       VM_fputs,
+       VM_strlen,
+       VM_strcat,
+       VM_substring,
+       VM_stov,
+       VM_strzone,
+       VM_strunzone,
+       VM_tokenize,
+       VM_argv,
+       VM_isserver,    // 60
+       VM_clientcount, 
+       VM_clientstate, 
+       VM_clcommand,
+       VM_changelevel,
+       VM_localsound,  
+       VM_getmousepos,
+       VM_gettime,
+       VM_loadfromdata,
+       VM_loadfromfile,
+       VM_modulo,              // 70
+       VM_str_cvar,    
+       VM_crash,
+       VM_stackdump,   // 73
+       VM_search_begin,
+       VM_search_end,
+       VM_search_getsize,
+       VM_search_getfilename, // 77
+       VM_chr, //78
+       0,0,// 80
+       e10,                    // 90
+       e10,                    // 100
+       e100,                   // 200
+       e100,                   // 300
+       e100,                   // 400
+       // msg functions
+       VM_WriteByte,
+       VM_WriteChar,
+       VM_WriteShort,
+       VM_WriteLong,
+       VM_WriteAngle,
+       VM_WriteCoord,
+       VM_WriteString,
+       VM_WriteEntity, // 408
+       0,
+       0,                              // 410
+       e10,                    // 420
+       e10,                    // 430
+       e10,                    // 440
+       e10,                    // 450
+       // draw functions
+       VM_iscachedpic,
+       VM_precache_pic,
+       VM_freepic,
+       VM_drawcharacter,
+       VM_drawstring,
+       VM_drawpic,
+       VM_drawfill,    
+       VM_drawsetcliparea,
+       VM_drawresetcliparea,
+       VM_getimagesize,// 460
+       e10,                    // 470
+       e10,                    // 480
+       e10,                    // 490
+       e10,                    // 500
+       e100,                   // 600
+       // menu functions
+       VM_M_setkeydest,
+       VM_M_getkeydest,
+       VM_M_setmousetarget,
+       VM_M_getmousetarget,
+       VM_M_callfunction,
+       VM_M_writetofile,
+       VM_M_isfunction,
+       VM_M_getresolution,
+       VM_M_keynumtostring,
+       VM_M_findkeysforcommand,// 610
+       VM_M_gethostcachevalue,
+       VM_M_gethostcachestring // 612 
 };
 
 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
 
 void VM_M_Cmd_Init(void)
 {
 };
 
 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
 
 void VM_M_Cmd_Init(void)
 {
+       VM_Cmd_Init();
 }
 
 void VM_M_Cmd_Reset(void)
 {
 }
 
 void VM_M_Cmd_Reset(void)
 {
+       //VM_Cmd_Init();
+       VM_Cmd_Reset();
 }
 }
-