]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
cvar, prvm_cmds: Remove redundant Cmd_Exists checks
[xonotic/darkplaces.git] / prvm_cmds.c
index e375a50da8a205f0d1b9c1d567171fcbab788c76..07adabf396246c2a6ec3b0e140ff3d389b1813c7 100644 (file)
@@ -21,7 +21,7 @@ extern cvar_t prvm_backtraceforwarnings;
 extern dllhandle_t ode_dll;
 #endif
 
-// LordHavoc: changed this to NOT use a return statement, so that it can be used in functions that must return a value
+// LadyHavoc: changed this to NOT use a return statement, so that it can be used in functions that must return a value
 void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
 {
        va_list argptr;
@@ -32,12 +32,12 @@ void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
        dpvsnprintf(msg,sizeof(msg),fmt,argptr);
        va_end(argptr);
 
-       Con_Print(msg);
+       Con_Printf(CON_WARN "%s", msg);
 
        // TODO: either add a cvar/cmd to control the state dumping or replace some of the calls with Con_Printf [9/13/2006 Black]
-       if(prvm_backtraceforwarnings.integer && recursive != realtime) // NOTE: this compares to the time, just in case if PRVM_PrintState causes a Host_Error and keeps recursive set
+       if(prvm_backtraceforwarnings.integer && recursive != host.realtime) // NOTE: this compares to the time, just in case if PRVM_PrintState causes a Host_Error and keeps recursive set
        {
-               recursive = realtime;
+               recursive = host.realtime;
                PRVM_PrintState(prog, 0);
                recursive = -1;
        }
@@ -49,8 +49,8 @@ void VM_Warning(prvm_prog_t *prog, const char *fmt, ...)
 
 // TODO DONE: move vm_files and vm_fssearchlist to prvm_prog_t struct
 // TODO: move vm_files and vm_fssearchlist back [9/13/2006 Black]
-// TODO: (move vm_files and vm_fssearchlist to prvm_prog_t struct again) [2007-01-23 LordHavoc]
-// TODO: will this war ever end? [2007-01-23 LordHavoc]
+// TODO: (move vm_files and vm_fssearchlist to prvm_prog_t struct again) [2007-01-23 LadyHavoc]
+// TODO: will this war ever end? [2007-01-23 LadyHavoc]
 
 void VM_CheckEmptyString(prvm_prog_t *prog, const char *s)
 {
@@ -58,6 +58,34 @@ void VM_CheckEmptyString(prvm_prog_t *prog, const char *s)
                prog->error_cmd("%s: Bad string", prog->name);
 }
 
+qbool PRVM_ConsoleCommand (prvm_prog_t *prog, const char *text, int *func, qbool preserve_self, int curself, double ptime, qbool prog_loaded, const char *error_message)
+{
+       int restorevm_tempstringsbuf_cursize;
+       int save_self = 0; // hush compiler warning
+       qbool r = false;
+
+       if(!prog_loaded)
+               return false;
+
+       if(func)
+       {
+               if(preserve_self)
+                       save_self = PRVM_gameglobaledict(self);
+               if(ptime)
+                       PRVM_gameglobalfloat(time) = ptime;
+               PRVM_gameglobaledict(self) = curself;
+               restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+               PRVM_G_INT(OFS_PARM0) = PRVM_SetTempString(prog, text);
+               prog->ExecuteProgram(prog, *func, error_message);
+               prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+               if(preserve_self)
+                       PRVM_gameglobaledict(self) = save_self;
+               r = (int) PRVM_G_FLOAT(OFS_RETURN) != 0;
+       }
+
+       return r;
+}
+
 void VM_GenerateFrameGroupBlend(prvm_prog_t *prog, framegroupblend_t *framegroupblend, const prvm_edict_t *ed)
 {
        // self.frame is the interpolation target (new frame)
@@ -84,10 +112,10 @@ void VM_GenerateFrameGroupBlend(prvm_prog_t *prog, framegroupblend_t *framegroup
        framegroupblend[0].lerp = 1 - framegroupblend[1].lerp - framegroupblend[2].lerp - framegroupblend[3].lerp;
 }
 
-// LordHavoc: quite tempting to break apart this function to reuse the
+// LadyHavoc: quite tempting to break apart this function to reuse the
 //            duplicated code, but I suspect it is better for performance
 //            this way
-void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroupblend_t *framegroupblend, const dp_model_t *model, double curtime)
+void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroupblend_t *framegroupblend, const model_t *model, double curtime)
 {
        int sub2, numframes, f, i, k;
        int isfirstframegroup = true;
@@ -99,13 +127,16 @@ void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroup
 
        memset(blend, 0, MAX_FRAMEBLENDS * sizeof(*blend));
 
-       if (!model || !model->surfmesh.isanimated)
+       // rpolzer: Not testing isanimated here - a model might have
+       // "animations" that move no vertices (but only bones), thus rendering
+       // may assume it's not animated while processing can't.
+       if (!model)
        {
                blend[0].lerp = 1;
                return;
        }
 
-       nolerp = (model->type == mod_sprite) ? !r_lerpsprites.integer : !r_lerpmodels.integer;
+       nolerp = ((model->type == mod_sprite) ? !r_lerpsprites.integer : !r_lerpmodels.integer) || (model->nolerp == true);
        numframes = model->numframes;
        for (k = 0, g = framegroupblend;k < MAX_FRAMEGROUPBLENDS;k++, g++)
        {
@@ -185,7 +216,7 @@ void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroup
        }
 }
 
-void VM_UpdateEdictSkeleton(prvm_prog_t *prog, prvm_edict_t *ed, const dp_model_t *edmodel, const frameblend_t *frameblend)
+void VM_UpdateEdictSkeleton(prvm_prog_t *prog, prvm_edict_t *ed, const model_t *edmodel, const frameblend_t *frameblend)
 {
        if (ed->priv.server->skeleton.model != edmodel)
        {
@@ -260,22 +291,13 @@ checkextension(extensionname)
 */
 
 // kind of helper function
-static qboolean checkextension(prvm_prog_t *prog, const char *name)
+static qbool checkextension(prvm_prog_t *prog, const char *name)
 {
-       int len;
-       const char *e, *start;
-       len = (int)strlen(name);
+       const char **e;
 
        for (e = prog->extensionstring;*e;e++)
        {
-               while (*e == ' ')
-                       e++;
-               if (!*e)
-                       break;
-               start = e;
-               while (*e && *e != ' ')
-                       e++;
-               if ((e - start) == len && !strncasecmp(start, name, len))
+               if(!strcasecmp(*e, name))
                {
 #ifdef USEODE
                        // special sheck for ODE
@@ -328,7 +350,7 @@ void VM_error(prvm_prog_t *prog)
        char string[VM_STRINGTEMP_LENGTH];
 
        VM_VarString(prog, 0, string, sizeof(string));
-       Con_Printf("======%s ERROR in %s:\n%s\n", prog->name, PRVM_GetString(prog, prog->xfunction->s_name), string);
+       Con_Printf(CON_ERROR "======%s ERROR in %s:\n%s\n", prog->name, PRVM_GetString(prog, prog->xfunction->s_name), string);
        ed = PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self));
        PRVM_ED_Print(prog, ed, NULL);
 
@@ -351,11 +373,11 @@ void VM_objerror(prvm_prog_t *prog)
        char string[VM_STRINGTEMP_LENGTH];
 
        VM_VarString(prog, 0, string, sizeof(string));
-       Con_Printf("======OBJECT ERROR======\n"); // , prog->name, PRVM_GetString(prog->xfunction->s_name), string); // or include them? FIXME
+       Con_Printf(CON_ERROR "======OBJECT ERROR======\n"); // , prog->name, PRVM_GetString(prog->xfunction->s_name), string); // or include them? FIXME
        ed = PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self));
        PRVM_ED_Print(prog, ed, NULL);
        PRVM_ED_Free (prog, ed);
-       Con_Printf("%s OBJECT ERROR in %s:\n%s\nTip: read above for entity information\n", prog->name, PRVM_GetString(prog, prog->xfunction->s_name), string);
+       Con_Printf(CON_ERROR "%s OBJECT ERROR in %s:\n%s\nTip: read above for entity information\n", prog->name, PRVM_GetString(prog, prog->xfunction->s_name), string);
 }
 
 /*
@@ -601,7 +623,7 @@ void VM_break(prvm_prog_t *prog)
 
 /*
 =================
-VM_localcmd
+VM_localcmd_local
 
 Sends text over to the client's execution buffer
 
@@ -609,19 +631,37 @@ Sends text over to the client's execution buffer
 cmd (string, ...)
 =================
 */
-void VM_localcmd(prvm_prog_t *prog)
+void VM_localcmd_local(prvm_prog_t *prog)
+{
+       char string[VM_STRINGTEMP_LENGTH];
+       VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd_local);
+       VM_VarString(prog, 0, string, sizeof(string));
+       Cbuf_AddText(cmd_local, string);
+}
+
+/*
+=================
+VM_localcmd_server
+
+Sends text over to the server's execution buffer
+
+[localcmd (string, ...) or]
+cmd (string, ...)
+=================
+*/
+void VM_localcmd_server(prvm_prog_t *prog)
 {
        char string[VM_STRINGTEMP_LENGTH];
-       VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd);
+       VM_SAFEPARMCOUNTRANGE(1, 8, VM_localcmd_server);
        VM_VarString(prog, 0, string, sizeof(string));
-       Cbuf_AddText(string);
+       Cbuf_AddText(cmd_local, string);
 }
 
