]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
fix portal lighting in a single cluster map (box map)
[xonotic/darkplaces.git] / prvm_cmds.c
index 0b4fb015b32a5798be9b43617e7dceb41420e548..1e82ccbb870c88fb83a02242d4d6a4ae92558f81 100644 (file)
@@ -1,7 +1,7 @@
 // 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
 
 
@@ -42,7 +42,7 @@ entity        findchain(.string field, string match)
 
 entity findchainfloat(.string field, float match)
 entity findchainentity(.string field, entity match)
 
 entity findchainfloat(.string field, float match)
 entity findchainentity(.string field, entity match)
-  
+
 string precache_file(string)
 string precache_sound (string sample)
                coredump()
 string precache_file(string)
 string precache_sound (string sample)
                coredump()
@@ -57,7 +57,7 @@ float sin(float)
 float  cos(float)
 float  sqrt(float)
 vector randomvec()
 float  cos(float)
 float  sqrt(float)
 vector randomvec()
-float  registercvar (string name, string value)
+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)
@@ -86,8 +86,27 @@ float        gettime()
                loadfromdata(string data)
                loadfromfile(string file)
 float  mod(float val, float m)
                loadfromdata(string data)
                loadfromfile(string file)
 float  mod(float val, float m)
-               
-perhaps only : Menu : WriteMsg 
+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)
+
+float  itof(intt ent)
+intt   ftoi(float num)
+
+float  altstr_count(string)
+string altstr_prepare(string)
+string altstr_get(string,float)
+string altstr_set(string altstr, float num, string set)
+string altstr_ins(string altstr, float num, string set)
+
+perhaps only : Menu : WriteMsg
 ===============================
 
                WriteByte(float data, float dest, float desto)
 ===============================
 
                WriteByte(float data, float dest, float desto)
@@ -98,12 +117,12 @@ perhaps only : Menu : WriteMsg
                WriteCoord(float data, float dest, float desto)
                WriteString(string data, float dest, float desto)
                WriteEntity(entity 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 
-===============================
+
+Client & Menu : draw functions & video functions
+===================================================
 
 float  iscachedpic(string pic)
 
 float  iscachedpic(string pic)
-string precache_pic(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)
                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)
@@ -112,23 +131,54 @@ 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)
                drawsetcliparea(float x, float y, float width, float height)
                drawresetcliparea()
 vector getimagesize(string pic)
-               
+
+float  cin_open(string file, string name)
+void   cin_close(string name)
+void   cin_setstate(string name, float type)
+float  cin_getstate(string name)
+void   cin_restart(string name)
 
 ==============================================================================
 menu cmd list:
 ===============
 
                setkeydest(float dest)
 
 ==============================================================================
 menu cmd list:
 ===============
 
                setkeydest(float dest)
-float  getkeydest
+float  getkeydest()
                setmousetarget(float target)
                setmousetarget(float target)
-float  getmousetarget(void)
+float  getmousetarget()
+
+               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  getserverliststat(float type)
+string getserverliststring(float fld, float hostnr)
+
+               parseentitydata(entity ent, string data)
+
+float  stringtokeynum(string key)
+
+               resetserverlistmasks()
+               setserverlistmaskstring(float mask, float fld, string str)
+               setserverlistmasknumber(float mask, float fld, float num, float op)
+               resortserverlist()
+               setserverlistsort(float field, float descending)
+               refreshserverlist()
+float  getserverlistnumber(float fld, float hostnr)
+float  getserverlistindexforkey(string key)
+               addwantedserverlistkey(string key)
 */
 
 #include "quakedef.h"
 #include "progdefs.h"
 */
 
 #include "quakedef.h"
 #include "progdefs.h"
+#include "progsvm.h"
 #include "clprogdefs.h"
 #include "mprogdefs.h"
 
 #include "clprogdefs.h"
 #include "mprogdefs.h"
 
+#include "cl_video.h"
+
 //============================================================================
 // nice helper macros
 
 //============================================================================
 // nice helper macros
 
@@ -140,8 +190,6 @@ float       getmousetarget(void)
 
 #define        VM_RETURN_EDICT(e)              (((int *)prog->globals)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
 
 
 #define        VM_RETURN_EDICT(e)              (((int *)prog->globals)[OFS_RETURN] = PRVM_EDICT_TO_PROG(e))
 
-#define VM_STRINGS_MEMPOOL             vm_strings_mempool[PRVM_GetProgNr()]
-
 #define e10 0,0,0,0,0,0,0,0,0,0
 #define e100 e10,e10,e10,e10,e10,e10,e10,e10,e10,e10
 #define e1000 e100,e100,e100,e100,e100,e100,e100,e100,e100,e100
 #define e10 0,0,0,0,0,0,0,0,0,0
 #define e100 e10,e10,e10,e10,e10,e10,e10,e10,e10,e10
 #define e1000 e100,e100,e100,e100,e100,e100,e100,e100,e100,e100
@@ -149,21 +197,13 @@ float     getmousetarget(void)
 //============================================================================
 // Common
 
 //============================================================================
 // Common
 
-// string zone mempool
-mempool_t *vm_strings_mempool[PRVM_MAXPROGS];
-
 // temp string handling
 // LordHavoc: added this to semi-fix the problem of using many ftos calls in a print
 // temp string handling
 // 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
 // qc file handling
 #define MAX_VMFILES            256
 #define MAX_PRVMFILES  MAX_VMFILES * PRVM_MAXPROGS
@@ -171,15 +211,22 @@ int vm_currentqc_cvar;
 
 qfile_t *vm_files[MAX_PRVMFILES];
 
 
 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)