-static qboolean PRVM_Cvar_ReadOk(const char *string)
+static qbool PRVM_Cvar_ReadOk(prvm_prog_t *prog, const char *string)
 {
        cvar_t *cvar;
-       cvar = Cvar_FindVar(string);
-       return ((cvar) && ((cvar->flags & CVAR_PRIVATE) == 0));
+       cvar = Cvar_FindVar(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask);
+       return ((cvar) && ((cvar->flags & CF_PRIVATE) == 0));
 }
 
 /*
@@ -637,7 +677,7 @@ void VM_cvar(prvm_prog_t *prog)
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar);
        VM_VarString(prog, 0, string, sizeof(string));
        VM_CheckEmptyString(prog, string);
-       PRVM_G_FLOAT(OFS_RETURN) = PRVM_Cvar_ReadOk(string) ? Cvar_VariableValue(string) : 0;
+       PRVM_G_FLOAT(OFS_RETURN) = PRVM_Cvar_ReadOk(prog, string) ? Cvar_VariableValue(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask) : 0;
 }
 
 /*
@@ -659,10 +699,10 @@ void VM_cvar_type(prvm_prog_t *prog)
        cvar_t *cvar;
        int ret;
 
-       VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar);
+       VM_SAFEPARMCOUNTRANGE(1, 8, VM_cvar_type);
        VM_VarString(prog, 0, string, sizeof(string));
        VM_CheckEmptyString(prog, string);
-       cvar = Cvar_FindVar(string);
+       cvar = Cvar_FindVar(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask);
 
 
        if(!cvar)
@@ -672,15 +712,15 @@ void VM_cvar_type(prvm_prog_t *prog)
        }
 
        ret = 1; // CVAR_EXISTS
-       if(cvar->flags & CVAR_SAVE)
+       if(cvar->flags & CF_ARCHIVE)
                ret |= 2; // CVAR_TYPE_SAVED
-       if(cvar->flags & CVAR_PRIVATE)
+       if(cvar->flags & CF_PRIVATE)
                ret |= 4; // CVAR_TYPE_PRIVATE
-       if(!(cvar->flags & CVAR_ALLOCATED))
+       if(!(cvar->flags & CF_ALLOCATED))
                ret |= 8; // CVAR_TYPE_ENGINE
        if(cvar->description != cvar_dummy_description)
                ret |= 16; // CVAR_TYPE_HASDESCRIPTION
-       if(cvar->flags & CVAR_READONLY)
+       if(cvar->flags & CF_READONLY)
                ret |= 32; // CVAR_TYPE_READONLY
        
        PRVM_G_FLOAT(OFS_RETURN) = ret;
@@ -699,7 +739,7 @@ void VM_cvar_string(prvm_prog_t *prog)
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_string);
        VM_VarString(prog, 0, string, sizeof(string));
        VM_CheckEmptyString(prog, string);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, PRVM_Cvar_ReadOk(string) ? Cvar_VariableString(string) : "");
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, PRVM_Cvar_ReadOk(prog, string) ? Cvar_VariableString(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask) : "");
 }
 
 
@@ -716,7 +756,7 @@ void VM_cvar_defstring(prvm_prog_t *prog)
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_defstring);
        VM_VarString(prog, 0, string, sizeof(string));
        VM_CheckEmptyString(prog, string);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Cvar_VariableDefString(string));
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Cvar_VariableDefString(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask));
 }
 
 /*
@@ -732,7 +772,7 @@ void VM_cvar_description(prvm_prog_t *prog)
        VM_SAFEPARMCOUNTRANGE(1,8,VM_cvar_description);
        VM_VarString(prog, 0, string, sizeof(string));
        VM_CheckEmptyString(prog, string);
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Cvar_VariableDescription(string));
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, Cvar_VariableDescription(prog->console_cmd->cvars, string, prog->console_cmd->cvars_flagsmask));
 }
 /*
 =================
@@ -749,7 +789,7 @@ void VM_cvar_set(prvm_prog_t *prog)
        VM_VarString(prog, 1, string, sizeof(string));
        name = PRVM_G_STRING(OFS_PARM0);
        VM_CheckEmptyString(prog, name);
-       Cvar_Set(name, string);
+       Cvar_Set(prog->console_cmd->cvars, name, string);
 }
 
 /*
@@ -1023,7 +1063,7 @@ void VM_find(prvm_prog_t *prog)
        f = PRVM_G_INT(OFS_PARM1);
        s = PRVM_G_STRING(OFS_PARM2);
 
-       // LordHavoc: apparently BloodMage does a find(world, weaponmodel, "") and
+       // LadyHavoc: apparently BloodMage does a find(world, weaponmodel, "") and
        // expects it to find all the monsters, so we must be careful to support
        // searching for ""
 
@@ -1054,12 +1094,12 @@ VM_findfloat
   entity       findentity(entity start, .entity field, entity match)
 =========
 */
-// LordHavoc: added this for searching float, int, and entity reference fields
+// LadyHavoc: added this for searching float, int, and entity reference fields
 void VM_findfloat(prvm_prog_t *prog)
 {
        int             e;
        int             f;
-       float   s;
+       prvm_vec_t      s;
        prvm_edict_t    *ed;
 
        VM_SAFEPARMCOUNT(3,VM_findfloat);
@@ -1115,7 +1155,7 @@ void VM_findchain(prvm_prog_t *prog)
        f = PRVM_G_INT(OFS_PARM0);
        s = PRVM_G_STRING(OFS_PARM1);
 
-       // LordHavoc: apparently BloodMage does a find(world, weaponmodel, "") and
+       // LadyHavoc: apparently BloodMage does a find(world, weaponmodel, "") and
        // expects it to find all the monsters, so we must be careful to support
        // searching for ""
 
@@ -1146,13 +1186,13 @@ entity  findchainfloat(.string field, float match)
 entity findchainentity(.string field, entity match)
 =========
 */
-// LordHavoc: chained search for float, int, and entity reference fields
+// LadyHavoc: chained search for float, int, and entity reference fields
 // entity(.string field, float match) findchainfloat = #403;
 void VM_findchainfloat(prvm_prog_t *prog)
 {
        int             i;
        int             f;
-       float   s;
+       prvm_vec_t      s;
        prvm_edict_t    *ent, *chain;
        int chainfield;
 
@@ -1193,7 +1233,7 @@ VM_findflags
 entity findflags(entity start, .float field, float match)
 ========================
 */
-// LordHavoc: search for flags in float fields
+// LadyHavoc: search for flags in float fields
 void VM_findflags(prvm_prog_t *prog)
 {
        prvm_int_t      e;
@@ -1233,7 +1273,7 @@ VM_findchainflags
 entity findchainflags(.float field, float match)
 ========================
 */
-// LordHavoc: chained search for flags in float fields
+// LadyHavoc: chained search for flags in float fields
 void VM_findchainflags(prvm_prog_t *prog)
 {
        prvm_int_t              i;
@@ -1325,9 +1365,9 @@ void VM_coredump(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0,VM_coredump);
 
-       Cbuf_AddText("prvm_edicts ");
-       Cbuf_AddText(prog->name);
-       Cbuf_AddText("\n");
+       Cbuf_AddText(cmd_local, "prvm_edicts ");
+       Cbuf_AddText(cmd_local, prog->name);
+       Cbuf_AddText(cmd_local, "\n");
 }
 
 /*
@@ -1508,7 +1548,7 @@ void VM_changelevel(prvm_prog_t *prog)
                return;
        svs.changelevel_issued = true;
 
-       Cbuf_AddText(va(vabuf, sizeof(vabuf), "changelevel %s\n",PRVM_G_STRING(OFS_PARM0)));
+       Cbuf_AddText(cmd_local, va(vabuf, sizeof(vabuf), "changelevel %s\n", PRVM_G_STRING(OFS_PARM0)));
 }
 
 /*
@@ -1648,21 +1688,21 @@ void VM_registercvar(prvm_prog_t *prog)
        flags = prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : 0;
        PRVM_G_FLOAT(OFS_RETURN) = 0;
 
-       if(flags > CVAR_MAXFLAGSVAL)
+       if(flags > CF_MAXFLAGSVAL)
                return;
 
 // first check to see if it has already been defined
-       if (Cvar_FindVar (name))
+       if (Cvar_FindVar (prog->console_cmd->cvars, name, prog->console_cmd->cvars_flagsmask))
                return;
 
 // check for overlap with a command
-       if (Cmd_Exists (name))
+       if (Cmd_Exists(cmd_local, name))
        {
                VM_Warning(prog, "VM_registercvar: %s is a command\n", name);
                return;
        }
 
-       Cvar_Get(name, value, flags, NULL);
+       Cvar_Get(prog->console_cmd->cvars, name, value, prog->console_cmd->cvars_flagsmask | flags, NULL);
 
        PRVM_G_FLOAT(OFS_RETURN) = 1; // success
 }
@@ -1680,7 +1720,7 @@ float min(float a, float b, ...[float])
 void VM_min(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_min);
-       // LordHavoc: 3+ argument enhancement suggested by FrikaC
+       // LadyHavoc: 3+ argument enhancement suggested by FrikaC
        if (prog->argc >= 3)
        {
                int i;
@@ -1706,7 +1746,7 @@ float     max(float a, float b, ...[float])
 void VM_max(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNTRANGE(2, 8, VM_max);
-       // LordHavoc: 3+ argument enhancement suggested by FrikaC
+       // LadyHavoc: 3+ argument enhancement suggested by FrikaC
        if (prog->argc >= 3)
        {
                int i;
@@ -2031,7 +2071,7 @@ Return name of the specified field as a string, or empty if the field is invalid
 */
 void VM_entityfieldname(prvm_prog_t *prog)
 {
-       ddef_t *d;
+       mdef_t *d;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
 
        if (i < 0 || i >= prog->numfielddefs)
@@ -2055,7 +2095,7 @@ float(float fieldnum) entityfieldtype
 */
 void VM_entityfieldtype(prvm_prog_t *prog)
 {
-       ddef_t *d;
+       mdef_t *d;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
        
        if (i < 0 || i >= prog->numfielddefs)
@@ -2080,7 +2120,7 @@ string(float fieldnum, entity ent) getentityfieldstring
 void VM_getentityfieldstring(prvm_prog_t *prog)
 {
        // put the data into a string
-       ddef_t *d;
+       mdef_t *d;
        int type, j;
        prvm_eval_t *val;
        prvm_edict_t * ent;
@@ -2130,7 +2170,7 @@ float(float fieldnum, entity ent, string s) putentityfieldstring
 */
 void VM_putentityfieldstring(prvm_prog_t *prog)
 {
-       ddef_t *d;
+       mdef_t *d;
        prvm_edict_t * ent;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
 
@@ -2189,7 +2229,7 @@ void VM_strdecolorize(prvm_prog_t *prog)
        // Prepare Strings
        VM_SAFEPARMCOUNT(1,VM_strdecolorize);
        szString = PRVM_G_STRING(OFS_PARM0);
-       COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), TRUE);
+       COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), true);
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString);
 }
 
@@ -2212,8 +2252,8 @@ void VM_strlennocol(prvm_prog_t *prog)
 
        szString = PRVM_G_STRING(OFS_PARM0);
 
-       //nCnt = COM_StringLengthNoColors(szString, 0, NULL);
-       nCnt = u8_COM_StringLengthNoColors(szString, 0, NULL);
+       //nCnt = (int)COM_StringLengthNoColors(szString, 0, NULL);
+       nCnt = (int)u8_COM_StringLengthNoColors(szString, 0, NULL);
 
        PRVM_G_FLOAT(OFS_RETURN) = nCnt;
 }
@@ -2327,7 +2367,7 @@ void VM_substring(prvm_prog_t *prog)
 
        if (start < 0) // FTE_STRINGS feature
        {
-               u_slength = u8_strlen(s);
+               u_slength = (int)u8_strlen(s);
                start += u_slength;
                start = bound(0, start, u_slength);
        }
@@ -2335,7 +2375,7 @@ void VM_substring(prvm_prog_t *prog)
        if (length < 0) // FTE_STRINGS feature
        {
                if (!u_slength) // it's not calculated when it's not needed above
-                       u_slength = u8_strlen(s);
+                       u_slength = (int)u8_strlen(s);
                length += u_slength - start + 1;
        }
                
@@ -2437,7 +2477,7 @@ void VM_strireplace(prvm_prog_t *prog)
        char string[VM_STRINGTEMP_LENGTH];
        int search_len, replace_len, subject_len;
 
-       VM_SAFEPARMCOUNT(3,VM_strreplace);
+       VM_SAFEPARMCOUNT(3, VM_strireplace);
 
        search = PRVM_G_STRING(OFS_PARM0);
        replace = PRVM_G_STRING(OFS_PARM1);
@@ -2543,36 +2583,6 @@ void VM_strunzone(prvm_prog_t *prog)
        PRVM_FreeString(prog, PRVM_G_INT(OFS_PARM0));
 }
 
-/*
-=========
-VM_command (used by client and menu)
-
-clientcommand(float client, string s) (for client and menu)
-=========
-*/
-//void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
-//this function originally written by KrimZon, made shorter by LordHavoc
-void VM_clcommand (prvm_prog_t *prog)
-{
-       client_t *temp_client;
-       int i;
-
-       VM_SAFEPARMCOUNT(2,VM_clcommand);
-
-       i = (int)PRVM_G_FLOAT(OFS_PARM0);
-       if (!sv.active  || i < 0 || i >= svs.maxclients || !svs.clients[i].active)
-       {
-               VM_Warning(prog, "VM_clientcommand: %s: invalid client/server is not active !\n", prog->name);
-               return;
-       }
-
-       temp_client = host_client;
-       host_client = svs.clients + i;
-       Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client, true);
-       host_client = temp_client;
-}
-
-
 /*
 =========
 VM_tokenize
@@ -2581,8 +2591,8 @@ float tokenize(string s)
 =========
 */
 //float(string s) tokenize = #441; // takes apart a string into individal words (access them with argv), returns how many
-//this function originally written by KrimZon, made shorter by LordHavoc
-//20040203: rewritten by LordHavoc (no longer uses allocations)
+//this function originally written by KrimZon, made shorter by LadyHavoc
+//20040203: rewritten by LadyHavoc (no longer uses allocations)
 static int num_tokens = 0;
 static int tokens[VM_STRINGTEMP_LENGTH / 2];
 static int tokens_startpos[VM_STRINGTEMP_LENGTH / 2];
@@ -2623,7 +2633,7 @@ void VM_tokenize_console (prvm_prog_t *prog)
 {
        const char *p;
 
-       VM_SAFEPARMCOUNT(1,VM_tokenize);
+       VM_SAFEPARMCOUNT(1, VM_tokenize_console);
 
        strlcpy(tokenize_string, PRVM_G_STRING(OFS_PARM0), sizeof(tokenize_string));
        p = tokenize_string;
@@ -2686,7 +2696,7 @@ void VM_tokenizebyseparator (prvm_prog_t *prog)
                if (!s[0])
                        continue;
                separators[numseparators] = s;
-               separatorlen[numseparators] = strlen(s);
+               separatorlen[numseparators] = (int)strlen(s);
                numseparators++;
        }
 
@@ -2728,7 +2738,7 @@ void VM_tokenizebyseparator (prvm_prog_t *prog)
 }
 
 //string(float n) argv = #442; // returns a word from the tokenized string (returns nothing for an invalid index)
-//this function originally written by KrimZon, made shorter by LordHavoc
+//this function originally written by KrimZon, made shorter by LadyHavoc
 void VM_argv (prvm_prog_t *prog)
 {
        int token_num;
@@ -2791,9 +2801,9 @@ float     isserver()
 */
 void VM_isserver(prvm_prog_t *prog)
 {
-       VM_SAFEPARMCOUNT(0,VM_serverstate);
+       VM_SAFEPARMCOUNT(0, VM_isserver);
 
-       PRVM_G_FLOAT(OFS_RETURN) = sv.active && (svs.maxclients > 1 || cls.state == ca_dedicated);
+       PRVM_G_FLOAT(OFS_RETURN) = sv.active;
 }
 
 /*
@@ -2872,9 +2882,7 @@ VM_gettime
 float  gettime(prvm_prog_t *prog)
 =========
 */
-#ifdef CONFIG_CD
 float CDAudio_GetPosition(void);
-#endif
 void VM_gettime(prvm_prog_t *prog)
 {
        int timer_index;
@@ -2883,7 +2891,7 @@ void VM_gettime(prvm_prog_t *prog)
 
        if(prog->argc == 0)
        {
-               PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t) realtime;
+               PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t) host.realtime;
        }
        else
        {
@@ -2891,25 +2899,23 @@ void VM_gettime(prvm_prog_t *prog)
                switch(timer_index)
                {
                        case 0: // GETTIME_FRAMESTART
-                               PRVM_G_FLOAT(OFS_RETURN) = realtime;
+                               PRVM_G_FLOAT(OFS_RETURN) = host.realtime;
                                break;
                        case 1: // GETTIME_REALTIME
                                PRVM_G_FLOAT(OFS_RETURN) = Sys_DirtyTime();
                                break;
                        case 2: // GETTIME_HIRES
-                               PRVM_G_FLOAT(OFS_RETURN) = (Sys_DirtyTime() - host_dirtytime);
+                               PRVM_G_FLOAT(OFS_RETURN) = (Sys_DirtyTime() - host.dirtytime);
                                break;
                        case 3: // GETTIME_UPTIME
-                               PRVM_G_FLOAT(OFS_RETURN) = realtime;
+                               PRVM_G_FLOAT(OFS_RETURN) = host.realtime;
                                break;
-#ifdef CONFIG_CD
                        case 4: // GETTIME_CDTRACK
                                PRVM_G_FLOAT(OFS_RETURN) = CDAudio_GetPosition();
                                break;
-#endif
                        default:
                                VM_Warning(prog, "VM_gettime: %s: unsupported timer specified, returning realtime\n", prog->name);
-                               PRVM_G_FLOAT(OFS_RETURN) = realtime;
+                               PRVM_G_FLOAT(OFS_RETURN) = host.realtime;
                                break;
                }
        }
@@ -2971,7 +2977,7 @@ loadfromdata(string data)
 */
 void VM_loadfromdata(prvm_prog_t *prog)
 {
-       VM_SAFEPARMCOUNT(1,VM_loadentsfromfile);
+       VM_SAFEPARMCOUNT(1, VM_loadfromdata);
 
        PRVM_ED_LoadFromFile(prog, PRVM_G_STRING(OFS_PARM0));
 }
@@ -3048,7 +3054,7 @@ float     mod(float val, float m)
 void VM_modulo(prvm_prog_t *prog)
 {
        prvm_int_t val, m;
-       VM_SAFEPARMCOUNT(2,VM_module);
+       VM_SAFEPARMCOUNT(2, VM_modulo);
 
        val = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM0);
        m       = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM1);
@@ -3079,16 +3085,16 @@ static void VM_Search_Reset(prvm_prog_t *prog)
 =========
 VM_search_begin
 
-float search_begin(string pattern, float caseinsensitive, float quiet)
+float search_begin(string pattern, float caseinsensitive, float quiet[, string packfile])
 =========
 */
 void VM_search_begin(prvm_prog_t *prog)
 {
        int handle;
-       const char *pattern;
+       const char *packfile = NULL, *pattern;
        int caseinsens, quiet;
 
-       VM_SAFEPARMCOUNT(3, VM_search_begin);
+       VM_SAFEPARMCOUNTRANGE(3, 4, VM_search_begin);
 
        pattern = PRVM_G_STRING(OFS_PARM0);
 
@@ -3097,6 +3103,10 @@ void VM_search_begin(prvm_prog_t *prog)
        caseinsens = (int)PRVM_G_FLOAT(OFS_PARM1);
        quiet = (int)PRVM_G_FLOAT(OFS_PARM2);
 
+       // optional packfile parameter (DP_QC_FS_SEARCH_PACKFILE)
+       if(prog->argc >= 4)
+               packfile = PRVM_G_STRING(OFS_PARM3);
+
        for(handle = 0; handle < PRVM_MAX_OPENSEARCHES; handle++)
                if(!prog->opensearches[handle])
                        break;
@@ -3108,7 +3118,7 @@ void VM_search_begin(prvm_prog_t *prog)
                return;
        }
 
-       if(!(prog->opensearches[handle] = FS_Search(pattern,caseinsens, quiet)))
+       if(!(prog->opensearches[handle] = FS_Search(pattern,caseinsens, quiet, packfile)))
                PRVM_G_FLOAT(OFS_RETURN) = -1;
        else
        {
@@ -3158,7 +3168,7 @@ float     search_getsize(float handle)
 void VM_search_getsize(prvm_prog_t *prog)
 {
        int handle;
-       VM_SAFEPARMCOUNT(1, VM_M_search_getsize);
+       VM_SAFEPARMCOUNT(1, VM_search_getsize);
 
        handle = (int)PRVM_G_FLOAT(OFS_PARM0);
 
@@ -3238,729 +3248,6 @@ void VM_chr(prvm_prog_t *prog)
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, tmp);
 }
 