+void VM_CheckEmptyString (const char *s)
 {
        if (s[0] <= ' ')
                PRVM_ERROR ("%s: Bad string", PRVM_NAME);
 {
        if (s[0] <= ' ')
                PRVM_ERROR ("%s: Bad string", PRVM_NAME);
@@ -215,7 +262,7 @@ checkextension(extensionname)
 */
 
 // kind of helper function
 */
 
 // kind of helper function
-static qboolean checkextension(char *name)
+static qboolean checkextension(const char *name)
 {
        int len;
        char *e, *start;
 {
        int len;
        char *e, *start;
@@ -259,14 +306,14 @@ error(value)
 void VM_error (void)
 {
        prvm_edict_t    *ed;
 void VM_error (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 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);
@@ -285,14 +332,14 @@ 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);
        }
 
                PRVM_ED_Free (ed);
        }
@@ -312,7 +359,7 @@ 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);
@@ -329,16 +376,16 @@ bprint(...[string])
 */
 void VM_bprint (void)
 {
 */
 void VM_bprint (void)
 {
-       char string[STRINGTEMP_LENGTH];
+       char string[VM_STRINGTEMP_LENGTH];
 
        if(!sv.active)
        {
 
        if(!sv.active)
        {
-               Con_Printf("VM_bprint: game is not server(%s) !", PRVM_NAME);
+               Con_Printf("VM_bprint: game is not server(%s) !\n", PRVM_NAME);
                return;
        }
 
        VM_VarString(0, string, sizeof(string));
                return;
        }
 
        VM_VarString(0, string, sizeof(string));
-       SV_BroadcastPrintf("%s", string);
+       SV_BroadcastPrint(string);
 }
 
 /*
 }
 
 /*
@@ -354,19 +401,17 @@ void VM_sprint (void)
 {
        client_t        *client;
        int                     clientnum;
 {
        client_t        *client;
        int                     clientnum;
-       char string[STRINGTEMP_LENGTH];
+       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)
        {
 
        //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 !", PRVM_NAME);
+               Con_Printf("VM_sprint: %s: invalid client or server is not active !\n", PRVM_NAME);
                return;
        }
                return;
        }
-       
+
        client = svs.clients + clientnum;
        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_VarString(1, string, sizeof(string));
        MSG_WriteChar(&client->message,svc_print);
        MSG_WriteString(&client->message, string);
@@ -383,7 +428,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);
@@ -534,13 +579,9 @@ float random()
 */
 void VM_random (void)
 {
 */
 void VM_random (void)
 {
-       float           num;
-
        VM_SAFEPARMCOUNT(0,VM_random);
 
        VM_SAFEPARMCOUNT(0,VM_random);
 
-       num = (rand ()&0x7fff) / ((float)0x7fff);
-
-       PRVM_G_FLOAT(OFS_RETURN) = num;
+       PRVM_G_FLOAT(OFS_RETURN) = lhrandom(0, 1);
 }
 
 /*
 }
 
 /*
@@ -595,20 +636,19 @@ localsound(string sample)
 */
 void VM_localsound(void)
 {
 */
 void VM_localsound(void)
 {
-       char *s;
-       
+       const char *s;
+
        VM_SAFEPARMCOUNT(1,VM_localsound);
 
        s = PRVM_G_STRING(OFS_PARM0);
 
        VM_SAFEPARMCOUNT(1,VM_localsound);
 
        s = PRVM_G_STRING(OFS_PARM0);
 
-       if(!S_GetCached(s))
+       if(!S_LocalSound (s))
        {
        {
-               Con_Printf("VM_localsound: %s : %s not cached !\n", PRVM_NAME, s);
+               Con_Printf("VM_localsound: Failed to play %s for %s !\n", s, PRVM_NAME);
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
-       }               
+       }
 
 
-       S_LocalSound(s);
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 
@@ -657,6 +697,36 @@ 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;
+       const char *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_RETURN) = PRVM_SetEngineString(out);
+}
+
 /*
 =================
 VM_cvar_set
 /*
 =================
 VM_cvar_set
@@ -680,7 +750,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));
@@ -710,7 +780,7 @@ void VM_ftos (void)
                sprintf(s, "%i", (int)v);
        else
                sprintf(s, "%f", v);
                sprintf(s, "%i", (int)v);
        else
                sprintf(s, "%f", v);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s);
 }
 
 /*
 }
 
 /*
@@ -747,7 +817,7 @@ void VM_vtos (void)
 
        s = VM_GetTempString();
        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]);
 
        s = VM_GetTempString();
        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]);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s);
 }
 
 /*
 }
 
 /*
@@ -766,7 +836,7 @@ void VM_etos (void)
 
        s = VM_GetTempString();
        sprintf (s, "entity %i", PRVM_G_EDICTNUM(OFS_PARM0));
 
        s = VM_GetTempString();
        sprintf (s, "entity %i", PRVM_G_EDICTNUM(OFS_PARM0));
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s);
 }
 
 /*
 }
 
 /*
@@ -778,11 +848,43 @@ 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);
 }
 
+/*
+========================
+VM_itof
+
+float itof(intt ent)
+========================
+*/
+void VM_itof(void)
+{
+       VM_SAFEPARMCOUNT(1, VM_itof);
+       PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
+}
+
+/*
+========================
+VM_itoe
+
+intt ftoi(float num)
+========================
+*/
+void VM_ftoi(void)
+{
+       int ent;
+       VM_SAFEPARMCOUNT(1, VM_ftoi);
+
+       ent = PRVM_G_FLOAT(OFS_PARM0);
+       if(PRVM_PROG_TO_EDICT(ent)->p.e->free)
+               PRVM_ERROR ("VM_ftoe: %s tried to access a freed entity (entity %i)!\n", PRVM_NAME, ent);
+
+       PRVM_G_INT(OFS_RETURN) = ent;
+}
+
 /*
 =========
 VM_spawn
 /*
 =========
 VM_spawn
@@ -803,7 +905,7 @@ void VM_spawn (void)
 =========
 VM_remove
 
 =========
 VM_remove
 
-entity remove()
+remove(entity e)
 =========
 */
 
 =========
 */
 
@@ -834,7 +936,7 @@ void VM_find (void)
 {
        int             e;
        int             f;
 {
        int             e;
        int             f;
-       char    *s, *t;
+       const char      *s, *t;
        prvm_edict_t    *ed;
 
        VM_SAFEPARMCOUNT(3,VM_find);
        prvm_edict_t    *ed;
 
        VM_SAFEPARMCOUNT(3,VM_find);
@@ -854,7 +956,7 @@ void VM_find (void)
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
-               if (ed->e->free)
+               if (ed->p.e->free)
                        continue;
                t = PRVM_E_STRING(ed,f);
                if (!t)
                        continue;
                t = PRVM_E_STRING(ed,f);
                if (!t)
@@ -895,7 +997,7 @@ void VM_findfloat (void)
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
-               if (ed->e->free)
+               if (ed->p.e->free)
                        continue;
                if (PRVM_E_FLOAT(ed,f) == s)
                {
                        continue;
                if (PRVM_E_FLOAT(ed,f) == s)
                {
@@ -922,7 +1024,7 @@ void VM_findchain (void)
        int             i;
        int             f;
        int             chain_of;
        int             i;
        int             f;
        int             chain_of;
-       char    *s, *t;
+       const char      *s, *t;
        prvm_edict_t    *ent, *chain;
 
        VM_SAFEPARMCOUNT(2,VM_findchain);
        prvm_edict_t    *ent, *chain;
 
        VM_SAFEPARMCOUNT(2,VM_findchain);
@@ -947,7 +1049,7 @@ void VM_findchain (void)
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
-               if (ent->e->free)
+               if (ent->p.e->free)
                        continue;
                t = PRVM_E_STRING(ent,f);
                if (!t)
                        continue;
                t = PRVM_E_STRING(ent,f);
                if (!t)
@@ -955,7 +1057,7 @@ void VM_findchain (void)
                if (strcmp(t,s))
                        continue;
 
                if (strcmp(t,s))
                        continue;
 
-               PRVM_E_FLOAT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
+               PRVM_E_INT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
                chain = ent;
        }
 
                chain = ent;
        }
 
@@ -996,12 +1098,12 @@ void VM_findchainfloat (void)
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
-               if (ent->e->free)
+               if (ent->p.e->free)
                        continue;
                        continue;
-               if (E_FLOAT(ent,f) != s)
+               if (PRVM_E_FLOAT(ent,f) != s)
                        continue;
 
                        continue;
 
-               PRVM_E_FLOAT(ent,chain_of) = PRVM_NUM_FOR_EDICT(chain);
+               PRVM_E_INT(ent,chain_of) = PRVM_EDICT_TO_PROG(chain);
                chain = ent;
        }
 
                chain = ent;
        }
 
@@ -1044,22 +1146,16 @@ string  precache_sound (string sample)
 */
 void VM_precache_sound (void)
 {
 */
 void VM_precache_sound (void)
 {
-       char    *s;
+       const char      *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);
 
        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);
-       
-       if(S_GetCached(s))
-       {
-               Con_Printf("VM_precache_sound: %s already cached (%s)\n", s, PRVM_NAME);
-               return;
-       }
-       
-       if(!S_PrecacheSound(s,true))
-               Con_Printf("VM_prache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
+
+       if(snd_initialized.integer && !S_PrecacheSound (s,true, true))
+               Con_Printf("VM_precache_sound: Failed to load %s for %s\n", s, PRVM_NAME);
 }
 
 /*
 }
 
 /*
@@ -1078,6 +1174,36 @@ void VM_coredump (void)
        Cbuf_AddText("\n");
 }
 
        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);
+}
+
 /*
 =========
 VM_traceon
 /*
 =========
 VM_traceon
@@ -1192,7 +1318,7 @@ void VM_nextent (void)
                        return;
                }
                ent = PRVM_EDICT_NUM(i);
                        return;
                }
                ent = PRVM_EDICT_NUM(i);
-               if (!ent->e->free)
+               if (!ent->p.e->free)
                {
                        VM_RETURN_EDICT(ent);
                        return;
                {
                        VM_RETURN_EDICT(ent);
                        return;
@@ -1274,12 +1400,12 @@ void VM_WriteLong (void)
 
 void VM_WriteAngle (void)
 {
 
 void VM_WriteAngle (void)
 {
-       MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+       MSG_WriteAngle (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
 }
 
 void VM_WriteCoord (void)
 {
 }
 
 void VM_WriteCoord (void)
 {
-       MSG_WriteDPCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0));
+       MSG_WriteCoord (VM_WriteDest(), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
 }
 
 void VM_WriteString (void)
 }
 
 void VM_WriteString (void)
@@ -1304,13 +1430,13 @@ changelevel(string map)
 */
 void VM_changelevel (void)
 {
 */
 void VM_changelevel (void)
 {
-       char    *s;
+       const char      *s;
 
        VM_SAFEPARMCOUNT(1, VM_changelevel);
 
        if(!sv.active)
        {
 
        VM_SAFEPARMCOUNT(1, VM_changelevel);
 
        if(!sv.active)
        {
-               Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME); 
+               Con_Printf("VM_changelevel: game is not server (%s)\n", PRVM_NAME);
                return;
        }
 
                return;
        }
 
@@ -1319,7 +1445,7 @@ void VM_changelevel (void)
                return;
        svs.changelevel_issued = true;
 
                return;
        svs.changelevel_issued = true;
 
-       s = G_STRING(OFS_PARM0);
+       s = PRVM_G_STRING(OFS_PARM0);
        Cbuf_AddText (va("changelevel %s\n",s));
 }
 
        Cbuf_AddText (va("changelevel %s\n",s));
 }
 
@@ -1403,19 +1529,24 @@ void VM_randomvec (void)
 =========
 VM_registercvar
 
 =========
 VM_registercvar
 
-float  registercvar (string name, string value)
+float  registercvar (string name, string value, float flags)
 =========
 */
 void VM_registercvar (void)
 {
 =========
 */
 void VM_registercvar (void)
 {
-       char *name, *value;
-       cvar_t *variable;
+       const char *name, *value;
+       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;
@@ -1423,22 +1554,12 @@ 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;
        }
 
-       if (vm_currentqc_cvar >= MAX_QC_CVARS)
-               PRVM_ERROR ("VM_registercvar: ran out of cvar slots (%i)\n", MAX_QC_CVARS);
-
-// copy the name and value
-       variable = &vm_qc_cvar[vm_currentqc_cvar++];
-       variable->name = Z_Malloc (strlen(name)+1);
-       strcpy (variable->name, name);
-       variable->string = Z_Malloc (strlen(value)+1);
-       strcpy (variable->string, value);
-       variable->value = atof (value);
+       Cvar_Get(name, value, flags);
 
 
-       Cvar_RegisterVariable(variable);
        PRVM_G_FLOAT(OFS_RETURN) = 1; // success
 }
 
        PRVM_G_FLOAT(OFS_RETURN) = 1; // success
 }
 
@@ -1490,7 +1611,7 @@ void VM_max (void)
                for (i = 1;i < prog->argc;i++)
                        if (PRVM_G_FLOAT((OFS_PARM0+i*3)) > f)
                                f = PRVM_G_FLOAT((OFS_PARM0+i*3));
                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;
+               PRVM_G_FLOAT(OFS_RETURN) = f;
        }
        else
                PRVM_ERROR("VM_max: %s must supply at least 2 floats\n", PRVM_NAME);
        }
        else
                PRVM_ERROR("VM_max: %s must supply at least 2 floats\n", PRVM_NAME);