-//=============================================================================
-// Draw builtins (client & menu)
-
-/*
-=========
-VM_iscachedpic
-
-float  iscachedpic(string pic)
-=========
-*/
-void VM_iscachedpic(prvm_prog_t *prog)
-{
-       VM_SAFEPARMCOUNT(1,VM_iscachedpic);
-
-       // drawq hasnt such a function, thus always return true
-       PRVM_G_FLOAT(OFS_RETURN) = false;
-}
-
-/*
-=========
-VM_precache_pic
-
-string precache_pic(string pic)
-=========
-*/
-#define PRECACHE_PIC_FROMWAD 1 /* FTEQW, not supported here */
-#define PRECACHE_PIC_NOTPERSISTENT 2
-//#define PRECACHE_PIC_NOCLAMP 4
-#define PRECACHE_PIC_MIPMAP 8
-void VM_precache_pic(prvm_prog_t *prog)
-{
-       const char      *s;
-       int flags = 0;
-
-       VM_SAFEPARMCOUNTRANGE(1, 2, VM_precache_pic);
-
-       s = PRVM_G_STRING(OFS_PARM0);
-       PRVM_G_INT(OFS_RETURN) = PRVM_G_INT(OFS_PARM0);
-       VM_CheckEmptyString(prog, s);
-
-       if(prog->argc >= 2)
-       {
-               int f = PRVM_G_FLOAT(OFS_PARM1);
-               if(f & PRECACHE_PIC_NOTPERSISTENT)
-                       flags |= CACHEPICFLAG_NOTPERSISTENT;
-               //if(f & PRECACHE_PIC_NOCLAMP)
-               //      flags |= CACHEPICFLAG_NOCLAMP;
-               if(f & PRECACHE_PIC_MIPMAP)
-                       flags |= CACHEPICFLAG_MIPMAP;
-       }
-
-       // AK Draw_CachePic is supposed to always return a valid pointer
-       if( Draw_CachePic_Flags(s, flags)->tex == r_texture_notexture )
-               PRVM_G_INT(OFS_RETURN) = OFS_NULL;
-}
-
-/*
-=========
-VM_freepic
-
-freepic(string s)
-=========
-*/
-void VM_freepic(prvm_prog_t *prog)
-{
-       const char *s;
-
-       VM_SAFEPARMCOUNT(1,VM_freepic);
-
-       s = PRVM_G_STRING(OFS_PARM0);
-       VM_CheckEmptyString(prog, s);
-
-       Draw_FreePic(s);
-}
-
-static void getdrawfontscale(prvm_prog_t *prog, float *sx, float *sy)
-{
-       vec3_t v;
-       *sx = *sy = 1;
-       VectorCopy(PRVM_drawglobalvector(drawfontscale), v);
-       if(VectorLength2(v) > 0)
-       {
-               *sx = v[0];
-               *sy = v[1];
-       }
-}
-
-static dp_font_t *getdrawfont(prvm_prog_t *prog)
-{
-       int f = (int) PRVM_drawglobalfloat(drawfont);
-       if(f < 0 || f >= dp_fonts.maxsize)
-               return FONT_DEFAULT;
-       return &dp_fonts.f[f];
-}
-
-/*
-=========
-VM_drawcharacter
-
-float  drawcharacter(vector position, float character, vector scale, vector rgb, float alpha, float flag)
-=========
-*/
-void VM_drawcharacter(prvm_prog_t *prog)
-{
-       prvm_vec_t *pos,*scale,*rgb;
-       char   character;
-       int flag;
-       float sx, sy;
-       VM_SAFEPARMCOUNT(6,VM_drawcharacter);
-
-       character = (char) PRVM_G_FLOAT(OFS_PARM1);
-       if(character == 0)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -1;
-               VM_Warning(prog, "VM_drawcharacter: %s passed null character !\n",prog->name);
-               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)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawcharacter: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
-               return;
-       }
-
-       if(pos[2] || scale[2])
-               VM_Warning(prog, "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])
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -3;
-               VM_Warning(prog, "VM_drawcharacter: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
-               return;
-       }
-
-       getdrawfontscale(prog, &sx, &sy);
-       DrawQ_String_Scale(pos[0], pos[1], &character, 1, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont(prog));
-       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(prvm_prog_t *prog)
-{
-       prvm_vec_t *pos,*scale,*rgb;
-       const char  *string;
-       int flag = 0;
-       float sx, sy;
-       VM_SAFEPARMCOUNTRANGE(5,6,VM_drawstring);
-
-       string = PRVM_G_STRING(OFS_PARM1);
-       pos = PRVM_G_VECTOR(OFS_PARM0);
-       scale = PRVM_G_VECTOR(OFS_PARM2);
-       rgb = PRVM_G_VECTOR(OFS_PARM3);
-       if (prog->argc >= 6)
-               flag = (int)PRVM_G_FLOAT(OFS_PARM5);
-
-       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawstring: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
-               return;
-       }
-
-       if(!scale[0] || !scale[1])
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -3;
-               VM_Warning(prog, "VM_drawstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
-               return;
-       }
-
-       if(pos[2] || scale[2])
-               VM_Warning(prog, "VM_drawstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
-
-       getdrawfontscale(prog, &sx, &sy);
-       DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true, getdrawfont(prog));
-       //Font_DrawString(pos[0], pos[1], string, 0, scale[0], scale[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag, NULL, true);
-       PRVM_G_FLOAT(OFS_RETURN) = 1;
-}
-
-/*
-=========
-VM_drawcolorcodedstring
-
-float  drawcolorcodedstring(vector position, string text, vector scale, float alpha, float flag)
-/
-float  drawcolorcodedstring(vector position, string text, vector scale, vector rgb, float alpha, float flag)
-=========
-*/
-void VM_drawcolorcodedstring(prvm_prog_t *prog)
-{
-       prvm_vec_t *pos, *scale;
-       const char  *string;
-       int flag;
-       vec3_t rgb;
-       float sx, sy, alpha;
-
-       VM_SAFEPARMCOUNTRANGE(5,6,VM_drawcolorcodedstring);
-
-       if (prog->argc == 6) // full 6 parms, like normal drawstring
-       {
-               pos = PRVM_G_VECTOR(OFS_PARM0);
-               string = PRVM_G_STRING(OFS_PARM1);
-               scale = PRVM_G_VECTOR(OFS_PARM2);
-               VectorCopy(PRVM_G_VECTOR(OFS_PARM3), rgb); 
-               alpha = PRVM_G_FLOAT(OFS_PARM4);
-               flag = (int)PRVM_G_FLOAT(OFS_PARM5);
-       }
-       else
-       {
-               pos = PRVM_G_VECTOR(OFS_PARM0);
-               string = PRVM_G_STRING(OFS_PARM1);
-               scale = PRVM_G_VECTOR(OFS_PARM2);
-               rgb[0] = 1.0;
-               rgb[1] = 1.0;
-               rgb[2] = 1.0;
-               alpha = PRVM_G_FLOAT(OFS_PARM3);
-               flag = (int)PRVM_G_FLOAT(OFS_PARM4);
-       }
-
-       if(flag < DRAWFLAG_NORMAL || flag >= DRAWFLAG_NUMFLAGS)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawcolorcodedstring: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
-               return;
-       }
-
-       if(!scale[0] || !scale[1])
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -3;
-               VM_Warning(prog, "VM_drawcolorcodedstring: scale %s is null !\n", (scale[0] == 0) ? ((scale[1] == 0) ? "x and y" : "x") : "y");
-               return;
-       }
-
-       if(pos[2] || scale[2])
-               VM_Warning(prog, "VM_drawcolorcodedstring: z value%s from %s discarded\n",(pos[2] && scale[2]) ? "s" : " ",((pos[2] && scale[2]) ? "pos and scale" : (pos[2] ? "pos" : "scale")));
-
-       getdrawfontscale(prog, &sx, &sy);
-       DrawQ_String_Scale(pos[0], pos[1], string, 0, scale[0], scale[1], sx, sy, rgb[0], rgb[1], rgb[2], alpha, flag, NULL, false, getdrawfont(prog));
-       if (prog->argc == 6) // also return vector of last color
-               VectorCopy(DrawQ_Color, PRVM_G_VECTOR(OFS_RETURN));
-       else
-               PRVM_G_FLOAT(OFS_RETURN) = 1;
-}
-/*
-=========
-VM_stringwidth
-
-float  stringwidth(string text, float allowColorCodes, float size)
-=========
-*/
-void VM_stringwidth(prvm_prog_t *prog)
-{
-       const char  *string;
-       vec2_t szv;
-       float mult; // sz is intended font size so we can later add freetype support, mult is font size multiplier in pixels per character cell
-       int colors;
-       float sx, sy;
-       size_t maxlen = 0;
-       VM_SAFEPARMCOUNTRANGE(2,3,VM_drawstring);
-
-       getdrawfontscale(prog, &sx, &sy);
-       if(prog->argc == 3)
-       {
-               Vector2Copy(PRVM_G_VECTOR(OFS_PARM2), szv);
-               mult = 1;
-       }
-       else
-       {
-               // we want the width for 8x8 font size, divided by 8
-               Vector2Set(szv, 8, 8);
-               mult = 0.125;
-               // to make sure snapping is turned off, ALWAYS use a nontrivial scale in this case
-               if(sx >= 0.9 && sx <= 1.1)
-               {
-                       mult *= 2;
-                       sx /= 2;
-                       sy /= 2;
-               }
-       }
-
-       string = PRVM_G_STRING(OFS_PARM0);
-       colors = (int)PRVM_G_FLOAT(OFS_PARM1);
-
-       PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth_UntilWidth_TrackColors_Scale(string, &maxlen, szv[0], szv[1], sx, sy, NULL, !colors, getdrawfont(prog), 1000000000) * mult;
-/*
-       if(prog->argc == 3)
-       {
-               mult = sz = PRVM_G_FLOAT(OFS_PARM2);
-       }
-       else
-       {
-               sz = 8;
-               mult = 1;
-       }
-
-       string = PRVM_G_STRING(OFS_PARM0);
-       colors = (int)PRVM_G_FLOAT(OFS_PARM1);
-
-       PRVM_G_FLOAT(OFS_RETURN) = DrawQ_TextWidth(string, 0, !colors, getdrawfont()) * mult; // 1x1 characters, don't actually draw
-*/
-}
-
-/*
-=========
-VM_findfont
-
-float findfont(string s)
-=========
-*/
-
-static float getdrawfontnum(const char *fontname)
-{
-       int i;
-
-       for(i = 0; i < dp_fonts.maxsize; ++i)
-               if(!strcmp(dp_fonts.f[i].title, fontname))
-                       return i;
-       return -1;
-}
-
-void VM_findfont(prvm_prog_t *prog)
-{
-       VM_SAFEPARMCOUNT(1,VM_findfont);
-       PRVM_G_FLOAT(OFS_RETURN) = getdrawfontnum(PRVM_G_STRING(OFS_PARM0));
-}
-
-/*
-=========
-VM_loadfont
-
-float loadfont(string fontname, string fontmaps, string sizes, float slot)
-=========
-*/
-
-void VM_loadfont(prvm_prog_t *prog)
-{
-       const char *fontname, *filelist, *sizes, *c, *cm;
-       char mainfont[MAX_QPATH];
-       int i, numsizes;
-       float sz, scale, voffset;
-       dp_font_t *f;
-
-       VM_SAFEPARMCOUNTRANGE(3,6,VM_loadfont);
-
-       fontname = PRVM_G_STRING(OFS_PARM0);
-       if (!fontname[0])
-               fontname = "default";
-
-       filelist = PRVM_G_STRING(OFS_PARM1);
-       if (!filelist[0])
-               filelist = "gfx/conchars";
-
-       sizes = PRVM_G_STRING(OFS_PARM2);
-       if (!sizes[0])
-               sizes = "10";
-
-       // find a font
-       f = NULL;
-       if (prog->argc >= 4)
-       {
-               i = PRVM_G_FLOAT(OFS_PARM3);
-               if (i >= 0 && i < dp_fonts.maxsize)
-               {
-                       f = &dp_fonts.f[i];
-                       strlcpy(f->title, fontname, sizeof(f->title)); // replace name
-               }
-       }
-       if (!f)
-               f = FindFont(fontname, true);
-       if (!f)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -1;
-               return; // something go wrong
-       }
-
-       memset(f->fallbacks, 0, sizeof(f->fallbacks));
-       memset(f->fallback_faces, 0, sizeof(f->fallback_faces));
-
-       // first font is handled "normally"
-       c = strchr(filelist, ':');
-       cm = strchr(filelist, ',');
-       if(c && (!cm || c < cm))
-               f->req_face = atoi(c+1);
-       else
-       {
-               f->req_face = 0;
-               c = cm;
-       }
-       if(!c || (c - filelist) > MAX_QPATH)
-               strlcpy(mainfont, filelist, sizeof(mainfont));
-       else
-       {
-               memcpy(mainfont, filelist, c - filelist);
-               mainfont[c - filelist] = 0;
-       }
-
-       // handle fallbacks
-       for(i = 0; i < MAX_FONT_FALLBACKS; ++i)
-       {
-               c = strchr(filelist, ',');
-               if(!c)
-                       break;
-               filelist = c + 1;
-               if(!*filelist)
-                       break;
-               c = strchr(filelist, ':');
-               cm = strchr(filelist, ',');
-               if(c && (!cm || c < cm))
-                       f->fallback_faces[i] = atoi(c+1);
-               else
-               {
-                       f->fallback_faces[i] = 0; // f->req_face; could make it stick to the default-font's face index
-                       c = cm;
-               }
-               if(!c || (c-filelist) > MAX_QPATH)
-               {
-                       strlcpy(f->fallbacks[i], filelist, sizeof(mainfont));
-               }
-               else
-               {
-                       memcpy(f->fallbacks[i], filelist, c - filelist);
-                       f->fallbacks[i][c - filelist] = 0;
-               }
-       }
-
-       // handle sizes
-       for(i = 0; i < MAX_FONT_SIZES; ++i)
-               f->req_sizes[i] = -1;
-       for (numsizes = 0,c = sizes;;)
-       {
-               if (!COM_ParseToken_VM_Tokenize(&c, 0))
-                       break;
-               sz = atof(com_token);
-               // detect crap size
-               if (sz < 0.001f || sz > 1000.0f)
-               {
-                       VM_Warning(prog, "VM_loadfont: crap size %s", com_token);
-                       continue;
-               }
-               // check overflow
-               if (numsizes == MAX_FONT_SIZES)
-               {
-                       VM_Warning(prog, "VM_loadfont: MAX_FONT_SIZES = %i exceeded", MAX_FONT_SIZES);
-                       break;
-               }
-               f->req_sizes[numsizes] = sz;
-               numsizes++;
-       }
-
-       // additional scale/hoffset parms
-       scale = 1;
-       voffset = 0;
-       if (prog->argc >= 5)
-       {
-               scale = PRVM_G_FLOAT(OFS_PARM4);
-               if (scale <= 0)
-                       scale = 1;
-       }
-       if (prog->argc >= 6)
-               voffset = PRVM_G_FLOAT(OFS_PARM5);
-
-       // load
-       LoadFont(true, mainfont, f, scale, voffset);
-
-       // return index of loaded font
-       PRVM_G_FLOAT(OFS_RETURN) = (f - dp_fonts.f);
-}
-
-/*
-=========
-VM_drawpic
-
-float  drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag)
-=========
-*/
-void VM_drawpic(prvm_prog_t *prog)
-{
-       const char *picname;
-       prvm_vec_t *size, *pos, *rgb;
-       int flag = 0;
-
-       VM_SAFEPARMCOUNTRANGE(5,6,VM_drawpic);
-
-       picname = PRVM_G_STRING(OFS_PARM1);
-       VM_CheckEmptyString(prog, picname);
-
-       // is pic cached ? no function yet for that
-       if(!1)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -4;
-               VM_Warning(prog, "VM_drawpic: %s: %s not cached !\n", prog->name, picname);
-               return;
-       }
-
-       pos = PRVM_G_VECTOR(OFS_PARM0);
-       size = PRVM_G_VECTOR(OFS_PARM2);
-       rgb = PRVM_G_VECTOR(OFS_PARM3);
-       if (prog->argc >= 6)
-               flag = (int) PRVM_G_FLOAT(OFS_PARM5);
-
-       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
-               return;
-       }
-
-       if(pos[2] || size[2])
-               VM_Warning(prog, "VM_drawpic: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
-
-       DrawQ_Pic(pos[0], pos[1], Draw_CachePic_Flags (picname, CACHEPICFLAG_NOTPERSISTENT), size[0], size[1], rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM4), flag);
-       PRVM_G_FLOAT(OFS_RETURN) = 1;
-}
-/*
-=========
-VM_drawrotpic
-
-float  drawrotpic(vector position, string pic, vector size, vector org, float angle, vector rgb, float alpha, float flag)
-=========
-*/
-void VM_drawrotpic(prvm_prog_t *prog)
-{
-       const char *picname;
-       prvm_vec_t *size, *pos, *org, *rgb;
-       int flag;
-
-       VM_SAFEPARMCOUNT(8,VM_drawrotpic);
-
-       picname = PRVM_G_STRING(OFS_PARM1);
-       VM_CheckEmptyString(prog, picname);
-
-       // is pic cached ? no function yet for that
-       if(!1)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -4;
-               VM_Warning(prog, "VM_drawrotpic: %s: %s not cached !\n", prog->name, picname);
-               return;
-       }
-
-       pos = PRVM_G_VECTOR(OFS_PARM0);
-       size = PRVM_G_VECTOR(OFS_PARM2);
-       org = PRVM_G_VECTOR(OFS_PARM3);
-       rgb = PRVM_G_VECTOR(OFS_PARM5);
-       flag = (int) PRVM_G_FLOAT(OFS_PARM7);
-
-       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawrotpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
-               return;
-       }
-
-       if(pos[2] || size[2] || org[2])
-               VM_Warning(prog, "VM_drawrotpic: z value from pos/size/org discarded\n");
-
-       DrawQ_RotPic(pos[0], pos[1], Draw_CachePic_Flags(picname, CACHEPICFLAG_NOTPERSISTENT), size[0], size[1], org[0], org[1], PRVM_G_FLOAT(OFS_PARM4), rgb[0], rgb[1], rgb[2], PRVM_G_FLOAT(OFS_PARM6), flag);
-       PRVM_G_FLOAT(OFS_RETURN) = 1;
-}
-/*
-=========
-VM_drawsubpic
-
-float  drawsubpic(vector position, vector size, string pic, vector srcPos, vector srcSize, vector rgb, float alpha, float flag)
-
-=========
-*/
-void VM_drawsubpic(prvm_prog_t *prog)
-{
-       const char *picname;
-       prvm_vec_t *size, *pos, *rgb, *srcPos, *srcSize, alpha;
-       int flag;
-
-       VM_SAFEPARMCOUNT(8,VM_drawsubpic);
-
-       picname = PRVM_G_STRING(OFS_PARM2);
-       VM_CheckEmptyString(prog, picname);
-
-       // is pic cached ? no function yet for that
-       if(!1)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -4;
-               VM_Warning(prog, "VM_drawsubpic: %s: %s not cached !\n", prog->name, picname);
-               return;
-       }
-
-       pos = PRVM_G_VECTOR(OFS_PARM0);
-       size = PRVM_G_VECTOR(OFS_PARM1);
-       srcPos = PRVM_G_VECTOR(OFS_PARM3);
-       srcSize = PRVM_G_VECTOR(OFS_PARM4);
-       rgb = PRVM_G_VECTOR(OFS_PARM5);
-       alpha = PRVM_G_FLOAT(OFS_PARM6);
-       flag = (int) PRVM_G_FLOAT(OFS_PARM7);
-
-       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawsubpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
-               return;
-       }
-
-       if(pos[2] || size[2])
-               VM_Warning(prog, "VM_drawsubpic: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
-
-       DrawQ_SuperPic(pos[0], pos[1], Draw_CachePic_Flags (picname, CACHEPICFLAG_NOTPERSISTENT),
-               size[0], size[1],
-               srcPos[0],              srcPos[1],              rgb[0], rgb[1], rgb[2], alpha,
-               srcPos[0] + srcSize[0], srcPos[1],              rgb[0], rgb[1], rgb[2], alpha,
-               srcPos[0],              srcPos[1] + srcSize[1], rgb[0], rgb[1], rgb[2], alpha,
-               srcPos[0] + srcSize[0], srcPos[1] + srcSize[1], rgb[0], rgb[1], rgb[2], alpha,
-               flag);
-       PRVM_G_FLOAT(OFS_RETURN) = 1;
-}
-
-/*
-=========
-VM_drawfill
-
-float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
-=========
-*/
-void VM_drawfill(prvm_prog_t *prog)
-{
-       prvm_vec_t *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)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawfill: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
-               return;
-       }
-
-       if(pos[2] || size[2])
-               VM_Warning(prog, "VM_drawfill: z value%s from %s discarded\n",(pos[2] && size[2]) ? "s" : " ",((pos[2] && size[2]) ? "pos and size" : (pos[2] ? "pos" : "size")));
-
-       DrawQ_Fill(pos[0], pos[1], 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(prvm_prog_t *prog)
-{
-       float x,y,w,h;
-       VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
-
-       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);
-}
-
-/*
-=========
-VM_drawresetcliparea
-
-drawresetcliparea()
-=========
-*/
-void VM_drawresetcliparea(prvm_prog_t *prog)
-{
-       VM_SAFEPARMCOUNT(0,VM_drawresetcliparea);
-
-       DrawQ_ResetClipArea();
-}
-
-/*
-=========
-VM_getimagesize
-
-vector getimagesize(string pic)
-=========
-*/
-void VM_getimagesize(prvm_prog_t *prog)
-{
-       const char *p;
-       cachepic_t *pic;
-
-       VM_SAFEPARMCOUNT(1,VM_getimagesize);
-
-       p = PRVM_G_STRING(OFS_PARM0);
-       VM_CheckEmptyString(prog, p);
-
-       pic = Draw_CachePic_Flags (p, CACHEPICFLAG_NOTPERSISTENT);
-       if( pic->tex == r_texture_notexture )
-       {
-               PRVM_G_VECTOR(OFS_RETURN)[0] = 0;
-               PRVM_G_VECTOR(OFS_RETURN)[1] = 0;
-       }
-       else
-       {
-               PRVM_G_VECTOR(OFS_RETURN)[0] = pic->width;
-               PRVM_G_VECTOR(OFS_RETURN)[1] = pic->height;
-       }
-       PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
-}
-
 /*
 =========
 VM_keynumtostring
@@ -4024,7 +3311,7 @@ float stringtokeynum(string key)
 */
 void VM_stringtokeynum (prvm_prog_t *prog)
 {
-       VM_SAFEPARMCOUNT( 1, VM_keynumtostring );
+       VM_SAFEPARMCOUNT( 1, VM_stringtokeynum );
 
        PRVM_G_FLOAT(OFS_RETURN) = Key_StringToKeynum(PRVM_G_STRING(OFS_PARM0));
 }