@@ -1564,7 +1685,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;
        }
 
@@ -1610,7 +1731,7 @@ float     fopen(string filename, float mode)
 void VM_fopen(void)
 {
        int filenum, mode;
 void VM_fopen(void)
 {
        int filenum, mode;
-       char *modestring, *filename;
+       const char *modestring, *filename;
 
        VM_SAFEPARMCOUNT(2,VM_fopen);
 
 
        VM_SAFEPARMCOUNT(2,VM_fopen);
 
@@ -1636,7 +1757,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;
        }
@@ -1651,7 +1772,10 @@ void VM_fopen(void)
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
        }
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
        }
-       VM_FILES[filenum] = FS_Open(va("data/%s", filename), modestring, false);
+       VM_FILES[filenum] = FS_Open(va("data/%s", filename), modestring, false, false);
+       if (VM_FILES[filenum] == NULL && mode == 0)
+               VM_FILES[filenum] = FS_Open(va("%s", filename), modestring, false, false);
+
        if (VM_FILES[filenum] == NULL)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
        else
        if (VM_FILES[filenum] == NULL)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
        else
@@ -1698,7 +1822,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);
@@ -1720,17 +1844,21 @@ 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;
        // remove \n following \r
        if (c == '\r')
                        string[end++] = c;
        }
        string[end] = 0;
        // remove \n following \r
        if (c == '\r')
+       {
                c = FS_Getc(VM_FILES[filenum]);
                c = FS_Getc(VM_FILES[filenum]);
-       if (developer.integer)
+               if (c != '\n')
+                       FS_UnGetc(VM_FILES[filenum], (unsigned char)c);
+       }
+       if (developer.integer >= 3)
                Con_Printf("fgets: %s: %s\n", PRVM_NAME, string);
                Con_Printf("fgets: %s: %s\n", PRVM_NAME, string);
-       if (c >= 0)
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string);
+       if (c >= 0 || end)
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string);
        else
                PRVM_G_INT(OFS_RETURN) = 0;
 }
        else
                PRVM_G_INT(OFS_RETURN) = 0;
 }
@@ -1746,7 +1874,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);
@@ -1779,7 +1907,7 @@ float     strlen(string s)
 //float(string s) strlen = #114; // returns how many characters are in a string
 void VM_strlen(void)
 {
 //float(string s) strlen = #114; // returns how many characters are in a string
 void VM_strlen(void)
 {
-       char *s;
+       const char *s;
 
        VM_SAFEPARMCOUNT(1,VM_strlen);
 
 
        VM_SAFEPARMCOUNT(1,VM_strlen);
 
@@ -1804,12 +1932,12 @@ void VM_strcat(void)
 {
        char *s;
 
 {
        char *s;
 
-       if(prog->argc <= 2) 
-               PRVM_ERROR("VM_strcat wrong parameter count (min. 2 expected ) !\n");
-       
+       if(prog->argc < 1)
+               PRVM_ERROR("VM_strcat wrong parameter count (min. 1 expected ) !\n");
+
        s = VM_GetTempString();
        s = VM_GetTempString();
-       VM_VarString(0, s, STRINGTEMP_LENGTH);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(s);
+       VM_VarString(0, s, VM_STRINGTEMP_LENGTH);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(s);
 }
 
 /*
 }
 
 /*
@@ -1824,7 +1952,8 @@ string    substring(string s, float start, float length)
 void VM_substring(void)
 {
        int i, start, length;
 void VM_substring(void)
 {
        int i, start, length;
-       char *s, *string;
+       const char *s;
+       char *string;
 
        VM_SAFEPARMCOUNT(3,VM_substring);
 
 
        VM_SAFEPARMCOUNT(3,VM_substring);
 
@@ -1835,10 +1964,10 @@ 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;
                string[i] = *s;
        string[i] = 0;
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(string);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(string);
 }
 
 /*
 }
 
 /*
@@ -1851,7 +1980,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);
 
@@ -1869,14 +1998,15 @@ string  strzone(string s)
 //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)
 void VM_strzone(void)
 {
 //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)
 void VM_strzone(void)
 {
-       char *in, *out;
+       const char *in;
+       char *out;
 
        VM_SAFEPARMCOUNT(1,VM_strzone);
 
        in = PRVM_G_STRING(OFS_PARM0);
 
        VM_SAFEPARMCOUNT(1,VM_strzone);
 
        in = PRVM_G_STRING(OFS_PARM0);
-       out = Mem_Alloc(VM_STRINGS_MEMPOOL, strlen(in) + 1);
+       out = PRVM_AllocString(strlen(in) + 1);
        strcpy(out, in);
        strcpy(out, in);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetString(out);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetQCString(out);
 }
 
 /*
 }
 
 /*
@@ -1890,8 +2020,7 @@ strunzone(string s)
 void VM_strunzone(void)
 {
        VM_SAFEPARMCOUNT(1,VM_strunzone);
 void VM_strunzone(void)
 {
        VM_SAFEPARMCOUNT(1,VM_strunzone);
-
-       Mem_Free(PRVM_G_STRING(OFS_PARM0));
+       PRVM_FreeString((char *)PRVM_G_STRING(OFS_PARM0));
 }
 
 /*
 }
 
 /*
@@ -1913,7 +2042,7 @@ void VM_clcommand (void)
        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;
        }
 
@@ -1938,8 +2067,7 @@ static char **tokens = NULL;
 static int    max_tokens, num_tokens = 0;
 void VM_tokenize (void)
 {
 static int    max_tokens, num_tokens = 0;
 void VM_tokenize (void)
 {
-       const char *p;
-       char *str;
+       const char *p, *str;
 
        VM_SAFEPARMCOUNT(1,VM_tokenize);
 
 
        VM_SAFEPARMCOUNT(1,VM_tokenize);
 
@@ -1984,9 +2112,9 @@ void VM_argv (void)
 
        token_num = PRVM_G_FLOAT(OFS_PARM0);
        if (token_num >= 0 && token_num < num_tokens)
 
        token_num = PRVM_G_FLOAT(OFS_PARM0);
        if (token_num >= 0 && token_num < num_tokens)
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetString(tokens[token_num]);
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(tokens[token_num]);
        else
        else
-               PRVM_G_INT(OFS_RETURN) = PRVM_SetString("");
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(NULL);
 }
 
 /*
 }
 
 /*
@@ -2020,9 +2148,10 @@ void PF_setattachment (void)
                                for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++)
                                        if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name))
                                                v->_float = i + 1;
                                for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++)
                                        if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name))
                                                v->_float = i + 1;
-                       if (v->_float == 0 && model->alias.aliasnum_tags)
-                               for (i = 0;i < model->alias.aliasnum_tags;i++)
-                                       if (!strcmp(tagname, model->alias.aliasdata_tags[i].name))
+                       // FIXME: use a model function to get tag info (need to handle skeletal)
+                       if (v->_float == 0 && model->num_tags)
+                               for (i = 0;i < model->num_tags;i++)
+                                       if (!strcmp(tagname, model->data_tags[i].name))
                                                v->_float = i + 1;
                        if (v->_float == 0)
                                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);
                                                v->_float = i + 1;
                        if (v->_float == 0)
                                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);
@@ -2074,6 +2203,32 @@ void VM_clientstate(void)
        PRVM_G_FLOAT(OFS_RETURN) = cls.state;
 }
 
        PRVM_G_FLOAT(OFS_RETURN) = cls.state;
 }
 
+/*
+=========
+VM_getostype
+
+float  getostype(void)
+=========
+*/ // not used at the moment -> not included in the common list
+void VM_getostype(void)
+{
+       VM_SAFEPARMCOUNT(0,VM_getostype);
+
+       /*
+       OS_WINDOWS
+       OS_LINUX
+       OS_MAC - not supported
+       */
+
+#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
+}
+
 /*
 =========
 VM_getmousepos
 /*
 =========
 VM_getmousepos
@@ -2085,9 +2240,9 @@ void VM_getmousepos(void)
 {
 
        VM_SAFEPARMCOUNT(0,VM_getmousepos);
 {
 
        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)[0] = in_mouse_x * vid_conwidth.integer / vid.width;
+       PRVM_G_VECTOR(OFS_RETURN)[1] = in_mouse_y * vid_conheight.integer / vid.height;
        PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
 }
 
        PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
 }
 
@@ -2119,6 +2274,34 @@ void VM_loadfromdata(void)
        PRVM_ED_LoadFromFile(PRVM_G_STRING(OFS_PARM0));
 }
 
        PRVM_ED_LoadFromFile(PRVM_G_STRING(OFS_PARM0));
 }
 
+/*
+========================
+VM_M_parseentitydata
+
+parseentitydata(entity ent, string data)
+========================
+*/
+void VM_M_parseentitydata(void)
+{
+       prvm_edict_t *ent;
+       const char *data;
+
+       VM_SAFEPARMCOUNT(2, VM_parseentitydata);
+
+    // get edict and test it
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       if (ent->p.e->free)
+               PRVM_ERROR ("VM_parseentitydata: %s: Can only set already spawned entities (entity %i is free)!\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ent));
+
+       data = PRVM_G_STRING(OFS_PARM1);
+
+    // parse the opening brace
+       if (!COM_ParseToken(&data, false) || com_token[0] != '{' )
+               PRVM_ERROR ("VM_parseentitydata: %s: Couldn't parse entity data:\n%s\n", PRVM_NAME, data );
+
+       PRVM_ED_ParseEdict (data, ent);
+}
+
 /*
 =========
 VM_loadfromfile
 /*
 =========
 VM_loadfromfile
@@ -2128,11 +2311,11 @@ loadfromfile(string file)
 */
 void VM_loadfromfile(void)
 {
 */
 void VM_loadfromfile(void)
 {
-       char *filename;
+       const char *filename;
        qbyte *data;
        qbyte *data;
-       
+
        VM_SAFEPARMCOUNT(1,VM_loadfromfile);
        VM_SAFEPARMCOUNT(1,VM_loadfromfile);
-       
+
        filename = PRVM_G_STRING(OFS_PARM0);
        // .. is parent directory on many platforms
        // / is parent directory on Amiga
        filename = PRVM_G_STRING(OFS_PARM0);
        // .. is parent directory on many platforms
        // / is parent directory on Amiga
@@ -2146,10 +2329,10 @@ void VM_loadfromfile(void)
        }
 
        // not conform with VM_fopen
        }
 
        // not conform with VM_fopen
-       data = FS_LoadFile(filename, false);
+       data = FS_LoadFile(filename, tempmempool, false);
        if (data == NULL)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
        if (data == NULL)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
-       
+
        PRVM_ED_LoadFromFile(data);
 
        if(data)
        PRVM_ED_LoadFromFile(data);
 
        if(data)
@@ -2175,6 +2358,174 @@ void VM_modulo(void)
        PRVM_G_FLOAT(OFS_RETURN) = (float) (val % m);
 }
 
        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;
+       const 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_SetEngineString(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_SetEngineString(tmp);
+}
+
 //=============================================================================
 // Draw builtins (client & menu)
 
 //=============================================================================
 // Draw builtins (client & menu)
 
@@ -2189,33 +2540,34 @@ void VM_iscachedpic(void)
 {
        VM_SAFEPARMCOUNT(1,VM_iscachedpic);
 
 {
        VM_SAFEPARMCOUNT(1,VM_iscachedpic);
 
-       // drawq hasnt such a function, thus always return true 
-       PRVM_G_FLOAT(OFS_RETURN) = TRUE;
+       // drawq hasnt such a function, thus always return true
+       PRVM_G_FLOAT(OFS_RETURN) = false;
 }
 
 /*
 =========
 VM_precache_pic
 
 }
 
 /*
 =========
 VM_precache_pic
 
-string precache_pic(string pic) 
+string precache_pic(string pic)
 =========
 */
 void VM_precache_pic(void)
 {
 =========
 */
 void VM_precache_pic(void)
 {
-       char    *s;
-       
+       const char      *s;
+
        VM_SAFEPARMCOUNT(1, VM_precache_pic);
        VM_SAFEPARMCOUNT(1, VM_precache_pic);
-       
+
        s = PRVM_G_STRING(OFS_PARM0);
        PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
        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(!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(""); 
+
+       // AK Draw_CachePic is supposed to always return a valid pointer
+       if( Draw_CachePic(s, false)->tex == r_texture_notexture )
+               PRVM_G_INT(OFS_RETURN) = PRVM_SetEngineString(NULL);
 }
 
 /*
 }
 
 /*
@@ -2227,17 +2579,17 @@ freepic(string s)
 */
 void VM_freepic(void)
 {
 */
 void VM_freepic(void)
 {
-       char *s;
+       const char *s;
 
        VM_SAFEPARMCOUNT(1,VM_freepic);
 
        s = PRVM_G_STRING(OFS_PARM0);
 
        VM_SAFEPARMCOUNT(1,VM_freepic);
 
        s = PRVM_G_STRING(OFS_PARM0);
-       
+
        if(!s)
                PRVM_ERROR ("VM_freepic: %s: NULL\n");
        if(!s)
                PRVM_ERROR ("VM_freepic: %s: NULL\n");
-       
+
        VM_CheckEmptyString (s);
        VM_CheckEmptyString (s);
-       
+
        Draw_FreePic(s);
 }
 
        Draw_FreePic(s);
 }
 
@@ -2262,21 +2614,21 @@ void VM_drawcharacter(void)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
                return;
        }
                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);
        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(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])
        if(pos[2] || scale[2])
-               Con_Printf("VM_drawcharacter: z value%c from %s discarded",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); 
+               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])
        {
 
        if(!scale[0] || !scale[1])
        {
@@ -2287,7 +2639,7 @@ void VM_drawcharacter(void)
 
        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;
 
        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;
-}      
+}
 
 /*
 =========
 
 /*
 =========
@@ -2299,10 +2651,10 @@ float   drawstring(vector position, string text, vector scale, vector rgb, float a
 void VM_drawstring(void)
 {
        float *pos,*scale,*rgb;
 void VM_drawstring(void)
 {
        float *pos,*scale,*rgb;
-       char  *string;
+       const char  *string;
        int flag;
        VM_SAFEPARMCOUNT(6,VM_drawstring);
        int flag;
        VM_SAFEPARMCOUNT(6,VM_drawstring);
-       
+
        string = PRVM_G_STRING(OFS_PARM1);
        if(!string)
        {
        string = PRVM_G_STRING(OFS_PARM1);
        if(!string)
        {
@@ -2310,21 +2662,21 @@ void VM_drawstring(void)
                PRVM_G_FLOAT(OFS_RETURN) = -1;
                return;
        }
                PRVM_G_FLOAT(OFS_RETURN) = -1;
                return;
        }
-       
-       VM_CheckEmptyString(string);
-       
+
+       //VM_CheckEmptyString(string); Why should it be checked - perhaps the menu wants to support the precolored letters, too?
+
        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);
        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(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");
        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");
@@ -2333,8 +2685,8 @@ void VM_drawstring(void)
        }
 
        if(pos[2] || scale[2])
        }
 
        if(pos[2] || scale[2])
-               Con_Printf("VM_drawstring: z value%c from %s discarded",(pos[2] && scale[2]) ? 's' : 0,((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale"))); 
-       
+               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;
 }
        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;
 }
@@ -2347,7 +2699,7 @@ float     drawpic(vector position, string pic, vector size, vector rgb, float alpha,
 */
 void VM_drawpic(void)
 {
 */
 void VM_drawpic(void)
 {
-       char *pic;
+       const char *pic;
        float *size, *pos, *rgb;
        int flag;
 
        float *size, *pos, *rgb;
        int flag;
 
@@ -2358,7 +2710,7 @@ void VM_drawpic(void)
        if(!pic)
        {
                Con_Printf("VM_drawpic: %s passed null picture name !\n", PRVM_NAME);
        if(!pic)
        {
                Con_Printf("VM_drawpic: %s passed null picture name !\n", PRVM_NAME);
-               PRVM_G_FLOAT(OFS_RETURN) = -1;  
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
                return;
        }
 
                return;
        }
 
@@ -2371,7 +2723,7 @@ void VM_drawpic(void)
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                return;
        }
                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);
        pos = PRVM_G_VECTOR(OFS_PARM0);
        size = PRVM_G_VECTOR(OFS_PARM2);
        rgb = PRVM_G_VECTOR(OFS_PARM3);
@@ -2385,8 +2737,8 @@ void VM_drawpic(void)
        }
 
        if(pos[2] || size[2])
        }
 
        if(pos[2] || size[2])