@@ -4039,7 +3326,7 @@ string getkeybind(float key, float bindmap)
 void VM_getkeybind (prvm_prog_t *prog)
 {
        int bindmap;
-       VM_SAFEPARMCOUNTRANGE(1, 2, VM_CL_getkeybind);
+       VM_SAFEPARMCOUNTRANGE(1, 2, VM_getkeybind);
        if(prog->argc == 2)
                bindmap = bound(-1, PRVM_G_FLOAT(OFS_PARM1), MAX_BINDMAPS-1);
        else
@@ -4058,7 +3345,7 @@ float setkeybind(float key, string cmd, float bindmap)
 void VM_setkeybind (prvm_prog_t *prog)
 {
        int bindmap;
-       VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_setkeybind);
+       VM_SAFEPARMCOUNTRANGE(2, 3, VM_setkeybind);
        if(prog->argc == 3)
                bindmap = bound(-1, PRVM_G_FLOAT(OFS_PARM2), MAX_BINDMAPS-1);
        else
@@ -4079,7 +3366,7 @@ vector getbindmaps()
 void VM_getbindmaps (prvm_prog_t *prog)
 {
        int fg, bg;
-       VM_SAFEPARMCOUNT(0, VM_CL_getbindmap);
+       VM_SAFEPARMCOUNT(0, VM_getbindmaps);
        Key_GetBindMap(&fg, &bg);
        PRVM_G_VECTOR(OFS_RETURN)[0] = fg;
        PRVM_G_VECTOR(OFS_RETURN)[1] = bg;
@@ -4095,130 +3382,13 @@ float setbindmaps(vector bindmap)
 */
 void VM_setbindmaps (prvm_prog_t *prog)
 {
-       VM_SAFEPARMCOUNT(1, VM_CL_setbindmap);
+       VM_SAFEPARMCOUNT(1, VM_setbindmaps);
        PRVM_G_FLOAT(OFS_RETURN) = 0;
        if(PRVM_G_VECTOR(OFS_PARM0)[2] == 0)
                if(Key_SetBindMap((int)PRVM_G_VECTOR(OFS_PARM0)[0], (int)PRVM_G_VECTOR(OFS_PARM0)[1]))
                        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 
-// CL_Video interface functions
-
-/*
-========================
-VM_cin_open
-
-float cin_open(string file, string name)
-========================
-*/
-void VM_cin_open(prvm_prog_t *prog)
-{
-       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(prog,  file );
-    VM_CheckEmptyString(prog,  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(prvm_prog_t *prog)
-{
-       const char *name;
-
-       VM_SAFEPARMCOUNT( 1, VM_cin_close );
-
-       name = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString(prog,  name );
-
-       CL_CloseVideo( CL_GetVideoByName( name ) );
-}
-
-/*
-========================
-VM_cin_setstate
-void cin_setstate(string name, float type)
-========================
-*/
-void VM_cin_setstate(prvm_prog_t *prog)
-{
-       const char *name;
-       clvideostate_t  state;
-       clvideo_t               *video;
-
-       VM_SAFEPARMCOUNT( 2, VM_cin_netstate );
-
-       name = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString(prog,  name );
-
-       state = (clvideostate_t)((int)PRVM_G_FLOAT( OFS_PARM1 ));
-
-       video = CL_GetVideoByName( 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(prvm_prog_t *prog)
-{
-       const char *name;
-       clvideo_t               *video;
-
-       VM_SAFEPARMCOUNT( 1, VM_cin_getstate );
-
-       name = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString(prog,  name );
-
-       video = CL_GetVideoByName( 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(prvm_prog_t *prog)
-{
-       const char *name;
-       clvideo_t               *video;
-
-       VM_SAFEPARMCOUNT( 1, VM_cin_restart );
-
-       name = PRVM_G_STRING( OFS_PARM0 );
-       VM_CheckEmptyString(prog,  name );
-
-       video = CL_GetVideoByName( name );
-       if( video )
-               CL_RestartVideo( video );
-}
-
 /*
 ========================
 VM_gecko_create
@@ -4342,29 +3512,6 @@ void VM_vectorvectors (prvm_prog_t *prog)
        VectorCopy(up, PRVM_gameglobalvector(v_up));
 }
 
-/*
-========================
-VM_drawline
-
-void drawline(float width, vector pos1, vector pos2, vector rgb, float alpha, float flags)
-========================
-*/
-void VM_drawline (prvm_prog_t *prog)
-{
-       prvm_vec_t      *c1, *c2, *rgb;
-       float   alpha, width;
-       unsigned char   flags;
-
-       VM_SAFEPARMCOUNT(6, VM_drawline);
-       width   = PRVM_G_FLOAT(OFS_PARM0);
-       c1              = PRVM_G_VECTOR(OFS_PARM1);
-       c2              = PRVM_G_VECTOR(OFS_PARM2);
-       rgb             = PRVM_G_VECTOR(OFS_PARM3);
-       alpha   = PRVM_G_FLOAT(OFS_PARM4);
-       flags   = (int)PRVM_G_FLOAT(OFS_PARM5);
-       DrawQ_Line(width, c1[0], c1[1], c2[0], c2[1], rgb[0], rgb[1], rgb[2], alpha, flags);
-}
-
 // float(float number, float quantity) bitshift (EXT_BITSHIFT)
 void VM_bitshift (prvm_prog_t *prog)
 {
@@ -4425,23 +3572,25 @@ string altstr_prepare(string)
 */
 void VM_altstr_prepare(prvm_prog_t *prog)
 {
-       char *out;
        const char *instr, *in;
-       int size;
        char outstr[VM_STRINGTEMP_LENGTH];
+       size_t outpos;
 
        VM_SAFEPARMCOUNT( 1, VM_altstr_prepare );
 
        instr = PRVM_G_STRING( OFS_PARM0 );
 
-       for( out = outstr, in = instr, size = sizeof(outstr) - 1 ; size && *in ; size--, in++, out++ )
-               if( *in == '\'' ) {
-                       *out++ = '\\';
-                       *out = '\'';
-                       size--;
-               } else
-                       *out = *in;
-       *out = 0;
+       for (in = instr, outpos = 0; *in && outpos < sizeof(outstr) - 1; ++in)
+       {
+               if (*in == '\'' && outpos < sizeof(outstr) - 2)
+               {
+                       outstr[outpos++] = '\\';
+                       outstr[outpos++] = '\'';
+               }
+               else
+                       outstr[outpos++] = *in;
+       }
+       outstr[outpos] = 0;
 
        PRVM_G_INT( OFS_RETURN ) = PRVM_SetTempString(prog,  outstr );
 }
@@ -4637,7 +3786,7 @@ static int BufStr_SortStringsDOWN (const void *in1, const void *in2)
        return strncmp(b, a, stringbuffers_sortlength);
 }
 
-prvm_stringbuffer_t *BufStr_FindCreateReplace (prvm_prog_t *prog, int bufindex, int flags, char *format)
+prvm_stringbuffer_t *BufStr_FindCreateReplace (prvm_prog_t *prog, int bufindex, int flags, const char *format)
 {
        prvm_stringbuffer_t *stringbuffer;
        int i;
@@ -4718,7 +3867,7 @@ void BufStr_Flush(prvm_prog_t *prog)
        prvm_stringbuffer_t *stringbuffer;
        int i, numbuffers;
 
-       numbuffers = Mem_ExpandableArray_IndexRange(&prog->stringbuffersarray);
+       numbuffers = (int)Mem_ExpandableArray_IndexRange(&prog->stringbuffersarray);
        for (i = 0; i < numbuffers; i++)
                if ( (stringbuffer = (prvm_stringbuffer_t *)Mem_ExpandableArray_RecordAtIndex(&prog->stringbuffersarray, i)) )
                        BufStr_Del(prog, stringbuffer);
@@ -4738,9 +3887,9 @@ void VM_buf_create (prvm_prog_t *prog)
 {
        prvm_stringbuffer_t *stringbuffer;
        int i;
-       
+
        VM_SAFEPARMCOUNTRANGE(0, 2, VM_buf_create);
-       
+
        // VorteX: optional parm1 (buffer format) is unfinished, to keep intact with future databuffers extension must be set to "string"
        if(prog->argc >= 1 && strcmp(PRVM_G_STRING(OFS_PARM0), "string"))
        {
@@ -4859,7 +4008,7 @@ void VM_buf_copy (prvm_prog_t *prog)
 ========================
 VM_buf_sort
 sort buffer by beginnings of strings (cmplength defaults it's length)
-"backward == TRUE" means that sorting goes upside-down
+"backward == true" means that sorting goes upside-down
 void buf_sort(float bufhandle, float cmplength, float backward) = #464;
 ========================
 */
@@ -4998,7 +4147,7 @@ void VM_bufstr_set (prvm_prog_t *prog)
 ========================
 VM_bufstr_add
 adds string to buffer in first free slot and returns its index
-"order == TRUE" means that string will be added after last "full" slot
+"order == true" means that string will be added after last "full" slot
 float bufstr_add(float bufhandle, string str, float order) = #467;
 ========================
 */
@@ -5090,21 +4239,19 @@ void VM_buf_loadfile(prvm_prog_t *prog)
        size_t alloclen;
        prvm_stringbuffer_t *stringbuffer;
        char string[VM_STRINGTEMP_LENGTH];
-       int filenum, strindex, c, end;
+       int strindex, c, end;
        const char *filename;
        char vabuf[1024];
+       qfile_t *file;
 
        VM_SAFEPARMCOUNT(2, VM_buf_loadfile);
 
        // get file
        filename = PRVM_G_STRING(OFS_PARM0);
-       for (filenum = 0;filenum < PRVM_MAX_OPENFILES;filenum++)
-               if (prog->openfiles[filenum] == NULL)
-                       break;
-       prog->openfiles[filenum] = FS_OpenVirtualFile(va(vabuf, sizeof(vabuf), "data/%s", filename), false);
-       if (prog->openfiles[filenum] == NULL)
-               prog->openfiles[filenum] = FS_OpenVirtualFile(va(vabuf, sizeof(vabuf), "%s", filename), false);
-       if (prog->openfiles[filenum] == NULL)
+       file = FS_OpenVirtualFile(va(vabuf, sizeof(vabuf), "data/%s", filename), false);
+       if (file == NULL)
+               file = FS_OpenVirtualFile(va(vabuf, sizeof(vabuf), "%s", filename), false);
+       if (file == NULL)
        {
                if (developer_extra.integer)
                        VM_Warning(prog, "VM_buf_loadfile: failed to open file %s in %s\n", filename, prog->name);
@@ -5129,7 +4276,7 @@ void VM_buf_loadfile(prvm_prog_t *prog)
                end = 0;
                for (;;)
                {
-                       c = FS_Getc(prog->openfiles[filenum]);
+                       c = FS_Getc(file);
                        if (c == '\r' || c == '\n' || c < 0)
                                break;
                        if (end < VM_STRINGTEMP_LENGTH - 1)
@@ -5139,9 +4286,9 @@ void VM_buf_loadfile(prvm_prog_t *prog)
                // remove \n following \r
                if (c == '\r')
                {
-                       c = FS_Getc(prog->openfiles[filenum]);
+                       c = FS_Getc(file);
                        if (c != '\n')
-                               FS_UnGetc(prog->openfiles[filenum], (unsigned char)c);
+                               FS_UnGetc(file, (unsigned char)c);
                }
                // add and continue
                if (c >= 0 || end)
@@ -5158,10 +4305,7 @@ void VM_buf_loadfile(prvm_prog_t *prog)
        }
 
        // close file
-       FS_Close(prog->openfiles[filenum]);
-       prog->openfiles[filenum] = NULL;
-       if (prog->openfiles_origin[filenum])
-               PRVM_Free((char *)prog->openfiles_origin[filenum]);
+       FS_Close(file);
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
 
@@ -5236,7 +4380,7 @@ void VM_buf_writefile(prvm_prog_t *prog)
        {
                if (stringbuffer->strings[strindex])
                {
-                       if ((strlength = strlen(stringbuffer->strings[strindex])))
+                       if ((strlength = (int)strlen(stringbuffer->strings[strindex])))
                                FS_Write(prog->openfiles[filenum], stringbuffer->strings[strindex], strlength);
                        FS_Write(prog->openfiles[filenum], "\n", 1);
                }
@@ -5259,7 +4403,7 @@ static const char *detect_match_rule(char *pattern, int *matchrule)
        char *ppos, *qpos;
        int patternlength;
 
-       patternlength = strlen(pattern);
+       patternlength = (int)strlen(pattern);
        ppos = strchr(pattern, '*');
        qpos = strchr(pattern, '?');
        // has ? - pattern
@@ -5309,7 +4453,7 @@ static const char *detect_match_rule(char *pattern, int *matchrule)
 }
 
 // todo: support UTF8
-static qboolean match_rule(const char *string, int max_string, const char *pattern, int patternlength, int rule)
+static qbool match_rule(const char *string, int max_string, const char *pattern, int patternlength, int rule)
 {
        const char *mid;
 
@@ -5342,7 +4486,7 @@ void VM_bufstr_find(prvm_prog_t *prog)
        char string[VM_STRINGTEMP_LENGTH];
        int matchrule, matchlen, i, step;
        const char *match;
-       
+
        VM_SAFEPARMCOUNTRANGE(3, 5, VM_bufstr_find);
 
        PRVM_G_FLOAT(OFS_RETURN) = -1;
@@ -5357,7 +4501,7 @@ void VM_bufstr_find(prvm_prog_t *prog)
 
        // get pattern/rule
        matchrule = (int)PRVM_G_FLOAT(OFS_PARM2);
-       if (matchrule < 0 && matchrule > 5)
+       if (matchrule < 0 || matchrule > 5)
        {
                VM_Warning(prog, "VM_bufstr_find: invalid match rule %i in %s\n", matchrule, prog->name);
                return;
@@ -5369,7 +4513,7 @@ void VM_bufstr_find(prvm_prog_t *prog)
                strlcpy(string, PRVM_G_STRING(OFS_PARM1), sizeof(string));
                match = detect_match_rule(string, &matchrule);
        }
-       matchlen = strlen(match);
+       matchlen = (int)strlen(match);
 
        // find
        i = (prog->argc > 3) ? (int)PRVM_G_FLOAT(OFS_PARM3) : 0;
@@ -5403,9 +4547,9 @@ void VM_matchpattern(prvm_prog_t *prog)
 
        // get pattern/rule
        matchrule = (int)PRVM_G_FLOAT(OFS_PARM2);
-       if (matchrule < 0 && matchrule > 5)
+       if (matchrule < 0 || matchrule > 5)
        {
-               VM_Warning(prog, "VM_bufstr_find: invalid match rule %i in %s\n", matchrule, prog->name);
+               VM_Warning(prog, "VM_matchpattern: invalid match rule %i in %s\n", matchrule, prog->name);
                return;
        }
        if (matchrule)
@@ -5417,7 +4561,7 @@ void VM_matchpattern(prvm_prog_t *prog)
        }
 
        // offset
-       l = strlen(match);
+       l = (int)strlen(match);
        if (prog->argc > 3)
                s += max(0, min((unsigned int)PRVM_G_FLOAT(OFS_PARM3), strlen(s)-1));
 
@@ -5437,7 +4581,7 @@ void VM_buf_cvarlist(prvm_prog_t *prog)
        const char *partial, *antipartial;
        size_t len, antilen;
        size_t alloclen;
-       qboolean ispattern, antiispattern;
+       qbool ispattern, antiispattern;
        int n;
        prvm_stringbuffer_t     *stringbuffer;
        VM_SAFEPARMCOUNTRANGE(2, 3, VM_buf_cvarlist);
@@ -5475,7 +4619,7 @@ void VM_buf_cvarlist(prvm_prog_t *prog)
        antiispattern = antipartial && (strchr(antipartial, '*') || strchr(antipartial, '?'));
 
        n = 0;
-       for(cvar = cvar_vars; cvar; cvar = cvar->next)
+       for(cvar = prog->console_cmd->cvars->vars; cvar; cvar = cvar->next)
        {
                if(len && (ispattern ? !matchpattern_with_separator(cvar->name, partial, false, "", false) : strncmp(partial, cvar->name, len)))
                        continue;
@@ -5491,7 +4635,7 @@ void VM_buf_cvarlist(prvm_prog_t *prog)
                stringbuffer->strings = (char **)Mem_Alloc(prog->progs_mempool, sizeof(stringbuffer->strings[0]) * stringbuffer->max_strings);
        
        n = 0;
-       for(cvar = cvar_vars; cvar; cvar = cvar->next)
+       for(cvar = prog->console_cmd->cvars->vars; cvar; cvar = cvar->next)
        {
                if(len && (ispattern ? !matchpattern_with_separator(cvar->name, partial, false, "", false) : strncmp(partial, cvar->name, len)))
                        continue;
@@ -5637,7 +4781,7 @@ void VM_uncolorstring (prvm_prog_t *prog)
        // Prepare Strings
        VM_SAFEPARMCOUNT(1, VM_uncolorstring);
        szString = PRVM_G_STRING(OFS_PARM0);
-       COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), TRUE);
+       COM_StringDecolorize(szString, 0, szNewString, sizeof(szNewString), true);
        PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, szNewString);
        
 }
@@ -5652,7 +4796,7 @@ void VM_strstrofs (prvm_prog_t *prog)
        instr = PRVM_G_STRING(OFS_PARM0);
        match = PRVM_G_STRING(OFS_PARM1);
        firstofs = (prog->argc > 2)?(int)PRVM_G_FLOAT(OFS_PARM2):0;
-       firstofs = u8_bytelen(instr, firstofs);
+       firstofs = (int)u8_bytelen(instr, firstofs);
 
        if (firstofs && (firstofs < 0 || firstofs > (int)strlen(instr)))
        {
@@ -5675,7 +4819,7 @@ void VM_str2chr (prvm_prog_t *prog)
        int index;
        VM_SAFEPARMCOUNT(2, VM_str2chr);
        s = PRVM_G_STRING(OFS_PARM0);
-       index = u8_bytelen(s, (int)PRVM_G_FLOAT(OFS_PARM1));
+       index = (int)u8_bytelen(s, (int)PRVM_G_FLOAT(OFS_PARM1));
 
        if((unsigned)index < strlen(s))
        {
@@ -5805,7 +4949,7 @@ void VM_strconv (prvm_prog_t *prog)
        redalpha = (int) PRVM_G_FLOAT(OFS_PARM1);       //0 same, 1 white, 2 red,  5 alternate, 6 alternate-alternate
        rednum = (int) PRVM_G_FLOAT(OFS_PARM2); //0 same, 1 white, 2 red, 3 redspecial, 4 whitespecial, 5 alternate, 6 alternate-alternate
        VM_VarString(prog, 3, (char *) resbuf, sizeof(resbuf));
-       len = strlen((char *) resbuf);
+       len = (int)strlen((char *) resbuf);
 
        for (i = 0; i < len; i++, result++)     //should this be done backwards?
        {
@@ -5957,7 +5101,7 @@ void VM_digest_hex(prvm_prog_t *prog)
        if(!digest)
                digest = "";
        VM_VarString(prog, 1, s, sizeof(s));
-       len = strlen(s);
+       len = (int)strlen(s);
 
        outlen = 0;
 
@@ -6039,11 +5183,14 @@ void VM_Cmd_Init(prvm_prog_t *prog)
        VM_Search_Init(prog);
 }
 
+static void animatemodel_reset(prvm_prog_t *prog);
+
 void VM_Cmd_Reset(prvm_prog_t *prog)
 {
        CL_PurgeOwner( MENUOWNER );
        VM_Search_Reset(prog);
        VM_Files_CloseAll(prog);
+       animatemodel_reset(prog);
 }
 
 // #510 string(string input, ...) uri_escape (DP_QC_URI_ESCAPE)
@@ -6136,7 +5283,7 @@ void VM_whichpack (prvm_prog_t *prog)
        fn = PRVM_G_STRING(OFS_PARM0);
        pack = FS_WhichPack(fn);
 
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, pack ? pack : "");
+       PRVM_G_INT(OFS_RETURN) = pack ? PRVM_SetTempString(prog, pack) : 0;
 }
 
 typedef struct
@@ -6195,7 +5342,7 @@ void VM_uri_get (prvm_prog_t *prog)
 {
        const char *url;
        float id;
-       qboolean ret;
+       qbool ret;
        uri_to_prog_t *handle;
        const char *posttype = NULL;
        const char *postseparator = NULL;
@@ -6447,7 +5594,7 @@ void VM_callfunction(prvm_prog_t *prog)
        func = PRVM_ED_FindFunction(prog, s);
 
        if(!func)
-               prog->error_cmd("VM_callfunciton: function %s not found !", s);
+               prog->error_cmd("VM_callfunction: function %s not found !", s);
        else if (func->first_statement < 0)
        {
                // negative statements are built in functions
@@ -6785,6 +5932,7 @@ nolength:
                                                                o += u8_strpad(o, end - o, buf, (flags & PRINTF_LEFT) != 0, width, precision);
                                                        }
                                                        break;
+                                               //spike FIXME -- 'S' for quoted tokenize-safe-or-print escaping of strings so stuff can safely survive console commands.
                                                case 's':
                                                        if(flags & PRINTF_ALTERNATE)
                                                        {
@@ -6813,7 +5961,8 @@ nolength:
                        default:
 verbatim:
                                if(o < end - 1)
-                                       *o++ = *s++;
+                                       *o++ = *s;
+                               ++s;
                                break;
                }
        }
@@ -6825,7 +5974,7 @@ finished:
 
 // surface querying
 
-static dp_model_t *getmodel(prvm_prog_t *prog, prvm_edict_t *ed)
+static model_t *getmodel(prvm_prog_t *prog, prvm_edict_t *ed)
 {
        if (prog == SVVM_prog)
                return SV_GetModelFromEdict(ed);
@@ -6835,10 +5984,9 @@ static dp_model_t *getmodel(prvm_prog_t *prog, prvm_edict_t *ed)
                return NULL;
 }
 
-typedef struct
+struct animatemodel_cache
 {
-       unsigned int progid;
-       dp_model_t *model;
+       model_t *model;
        frameblend_t frameblend[MAX_FRAMEBLENDS];
        skeleton_t *skeleton_p;
        skeleton_t skeleton;
@@ -6851,61 +5999,74 @@ typedef struct
        float *buf_svector3f;
        float *buf_tvector3f;
        float *buf_normal3f;
+};
+
+static void animatemodel_reset(prvm_prog_t *prog)
+{
+       if (!prog->animatemodel_cache)
+               return;
+       if(prog->animatemodel_cache->buf_vertex3f) Mem_Free(prog->animatemodel_cache->buf_vertex3f);
+       if(prog->animatemodel_cache->buf_svector3f) Mem_Free(prog->animatemodel_cache->buf_svector3f);
+       if(prog->animatemodel_cache->buf_tvector3f) Mem_Free(prog->animatemodel_cache->buf_tvector3f);
+       if(prog->animatemodel_cache->buf_normal3f) Mem_Free(prog->animatemodel_cache->buf_normal3f);
+       Mem_Free(prog->animatemodel_cache);
 }
-animatemodel_cache_t;
-static animatemodel_cache_t animatemodel_cache;
 
-static void animatemodel(prvm_prog_t *prog, dp_model_t *model, prvm_edict_t *ed)
+static void animatemodel(prvm_prog_t *prog, model_t *model, prvm_edict_t *ed)
 {
        skeleton_t *skeleton;
        int skeletonindex = -1;
-       qboolean need = false;
+       qbool need = false;
+       struct animatemodel_cache *animatemodel_cache;
+       if (!prog->animatemodel_cache)
+       {
+               prog->animatemodel_cache = (struct animatemodel_cache *)Mem_Alloc(prog->progs_mempool, sizeof(struct animatemodel_cache));
+               memset(prog->animatemodel_cache, 0, sizeof(struct animatemodel_cache));
+       }
+       animatemodel_cache = prog->animatemodel_cache;
        if(!(model->surfmesh.isanimated && model->AnimateVertices))
        {
-               animatemodel_cache.data_vertex3f = model->surfmesh.data_vertex3f;
-               animatemodel_cache.data_svector3f = model->surfmesh.data_svector3f;
-               animatemodel_cache.data_tvector3f = model->surfmesh.data_tvector3f;
-               animatemodel_cache.data_normal3f = model->surfmesh.data_normal3f;
+               animatemodel_cache->data_vertex3f = model->surfmesh.data_vertex3f;
+               animatemodel_cache->data_svector3f = model->surfmesh.data_svector3f;
+               animatemodel_cache->data_tvector3f = model->surfmesh.data_tvector3f;
+               animatemodel_cache->data_normal3f = model->surfmesh.data_normal3f;
                return;
        }
-       if(animatemodel_cache.progid != prog->id)
-               memset(&animatemodel_cache, 0, sizeof(animatemodel_cache));
-       need |= (animatemodel_cache.model != model);
+       need |= (animatemodel_cache->model != model);
        VM_GenerateFrameGroupBlend(prog, ed->priv.server->framegroupblend, ed);
        VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model, PRVM_serverglobalfloat(time));
-       need |= (memcmp(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend))) != 0;
+       need |= (memcmp(&animatemodel_cache->frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend))) != 0;
        skeletonindex = (int)PRVM_gameedictfloat(ed, skeletonindex) - 1;
        if (!(skeletonindex >= 0 && skeletonindex < MAX_EDICTS && (skeleton = prog->skeletons[skeletonindex]) && skeleton->model->num_bones == ed->priv.server->skeleton.model->num_bones))
                skeleton = NULL;
-       need |= (animatemodel_cache.skeleton_p != skeleton);
+       need |= (animatemodel_cache->skeleton_p != skeleton);
        if(skeleton)
-               need |= (memcmp(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton))) != 0;
+               need |= (memcmp(&animatemodel_cache->skeleton, skeleton, sizeof(ed->priv.server->skeleton))) != 0;
        if(!need)
                return;
-       if(model->surfmesh.num_vertices > animatemodel_cache.max_vertices)
-       {
-               animatemodel_cache.max_vertices = model->surfmesh.num_vertices * 2;
-               if(animatemodel_cache.buf_vertex3f) Mem_Free(animatemodel_cache.buf_vertex3f);
-               if(animatemodel_cache.buf_svector3f) Mem_Free(animatemodel_cache.buf_svector3f);
-               if(animatemodel_cache.buf_tvector3f) Mem_Free(animatemodel_cache.buf_tvector3f);
-               if(animatemodel_cache.buf_normal3f) Mem_Free(animatemodel_cache.buf_normal3f);
-               animatemodel_cache.buf_vertex3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
-               animatemodel_cache.buf_svector3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
-               animatemodel_cache.buf_tvector3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
-               animatemodel_cache.buf_normal3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache.max_vertices);
-       }
-       animatemodel_cache.data_vertex3f = animatemodel_cache.buf_vertex3f;
-       animatemodel_cache.data_svector3f = animatemodel_cache.buf_svector3f;
-       animatemodel_cache.data_tvector3f = animatemodel_cache.buf_tvector3f;
-       animatemodel_cache.data_normal3f = animatemodel_cache.buf_normal3f;
+       if(model->surfmesh.num_vertices > animatemodel_cache->max_vertices)
+       {
+               animatemodel_cache->max_vertices = model->surfmesh.num_vertices * 2;
+               if(animatemodel_cache->buf_vertex3f) Mem_Free(animatemodel_cache->buf_vertex3f);
+               if(animatemodel_cache->buf_svector3f) Mem_Free(animatemodel_cache->buf_svector3f);
+               if(animatemodel_cache->buf_tvector3f) Mem_Free(animatemodel_cache->buf_tvector3f);
+               if(animatemodel_cache->buf_normal3f) Mem_Free(animatemodel_cache->buf_normal3f);
+               animatemodel_cache->buf_vertex3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache->max_vertices);
+               animatemodel_cache->buf_svector3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache->max_vertices);
+               animatemodel_cache->buf_tvector3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache->max_vertices);
+               animatemodel_cache->buf_normal3f = (float *)Mem_Alloc(prog->progs_mempool, sizeof(float[3]) * animatemodel_cache->max_vertices);
+       }
+       animatemodel_cache->data_vertex3f = animatemodel_cache->buf_vertex3f;
+       animatemodel_cache->data_svector3f = animatemodel_cache->buf_svector3f;
+       animatemodel_cache->data_tvector3f = animatemodel_cache->buf_tvector3f;
+       animatemodel_cache->data_normal3f = animatemodel_cache->buf_normal3f;
        VM_UpdateEdictSkeleton(prog, ed, model, ed->priv.server->frameblend);
-       model->AnimateVertices(model, ed->priv.server->frameblend, &ed->priv.server->skeleton, animatemodel_cache.data_vertex3f, animatemodel_cache.data_normal3f, animatemodel_cache.data_svector3f, animatemodel_cache.data_tvector3f);
-       animatemodel_cache.progid = prog->id;
-       animatemodel_cache.model = model;
-       memcpy(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend));
-       animatemodel_cache.skeleton_p = skeleton;
+       model->AnimateVertices(model, ed->priv.server->frameblend, &ed->priv.server->skeleton, animatemodel_cache->data_vertex3f, animatemodel_cache->data_normal3f, animatemodel_cache->data_svector3f, animatemodel_cache->data_tvector3f);
+       animatemodel_cache->model = model;
+       memcpy(&animatemodel_cache->frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend));
+       animatemodel_cache->skeleton_p = skeleton;
        if(skeleton)
-               memcpy(&animatemodel_cache.skeleton, skeleton, sizeof(ed->priv.server->skeleton));
+               memcpy(&animatemodel_cache->skeleton, skeleton, sizeof(ed->priv.server->skeleton));
 }
 
 static void getmatrix(prvm_prog_t *prog, prvm_edict_t *ed, matrix4x4_t *out)
@@ -6949,7 +6110,7 @@ static void applytransform_forward_normal(prvm_prog_t *prog, const vec3_t in, pr
        VectorCopy(p, out);
 }
 
-static void clippointtosurface(prvm_prog_t *prog, prvm_edict_t *ed, dp_model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
+static void clippointtosurface(prvm_prog_t *prog, prvm_edict_t *ed, model_t *model, msurface_t *surface, vec3_t p, vec3_t out)
 {
        int i, j, k;
        float *v[3], facenormal[3], edgenormal[3], sidenormal[3], temp[3], offsetdist, dist, bestdist;
@@ -6961,9 +6122,9 @@ static void clippointtosurface(prvm_prog_t *prog, prvm_edict_t *ed, dp_model_t *
        {
                // clip original point to each triangle of the surface and find the
                // triangle that is closest
-               v[0] = animatemodel_cache.data_vertex3f + e[0] * 3;
-               v[1] = animatemodel_cache.data_vertex3f + e[1] * 3;
-               v[2] = animatemodel_cache.data_vertex3f + e[2] * 3;
+               v[0] = prog->animatemodel_cache->data_vertex3f + e[0] * 3;
+               v[1] = prog->animatemodel_cache->data_vertex3f + e[1] * 3;
+               v[2] = prog->animatemodel_cache->data_vertex3f + e[2] * 3;
                TriangleNormal(v[0], v[1], v[2], facenormal);
                VectorNormalize(facenormal);
                offsetdist = DotProduct(v[0], facenormal) - DotProduct(p, facenormal);
@@ -6986,18 +6147,18 @@ static void clippointtosurface(prvm_prog_t *prog, prvm_edict_t *ed, dp_model_t *
        }
 }
 
-static msurface_t *getsurface(dp_model_t *model, int surfacenum)
+static msurface_t *getsurface(model_t *model, int surfacenum)
 {
-       if (surfacenum < 0 || surfacenum >= model->nummodelsurfaces)
+       if (surfacenum < 0 || surfacenum >= model->submodelsurfaces_end - model->submodelsurfaces_start)
                return NULL;
-       return model->data_surfaces + surfacenum + model->firstmodelsurface;
+       return model->data_surfaces + surfacenum + model->submodelsurfaces_start;
 }
 
 
 //PF_getsurfacenumpoints, // #434 float(entity e, float s) getsurfacenumpoints = #434;
 void VM_getsurfacenumpoints(prvm_prog_t *prog)
 {
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
        VM_SAFEPARMCOUNT(2, VM_getsurfacenumpoints);
        // return 0 if no such surface
@@ -7014,7 +6175,7 @@ void VM_getsurfacenumpoints(prvm_prog_t *prog)
 void VM_getsurfacepoint(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
        int pointnum;
        vec3_t result;
@@ -7028,7 +6189,7 @@ void VM_getsurfacepoint(prvm_prog_t *prog)
        if (pointnum < 0 || pointnum >= surface->num_vertices)
                return;
        animatemodel(prog, model, ed);
-       applytransform_forward(prog, &(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
+       applytransform_forward(prog, &(prog->animatemodel_cache->data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
        VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));
 }
 //PF_getsurfacepointattribute,     // #486 vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
@@ -7042,13 +6203,13 @@ void VM_getsurfacepoint(prvm_prog_t *prog)
 void VM_getsurfacepointattribute(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
        int pointnum;
        int attributetype;
        vec3_t result;
 
-       VM_SAFEPARMCOUNT(4, VM_getsurfacepoint);
+       VM_SAFEPARMCOUNT(4, VM_getsurfacepointattribute);
        VectorClear(PRVM_G_VECTOR(OFS_RETURN));
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!(model = getmodel(prog, ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
@@ -7063,22 +6224,22 @@ void VM_getsurfacepointattribute(prvm_prog_t *prog)
        switch( attributetype ) {
                // float SPA_POSITION = 0;
                case 0:
-                       applytransform_forward(prog, &(animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
+                       applytransform_forward(prog, &(prog->animatemodel_cache->data_vertex3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
                        VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                // float SPA_S_AXIS = 1;
                case 1:
-                       applytransform_forward_direction(prog, &(animatemodel_cache.data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
+                       applytransform_forward_direction(prog, &(prog->animatemodel_cache->data_svector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
                        VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                // float SPA_T_AXIS = 2;
                case 2:
-                       applytransform_forward_direction(prog, &(animatemodel_cache.data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
+                       applytransform_forward_direction(prog, &(prog->animatemodel_cache->data_tvector3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
                        VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                // float SPA_R_AXIS = 3; // same as SPA_NORMAL
                case 3:
-                       applytransform_forward_direction(prog, &(animatemodel_cache.data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
+                       applytransform_forward_direction(prog, &(prog->animatemodel_cache->data_normal3f + 3 * surface->num_firstvertex)[pointnum * 3], ed, result);
                        VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                // float SPA_TEXCOORDS0 = 4;
@@ -7112,7 +6273,7 @@ void VM_getsurfacepointattribute(prvm_prog_t *prog)
 //PF_getsurfacenormal,    // #436 vector(entity e, float s) getsurfacenormal = #436;
 void VM_getsurfacenormal(prvm_prog_t *prog)
 {
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
        vec3_t normal;
        vec3_t result;
@@ -7123,7 +6284,7 @@ void VM_getsurfacenormal(prvm_prog_t *prog)
        // note: this only returns the first triangle, so it doesn't work very
        // well for curved surfaces or arbitrary meshes
        animatemodel(prog, model, PRVM_G_EDICT(OFS_PARM0));
-       TriangleNormal((animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex), (animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex) + 3, (animatemodel_cache.data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
+       TriangleNormal((prog->animatemodel_cache->data_vertex3f + 3 * surface->num_firstvertex), (prog->animatemodel_cache->data_vertex3f + 3 * surface->num_firstvertex) + 3, (prog->animatemodel_cache->data_vertex3f + 3 * surface->num_firstvertex) + 6, normal);
        applytransform_forward_normal(prog, normal, PRVM_G_EDICT(OFS_PARM0), result);
        VectorNormalize(result);
        VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));
@@ -7131,7 +6292,7 @@ void VM_getsurfacenormal(prvm_prog_t *prog)
 //PF_getsurfacetexture,   // #437 string(entity e, float s) getsurfacetexture = #437;
 void VM_getsurfacetexture(prvm_prog_t *prog)
 {
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
        VM_SAFEPARMCOUNT(2, VM_getsurfacetexture);
        PRVM_G_INT(OFS_RETURN) = OFS_NULL;
@@ -7146,7 +6307,7 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog)
        vec3_t clipped, p;
        vec_t dist, bestdist;
        prvm_edict_t *ed;
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
        vec3_t point;
        VM_SAFEPARMCOUNT(2, VM_getsurfacenearpoint);
@@ -7165,9 +6326,9 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog)
        applytransform_inverted(prog, point, ed, p);
        best = -1;
        bestdist = 1000000000;
-       for (surfacenum = 0;surfacenum < model->nummodelsurfaces;surfacenum++)
+       for (surfacenum = model->submodelsurfaces_start;surfacenum < model->submodelsurfaces_end;surfacenum++)
        {
-               surface = model->data_surfaces + surfacenum + model->firstmodelsurface;
+               surface = model->data_surfaces + surfacenum;
                // first see if the nearest point on the surface's box is closer than the previous match
                clipped[0] = bound(surface->mins[0], p[0], surface->maxs[0]) - p[0];
                clipped[1] = bound(surface->mins[1], p[1], surface->maxs[1]) - p[1];
@@ -7182,7 +6343,7 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog)
                        if (dist < bestdist)
                        {
                                // that's closer too, store it as the best match
-                               best = surfacenum;
+                               best = surfacenum - model->submodelsurfaces_start;
                                bestdist = dist;
                        }
                }
@@ -7193,10 +6354,10 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog)
 void VM_getsurfaceclippedpoint(prvm_prog_t *prog)
 {
        prvm_edict_t *ed;
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
        vec3_t p, out, inp;
-       VM_SAFEPARMCOUNT(3, VM_te_getsurfaceclippedpoint);
+       VM_SAFEPARMCOUNT(3, VM_getsurfaceclippedpoint);
        VectorClear(PRVM_G_VECTOR(OFS_RETURN));
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!(model = getmodel(prog, ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
@@ -7211,9 +6372,9 @@ void VM_getsurfaceclippedpoint(prvm_prog_t *prog)
 //PF_getsurfacenumtriangles, // #??? float(entity e, float s) getsurfacenumtriangles = #???;
 void VM_getsurfacenumtriangles(prvm_prog_t *prog)
 {
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
-       VM_SAFEPARMCOUNT(2, VM_SV_getsurfacenumtriangles);
+       VM_SAFEPARMCOUNT(2, VM_getsurfacenumtriangles);
        // return 0 if no such surface
        if (!(model = getmodel(prog, PRVM_G_EDICT(OFS_PARM0))) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
        {
@@ -7228,10 +6389,10 @@ void VM_getsurfacetriangle(prvm_prog_t *prog)
 {
        const vec3_t d = {-1, -1, -1};
        prvm_edict_t *ed;
-       dp_model_t *model;
+       model_t *model;
        msurface_t *surface;
        int trinum;
-       VM_SAFEPARMCOUNT(3, VM_SV_getsurfacetriangle);
+       VM_SAFEPARMCOUNT(3, VM_getsurfacetriangle);
        VectorClear(PRVM_G_VECTOR(OFS_RETURN));
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!(model = getmodel(prog, ed)) || !(surface = getsurface(model, (int)PRVM_G_FLOAT(OFS_PARM1))))
@@ -7346,5 +6507,5 @@ void VM_coverage(prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(0, VM_coverage);
        if (prog->explicit_profile[prog->xstatement]++ == 0 && (prvm_coverage.integer & 2))
-               PRVM_ExplicitCoverageEvent(prog, prog->xstatement);
+               PRVM_ExplicitCoverageEvent(prog, prog->xfunction, prog->xstatement);
 }