-               Con_Printf("VM_drawstring: z value%c from %s discarded",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); 
-       
+               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;
 }
        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;
 }
@@ -2402,25 +2754,25 @@ void VM_drawfill(void)
 {
        float *size, *pos, *rgb;
        int flag;
 {
        float *size, *pos, *rgb;
        int flag;
-       
+
        VM_SAFEPARMCOUNT(5,VM_drawfill);
        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);
        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(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])
        if(pos[2] || size[2])
-               Con_Printf("VM_drawstring: z value%c from %s discarded",(pos[2] && size[2]) ? 's' : 0,((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size"))); 
-       
+               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;
 }
        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;
 }
@@ -2437,12 +2789,12 @@ void VM_drawsetcliparea(void)
        float x,y,w,h;
        VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
 
        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),x);
-       h = bound(0,PRVM_G_FLOAT(OFS_PARM3),y); 
+       x = bound(0, PRVM_G_FLOAT(OFS_PARM0), vid_conwidth.integer);
+       y = bound(0, PRVM_G_FLOAT(OFS_PARM1), vid_conheight.integer);
+       w = bound(0, PRVM_G_FLOAT(OFS_PARM2) + PRVM_G_FLOAT(OFS_PARM0) - x, (vid_conwidth.integer  - x));
+       h = bound(0, PRVM_G_FLOAT(OFS_PARM3) + PRVM_G_FLOAT(OFS_PARM1) - y, (vid_conheight.integer - y));
 
 
-       DrawQ_SetClipArea(x,y,w,h);
+       DrawQ_SetClipArea(x, y, w, h);
 }
 
 /*
 }
 
 /*
@@ -2468,35 +2820,347 @@ vector getimagesize(string pic)
 */
 void VM_getimagesize(void)
 {
 */
 void VM_getimagesize(void)
 {
-       char *p;
+       const char *p;
        cachepic_t *pic;
 
        VM_SAFEPARMCOUNT(1,VM_getimagesize);
        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);
        p = PRVM_G_STRING(OFS_PARM0);
 
        if(!p)
                PRVM_ERROR("VM_getimagepos: %s passed null picture name !\n", PRVM_NAME);
-       
+
        VM_CheckEmptyString (p);
 
        VM_CheckEmptyString (p);
 
-       pic = Draw_CachePic (p);
+       pic = Draw_CachePic (p, false);
 
        PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width;
        PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height;
        PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
 }
 
 
        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();                
-}
+// CL_Video interface functions
 
 
-void VM_Cmd_Reset(void)
+/*
+========================
+VM_cin_open
+
+float cin_open(string file, string name)
+========================
+*/
+void VM_cin_open( void )
+{
+       const char *file;
+       const char *name;
+
+       VM_SAFEPARMCOUNT( 2, VM_cin_open );
+
+       file = PRVM_G_STRING( OFS_PARM0 );
+       name = PRVM_G_STRING( OFS_PARM1 );
+
+       VM_CheckEmptyString( file );
+    VM_CheckEmptyString( name );
+
+       if( CL_OpenVideo( file, name, MENUOWNER ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = 1;
+       else
+               PRVM_G_FLOAT( OFS_RETURN ) = 0;
+}
+
+/*
+========================
+VM_cin_close
+
+void cin_close(string name)
+========================
+*/
+void VM_cin_close( void )
+{
+       const char *name;
+
+       VM_SAFEPARMCOUNT( 1, VM_cin_close );
+
+       name = PRVM_G_STRING( OFS_PARM0 );
+       VM_CheckEmptyString( name );
+
+       CL_CloseVideo( CL_GetVideo( name ) );
+}
+
+/*
+========================
+VM_cin_setstate
+void cin_setstate(string name, float type)
+========================
+*/
+void VM_cin_setstate( void )
+{
+       const char *name;
+       clvideostate_t  state;
+       clvideo_t               *video;
+
+       VM_SAFEPARMCOUNT( 2, VM_cin_netstate );
+
+       name = PRVM_G_STRING( OFS_PARM0 );
+       VM_CheckEmptyString( name );
+
+       state = PRVM_G_FLOAT( OFS_PARM1 );
+
+       video = CL_GetVideo( name );
+       if( video && state > CLVIDEO_UNUSED && state < CLVIDEO_STATECOUNT )
+               CL_SetVideoState( video, state );
+}
+
+/*
+========================
+VM_cin_getstate
+
+float cin_getstate(string name)
+========================
+*/
+void VM_cin_getstate( void )
+{
+       const char *name;
+       clvideo_t               *video;
+
+       VM_SAFEPARMCOUNT( 1, VM_cin_getstate );
+
+       name = PRVM_G_STRING( OFS_PARM0 );
+       VM_CheckEmptyString( name );
+
+       video = CL_GetVideo( name );
+       if( video )
+               PRVM_G_FLOAT( OFS_RETURN ) = (int)video->state;
+       else
+               PRVM_G_FLOAT( OFS_RETURN ) = 0;
+}
+
+/*
+========================
+VM_cin_restart
+
+void cin_restart(string name)
+========================
+*/
+void VM_cin_restart( void )
+{
+       const char *name;
+       clvideo_t               *video;
+
+       VM_SAFEPARMCOUNT( 1, VM_cin_restart );
+
+       name = PRVM_G_STRING( OFS_PARM0 );
+       VM_CheckEmptyString( name );
+
+       video = CL_GetVideo( name );
+       if( video )
+               CL_RestartVideo( video );
+}
+
+////////////////////////////////////////
+// AltString functions
+////////////////////////////////////////
+
+/*
+========================
+VM_altstr_count
+
+float altstr_count(string)
+========================
+*/
+void VM_altstr_count( void )
+{
+       const char *altstr, *pos;
+       int     count;
+
+       VM_SAFEPARMCOUNT( 1, VM_altstr_count );
+
+       altstr = PRVM_G_STRING( OFS_PARM0 );
+       //VM_CheckEmptyString( altstr );
+
+       for( count = 0, pos = altstr ; *pos ; pos++ )
+               if( *pos == '\\' && !*++pos )
+                               break;
+               else if( *pos == '\'' )
+                       count++;
+
+       PRVM_G_FLOAT( OFS_RETURN ) = (float) (count / 2);
+}
+
+/*
+========================
+VM_altstr_prepare
+
+string altstr_prepare(string)
+========================
+*/
+void VM_altstr_prepare( void )
+{
+       char *outstr, *out;
+       const char *instr, *in;
+       int size;
+
+       VM_SAFEPARMCOUNT( 1, VM_altstr_prepare );
+
+       instr = PRVM_G_STRING( OFS_PARM0 );
+       //VM_CheckEmptyString( instr );
+       outstr = VM_GetTempString();
+
+       for( out = outstr, in = instr, size = VM_STRINGTEMP_LENGTH - 1 ; size && *in ; size--, in++, out++ )
+               if( *in == '\'' ) {
+                       *out++ = '\\';
+                       *out = '\'';
+                       size--;
+               } else
+                       *out = *in;
+       *out = 0;
+
+       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr );
+}
+
+/*
+========================
+VM_altstr_get
+
+string altstr_get(string, float)
+========================
+*/
+void VM_altstr_get( void )
+{
+       const char *altstr, *pos;
+       char *outstr, *out;
+       int count, size;
+
+       VM_SAFEPARMCOUNT( 2, VM_altstr_get );
+
+       altstr = PRVM_G_STRING( OFS_PARM0 );
+       //VM_CheckEmptyString( altstr );
+
+       count = PRVM_G_FLOAT( OFS_PARM1 );
+       count = count * 2 + 1;
+
+       for( pos = altstr ; *pos && count ; pos++ )
+               if( *pos == '\\' && !*++pos )
+                       break;
+               else if( *pos == '\'' )
+                       count--;
+
+       if( !*pos ) {
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( NULL );
+               return;
+       }
+
+    outstr = VM_GetTempString();
+       for( out = outstr, size = VM_STRINGTEMP_LENGTH - 1 ; size && *pos ; size--, pos++, out++ )
+               if( *pos == '\\' ) {
+                       if( !*++pos )
+                               break;
+                       *out = *pos;
+                       size--;
+               } else if( *pos == '\'' )
+                       break;
+               else
+                       *out = *pos;
+
+       *out = 0;
+       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr );
+}
+
+/*
+========================
+VM_altstr_set
+
+string altstr_set(string altstr, float num, string set)
+========================
+*/
+void VM_altstr_set( void )
+{
+    int num;
+       const char *altstr, *str;
+       const char *in;
+       char *outstr, *out;
+
+       VM_SAFEPARMCOUNT( 3, VM_altstr_set );
+
+       altstr = PRVM_G_STRING( OFS_PARM0 );
+       //VM_CheckEmptyString( altstr );
+
+       num = PRVM_G_FLOAT( OFS_PARM1 );
+
+       str = PRVM_G_STRING( OFS_PARM2 );
+       //VM_CheckEmptyString( str );
+
+       outstr = out = VM_GetTempString();
+       for( num = num * 2 + 1, in = altstr; *in && num; *out++ = *in++ )
+               if( *in == '\\' && !*++in )
+                       break;
+               else if( *in == '\'' )
+                       num--;
+
+       if( !in ) {
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( NULL );
+               return;
+       }
+       // copy set in
+       for( ; *str; *out++ = *str++ );
+       // now jump over the old contents
+       for( ; *in ; in++ )
+               if( *in == '\'' || (*in == '\\' && !*++in) )
+                       break;
+
+       if( !in ) {
+               PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( NULL );
+               return;
+       }
+
+       strcpy( out, in );
+       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr );
+}
+
+/*
+========================
+VM_altstr_ins
+insert after num
+string altstr_ins(string altstr, float num, string set)
+========================
+*/
+void VM_altstr_ins(void)
 {
 {
-       Mem_EmptyPool(VM_STRINGS_MEMPOOL);
+       int num;
+       const char *setstr;
+       const char *set;
+       const char *instr;
+       const char *in;
+       char *outstr;
+       char *out;
+
+       in = instr = PRVM_G_STRING( OFS_PARM0 );
+       num = PRVM_G_FLOAT( OFS_PARM1 );
+       set = setstr = PRVM_G_STRING( OFS_PARM2 );
+
+       out = outstr = VM_GetTempString();
+       for( num = num * 2 + 2 ; *in && num > 0 ; *out++ = *in++ )
+               if( *in == '\\' && !*++in )
+                       break;
+               else if( *in == '\'' )
+                       num--;
+
+       for( ; *set ; *out++ = *set++ );
+
+       strcpy( out, in );
+       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( outstr );
+}
+
+void VM_Cmd_Init(void)
+{
+       // only init the stuff for the current prog
+       VM_Files_Init();
+       VM_Search_Init();
+}
+
+void VM_Cmd_Reset(void)
+{
+       CL_PurgeOwner( MENUOWNER );
+       VM_Search_Reset();
        VM_Files_CloseAll();
 }
 
        VM_Files_CloseAll();
 }
 
@@ -2544,7 +3208,7 @@ void VM_CL_Cmd_Reset(void)
 // Menu
 
 char *vm_m_extensions =
 // Menu
 
 char *vm_m_extensions =
-"";
+"DP_CINEMATIC_DPV";
 
 /*
 =========
 
 /*
 =========
@@ -2586,7 +3250,7 @@ void VM_M_getmousetarget(void)
        else
                PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
        else
                PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
-       
+
 
 
 /*
 
 
 /*
@@ -2648,6 +3312,577 @@ void VM_M_getkeydest(void)
        }
 }
 
        }
 }
 
+/*
+=========
+VM_M_callfunction
+
+       callfunction(...,string function_name)
+Extension: pass
+=========
+*/
+mfunction_t *PRVM_ED_FindFunction (const char *name);
+void VM_M_callfunction(void)
+{
+       mfunction_t *func;
+       const 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;
+       const 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->p.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_SetEngineString(tmp);
+}
+
+/*
+=========
+VM_M_stringtokeynum
+
+float stringtokeynum(string key)
+=========
+*/
+void VM_M_stringtokeynum( void )
+{
+       const char *str;
+       VM_SAFEPARMCOUNT( 1, VM_M_keynumtostring );
+
+       str = PRVM_G_STRING( OFS_PARM0 );
+
+       PRVM_G_INT(OFS_RETURN) = Key_StringToKeynum( str );
+}
+
+/*
+=========
+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(const char *command, int *keys);
+void VM_M_findkeysforcommand(void)
+{
+       const char *cmd;
+       char *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_SetEngineString(ret);
+}
+
+/*
+=========
+VM_M_getserverliststat
+
+float  getserverliststat(float type)
+=========
+*/
+/*
+       type:
+0      serverlist_viewcount
+1   serverlist_totalcount
+2      masterquerycount
+3      masterreplycount
+4      serverquerycount
+5      serverreplycount
+6      sortfield
+7      sortdescending
+*/
+void VM_M_getserverliststat( void )
+{
+       int type;
+       VM_SAFEPARMCOUNT ( 1, VM_M_getserverliststat );
+
+       PRVM_G_FLOAT( OFS_RETURN ) = 0;
+
+       type = PRVM_G_FLOAT( OFS_PARM0 );
+       switch(type)
+       {
+       case 0:
+               PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_viewcount;
+               return;
+       case 1:
+               PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_cachecount;
+       case 2:
+               PRVM_G_FLOAT ( OFS_RETURN ) = masterquerycount;
+               return;
+       case 3:
+               PRVM_G_FLOAT ( OFS_RETURN ) = masterreplycount;
+               return;
+       case 4:
+               PRVM_G_FLOAT ( OFS_RETURN ) = serverquerycount;
+               return;
+       case 5:
+               PRVM_G_FLOAT ( OFS_RETURN ) = serverreplycount;
+               return;
+       case 6:
+               PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_sortbyfield;
+               return;
+       case 7:
+               PRVM_G_FLOAT ( OFS_RETURN ) = serverlist_sortdescending;
+               return;
+       default:
+               Con_Printf( "VM_M_getserverliststat: bad type %i!\n", type );
+       }
+}
+
+/*
+========================
+VM_M_resetserverlistmasks
+
+resetserverlistmasks()
+========================
+*/
+void VM_M_resetserverlistmasks( void )
+{
+       ServerList_ResetMasks();
+}
+
+
+/*
+========================
+VM_M_setserverlistmaskstring
+
+setserverlistmaskstring(float mask, float fld, string str, float op)
+0-511          and
+512 - 1024     or
+========================
+*/
+void VM_M_setserverlistmaskstring( void )
+{
+       const char *str;
+       int masknr;
+       serverlist_mask_t *mask;
+       int field;
+
+       VM_SAFEPARMCOUNT( 4, VM_M_setserverlistmaskstring );
+       str = PRVM_G_STRING( OFS_PARM1 );
+       if( !str )
+               PRVM_ERROR( "VM_M_setserverlistmaskstring: null string passed!" );
+
+       masknr = PRVM_G_FLOAT( OFS_PARM0 );
+       if( masknr >= 0 && masknr <= SERVERLIST_ANDMASKCOUNT )
+               mask = &serverlist_andmasks[masknr];
+       else if( masknr >= 512 && masknr - 512 <= SERVERLIST_ORMASKCOUNT )
+               mask = &serverlist_ormasks[masknr - 512 ];
+       else {
+               Con_Printf( "VM_M_setserverlistmaskstring: invalid mask number %i\n", masknr );
+               return;
+       }
+
+       field = (int) PRVM_G_FLOAT( OFS_PARM1 );
+
+       switch( field ) {
+               case SLIF_CNAME:
+                       strncpy( mask->info.cname, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.cname) );
+                       break;
+               case SLIF_NAME:
+                       strncpy( mask->info.name, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.name)  );
+                       break;
+               case SLIF_MAP:
+                       strncpy( mask->info.map, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.map)  );
+                       break;
+               case SLIF_MOD:
+                       strncpy( mask->info.mod, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.mod)  );
+                       break;
+               case SLIF_GAME:
+                       strncpy( mask->info.game, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.game)  );
+                       break;
+               default:
+                       Con_Printf( "VM_M_setserverlistmaskstring: Bad field number %i passed!\n", field );
+                       return;
+       }
+
+       mask->active = true;
+       mask->tests[field] = (int) PRVM_G_FLOAT( OFS_PARM3 );
+}
+
+/*
+========================
+VM_M_setserverlistmasknumber
+
+setserverlistmasknumber(float mask, float fld, float num, float op)
+
+0-511          and
+512 - 1024     or
+========================
+*/
+void VM_M_setserverlistmasknumber( void )
+{
+       int number;
+       serverlist_mask_t *mask;
+       int     masknr;
+       int field;
+       VM_SAFEPARMCOUNT( 4, VM_M_setserverlistmasknumber );
+
+       masknr = PRVM_G_FLOAT( OFS_PARM0 );
+       if( masknr >= 0 && masknr <= SERVERLIST_ANDMASKCOUNT )
+               mask = &serverlist_andmasks[masknr];
+       else if( masknr >= 512 && masknr - 512 <= SERVERLIST_ORMASKCOUNT )
+               mask = &serverlist_ormasks[masknr - 512 ];
+       else {
+               Con_Printf( "VM_M_setserverlistmasknumber: invalid mask number %i\n", masknr );
+               return;
+       }
+
+       number = PRVM_G_FLOAT( OFS_PARM2 );
+       field = (int) PRVM_G_FLOAT( OFS_PARM1 );
+
+       switch( field ) {
+               case SLIF_MAXPLAYERS:
+                       mask->info.maxplayers = number;
+                       break;
+               case SLIF_NUMPLAYERS:
+                       mask->info.numplayers = number;
+                       break;
+               case SLIF_PING:
+                       mask->info.ping = number;
+                       break;
+               case SLIF_PROTOCOL:
+                       mask->info.protocol = number;
+                       break;
+               default:
+                       Con_Printf( "VM_M_setserverlistmasknumber: Bad field number %i passed!\n", field );
+                       return;
+       }
+
+       mask->active = true;
+       mask->tests[field] = (int) PRVM_G_FLOAT( OFS_PARM3 );
+}
+
+
+/*
+========================
+VM_M_resortserverlist
+
+resortserverlist
+========================
+*/
+void VM_M_resortserverlist( void )
+{
+       ServerList_RebuildViewList();
+}
+
+/*
+=========
+VM_M_getserverliststring
+
+string getserverliststring(float field, float hostnr)
+=========
+*/
+void VM_M_getserverliststring(void)
+{
+       serverlist_entry_t *cache;
+       int hostnr;
+
+       VM_SAFEPARMCOUNT(2, VM_M_getserverliststring);
+
+       PRVM_G_INT(OFS_RETURN) = 0;
+
+       hostnr = PRVM_G_FLOAT(OFS_PARM1);
+
+       if(hostnr < 0 || hostnr >= serverlist_viewcount)
+       {
+               Con_Print("VM_M_getserverliststring: bad hostnr passed!\n");
+               return;
+       }
+       cache = serverlist_viewlist[hostnr];
+       switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) {
+               case SLIF_CNAME:
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.cname );
+                       break;
+               case SLIF_NAME:
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.name );
+                       break;
+               case SLIF_GAME:
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.game );
+                       break;
+               case SLIF_MOD:
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.mod );
+                       break;
+               case SLIF_MAP:
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->info.map );
+                       break;
+               // TODO remove this again
+               case 1024:
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->line1 );
+                       break;
+               case 1025:
+                       PRVM_G_INT( OFS_RETURN ) = PRVM_SetEngineString( cache->line2 );
+                       break;
+               default:
+                       Con_Print("VM_M_getserverliststring: bad field number passed!\n");
+       }
+}
+
+/*
+=========
+VM_M_getserverlistnumber
+
+float  getserverlistnumber(float field, float hostnr)
+=========
+*/
+void VM_M_getserverlistnumber(void)
+{
+       serverlist_entry_t *cache;
+       int hostnr;
+
+       VM_SAFEPARMCOUNT(2, VM_M_getserverliststring);
+
+       PRVM_G_INT(OFS_RETURN) = 0;
+
+       hostnr = PRVM_G_FLOAT(OFS_PARM1);
+
+       if(hostnr < 0 || hostnr >= serverlist_viewcount)
+       {
+               Con_Print("VM_M_getserverliststring: bad hostnr passed!\n");
+               return;
+       }
+       cache = serverlist_viewlist[hostnr];
+       switch( (int) PRVM_G_FLOAT(OFS_PARM0) ) {
+               case SLIF_MAXPLAYERS:
+                       PRVM_G_FLOAT( OFS_RETURN ) = cache->info.maxplayers;
+                       break;
+               case SLIF_NUMPLAYERS:
+                       PRVM_G_FLOAT( OFS_RETURN ) = cache->info.numplayers;
+                       break;
+               case SLIF_PING:
+                       PRVM_G_FLOAT( OFS_RETURN ) = cache->info.ping;
+                       break;
+               case SLIF_PROTOCOL:
+                       PRVM_G_FLOAT( OFS_RETURN ) = cache->info.protocol;
+                       break;
+               default:
+                       Con_Print("VM_M_getserverlistnumber: bad field number passed!\n");
+       }
+}
+
+/*
+========================
+VM_M_setserverlistsort
+
+setserverlistsort(float field, float descending)
+========================
+*/
+void VM_M_setserverlistsort( void )
+{
+       VM_SAFEPARMCOUNT( 2, VM_M_setserverlistsort );
+
+       serverlist_sortbyfield = (int) PRVM_G_FLOAT( OFS_PARM0 );
+       serverlist_sortdescending = (qboolean) PRVM_G_FLOAT( OFS_PARM1 );
+}
+
+/*
+========================
+VM_M_refreshserverlist
+
+refreshserverlist()
+========================
+*/
+void VM_M_refreshserverlist( void )
+{
+       VM_SAFEPARMCOUNT( 0, VM_M_refreshserverlist );
+       ServerList_QueryList();
+}
+
+/*
+========================
+VM_M_getserverlistindexforkey
+
+float getserverlistindexforkey(string key)
+========================
+*/
+void VM_M_getserverlistindexforkey( void )
+{
+       const char *key;
+       VM_SAFEPARMCOUNT( 1, VM_M_getserverlistindexforkey );
+
+       key = PRVM_G_STRING( OFS_PARM0 );
+       VM_CheckEmptyString( key );
+
+       if( !strcmp( key, "cname" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_CNAME;
+       else if( !strcmp( key, "ping" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_PING;
+       else if( !strcmp( key, "game" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_GAME;
+       else if( !strcmp( key, "mod" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MOD;
+       else if( !strcmp( key, "map" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MAP;
+       else if( !strcmp( key, "name" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_NAME;
+       else if( !strcmp( key, "maxplayers" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_MAXPLAYERS;
+       else if( !strcmp( key, "numplayers" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_NUMPLAYERS;
+       else if( !strcmp( key, "protocol" ) )
+               PRVM_G_FLOAT( OFS_RETURN ) = SLIF_PROTOCOL;
+       else
+               PRVM_G_FLOAT( OFS_RETURN ) = -1;
+}
+
+/*
+========================
+VM_M_addwantedserverlistkey
+
+addwantedserverlistkey(string key)
+========================
+*/
+void VM_M_addwantedserverlistkey( void )
+{
+       VM_SAFEPARMCOUNT( 1, VM_M_addwantedserverlistkey );
+}
+
 prvm_builtin_t vm_m_builtins[] = {
        0, // to be consistent with the old vm
        // common builtings (mostly)
 prvm_builtin_t vm_m_builtins[] = {
        0, // to be consistent with the old vm
        // common builtings (mostly)
@@ -2711,18 +3946,33 @@ prvm_builtin_t vm_m_builtins[] = {
        VM_tokenize,
        VM_argv,
        VM_isserver,    // 60
        VM_tokenize,
        VM_argv,
        VM_isserver,    // 60
-       VM_clientcount, 
-       VM_clientstate, 
+       VM_clientcount,
+       VM_clientstate,
        VM_clcommand,
        VM_changelevel,
        VM_clcommand,
        VM_changelevel,
-       VM_localsound,  
+       VM_localsound,
        VM_getmousepos,
        VM_gettime,
        VM_loadfromdata,
        VM_loadfromfile,
        VM_modulo,              // 70
        VM_getmousepos,
        VM_gettime,
        VM_loadfromdata,
        VM_loadfromfile,
        VM_modulo,              // 70
-       e10,                    // 80
-       e10,                    // 90
+       VM_str_cvar,
+       VM_crash,
+       VM_stackdump,   // 73
+       VM_search_begin,
+       VM_search_end,
+       VM_search_getsize,
+       VM_search_getfilename, // 77
+       VM_chr,
+       VM_itof,
+       VM_ftoi,                // 80
+       VM_itof,                // isString
+       VM_altstr_count,
+       VM_altstr_prepare,
+       VM_altstr_get,
+       VM_altstr_set,
+       VM_altstr_ins,  // 86
+       0,0,0,0,        // 90
        e10,                    // 100
        e100,                   // 200
        e100,                   // 300
        e10,                    // 100
        e100,                   // 200
        e100,                   // 300
@@ -2749,11 +3999,16 @@ prvm_builtin_t vm_m_builtins[] = {
        VM_drawcharacter,
        VM_drawstring,
        VM_drawpic,
        VM_drawcharacter,
        VM_drawstring,
        VM_drawpic,
-       VM_drawfill,    
+       VM_drawfill,
        VM_drawsetcliparea,
        VM_drawresetcliparea,
        VM_getimagesize,// 460
        VM_drawsetcliparea,
        VM_drawresetcliparea,
        VM_getimagesize,// 460
-       e10,                    // 470
+       VM_cin_open,
+       VM_cin_close,
+       VM_cin_setstate,
+       VM_cin_getstate,
+       VM_cin_restart, // 465
+       0,0,0,0,0,      // 470
        e10,                    // 480
        e10,                    // 490
        e10,                    // 500
        e10,                    // 480
        e10,                    // 490
        e10,                    // 500
@@ -2762,7 +4017,26 @@ prvm_builtin_t vm_m_builtins[] = {
        VM_M_setkeydest,
        VM_M_getkeydest,
        VM_M_setmousetarget,
        VM_M_setkeydest,
        VM_M_getkeydest,
        VM_M_setmousetarget,
-       VM_M_getmousetarget
+       VM_M_getmousetarget,
+       VM_M_callfunction,
+       VM_M_writetofile,
+       VM_M_isfunction,
+       VM_M_getresolution,
+       VM_M_keynumtostring,
+       VM_M_findkeysforcommand,// 610
+       VM_M_getserverliststat,
+       VM_M_getserverliststring,
+       VM_M_parseentitydata,
+       VM_M_stringtokeynum,
+       VM_M_resetserverlistmasks,
+       VM_M_setserverlistmaskstring,
+       VM_M_setserverlistmasknumber,
+       VM_M_resortserverlist,
+       VM_M_setserverlistsort,
+       VM_M_refreshserverlist,
+       VM_M_getserverlistnumber,
+       VM_M_getserverlistindexforkey,
+       VM_M_addwantedserverlistkey // 623
 };
 
 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
 };
 
 const int vm_m_numbuiltins = sizeof(vm_m_builtins) / sizeof(prvm_builtin_t);
@@ -2774,6 +4048,6 @@ void VM_M_Cmd_Init(void)
 
 void VM_M_Cmd_Reset(void)
 {
 
 void VM_M_Cmd_Reset(void)
 {
-       VM_Cmd_Init();
+       //VM_Cmd_Init();
+       VM_Cmd_Reset();
 }
 }
-