]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - prvm_cmds.c
csqc: Implement builtin #177 "localsound"
[xonotic/darkplaces.git] / prvm_cmds.c
index 7be745ef3f203397ab071930943e3e17f24d4287..3ef0b74cf939fc417757249a4e328f1a5d0dcfb8 100644 (file)
@@ -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;
        }
@@ -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)
@@ -87,7 +115,7 @@ void VM_GenerateFrameGroupBlend(prvm_prog_t *prog, framegroupblend_t *framegroup
 // 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;
@@ -108,7 +136,7 @@ void VM_FrameBlendFromFrameGroupBlend(frameblend_t *frameblend, const framegroup
                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++)
        {
@@ -188,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)
        {
@@ -263,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
@@ -331,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);
 
@@ -354,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);
 }
 
 /*
@@ -567,18 +586,29 @@ void VM_random(prvm_prog_t *prog)
 =========
 VM_localsound
 
-localsound(string sample)
+localsound(string sample, float chan, float vol)
 =========
 */
 void VM_localsound(prvm_prog_t *prog)
 {
        const char *s;
+       float chan, vol;
 
-       VM_SAFEPARMCOUNT(1,VM_localsound);
+       VM_SAFEPARMCOUNTRANGE(1, 3,VM_localsound);
 
        s = PRVM_G_STRING(OFS_PARM0);
-
-       if(!S_LocalSound (s))
+       if(prog->argc == 3)
+       {
+               chan = PRVM_G_FLOAT(OFS_PARM1);
+               vol = PRVM_G_FLOAT(OFS_PARM2) == 0 ? 1 : PRVM_G_FLOAT(OFS_PARM2);
+               if(!S_LocalSoundEx(s, chan, vol))
+               {
+                       PRVM_G_FLOAT(OFS_RETURN) = -4;
+                       VM_Warning(prog, "VM_localsound: Failed to play %s for %s !\n", s, prog->name);
+                       return;
+               }
+       }
+       else if(!S_LocalSound (s))
        {
                PRVM_G_FLOAT(OFS_RETURN) = -4;
                VM_Warning(prog, "VM_localsound: Failed to play %s for %s !\n", s, prog->name);
@@ -604,7 +634,7 @@ void VM_break(prvm_prog_t *prog)
 
 /*
 =================
-VM_localcmd
+VM_localcmd_local
 
 Sends text over to the client's execution buffer
 
@@ -612,19 +642,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));
 }
 
 /*
@@ -640,7 +688,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;
 }
 
 /*
@@ -662,10 +710,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)
@@ -675,15 +723,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;
@@ -702,7 +750,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) : "");
 }
 
 
@@ -719,7 +767,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));
 }
 
 /*
@@ -735,7 +783,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));
 }
 /*
 =================
@@ -752,7 +800,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);
 }
 
 /*
@@ -893,7 +941,7 @@ void VM_ftoe(prvm_prog_t *prog)
        VM_SAFEPARMCOUNT(1, VM_ftoe);
 
        ent = (prvm_int_t)PRVM_G_FLOAT(OFS_PARM0);
-       if (ent < 0 || ent >= prog->max_edicts || PRVM_PROG_TO_EDICT(ent)->priv.required->free)
+       if (ent < 0 || ent >= prog->max_edicts || PRVM_PROG_TO_EDICT(ent)->free)
                ent = 0; // return world instead of a free or invalid entity
 
        PRVM_G_INT(OFS_RETURN) = ent;
@@ -996,7 +1044,7 @@ void VM_remove(prvm_prog_t *prog)
                if (developer.integer > 0)
                        VM_Warning(prog, "VM_remove: tried to remove the null entity or a reserved entity!\n" );
        }
-       else if( ed->priv.required->free )
+       else if( ed->free )
        {
                if (developer.integer > 0)
                        VM_Warning(prog, "VM_remove: tried to remove an already freed entity!\n" );
@@ -1034,7 +1082,7 @@ void VM_find(prvm_prog_t *prog)
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
-               if (ed->priv.required->free)
+               if (ed->free)
                        continue;
                t = PRVM_E_STRING(ed,f);
                if (!t)
@@ -1062,7 +1110,7 @@ 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);
@@ -1075,7 +1123,7 @@ void VM_findfloat(prvm_prog_t *prog)
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
-               if (ed->priv.required->free)
+               if (ed->free)
                        continue;
                if (PRVM_E_FLOAT(ed,f) == s)
                {
@@ -1126,7 +1174,7 @@ void VM_findchain(prvm_prog_t *prog)
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
-               if (ent->priv.required->free)
+               if (ent->free)
                        continue;
                t = PRVM_E_STRING(ent,f);
                if (!t)
@@ -1155,7 +1203,7 @@ void VM_findchainfloat(prvm_prog_t *prog)
 {
        int             i;
        int             f;
-       float   s;
+       prvm_vec_t      s;
        prvm_edict_t    *ent, *chain;
        int chainfield;
 
@@ -1177,7 +1225,7 @@ void VM_findchainfloat(prvm_prog_t *prog)
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
-               if (ent->priv.required->free)
+               if (ent->free)
                        continue;
                if (PRVM_E_FLOAT(ent,f) != s)
                        continue;
@@ -1215,7 +1263,7 @@ void VM_findflags(prvm_prog_t *prog)
        {
                prog->xfunction->builtinsprofile++;
                ed = PRVM_EDICT_NUM(e);
-               if (ed->priv.required->free)
+               if (ed->free)
                        continue;
                if (!PRVM_E_FLOAT(ed,f))
                        continue;
@@ -1263,7 +1311,7 @@ void VM_findchainflags(prvm_prog_t *prog)
        for (i = 1;i < prog->num_edicts;i++, ent = PRVM_NEXT_EDICT(ent))
        {
                prog->xfunction->builtinsprofile++;
-               if (ent->priv.required->free)
+               if (ent->free)
                        continue;
                if (!PRVM_E_FLOAT(ent,f))
                        continue;
@@ -1328,9 +1376,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");
 }
 
 /*
@@ -1477,7 +1525,7 @@ void VM_nextent(prvm_prog_t *prog)
                        return;
                }
                ent = PRVM_EDICT_NUM(i);
-               if (!ent->priv.required->free)
+               if (!ent->free)
                {
                        VM_RETURN_EDICT(ent);
                        return;
@@ -1511,7 +1559,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)));
 }
 
 /*
@@ -1651,21 +1699,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
 }
@@ -2000,7 +2048,7 @@ void VM_writetofile(prvm_prog_t *prog)
        }
 
        ent = PRVM_G_EDICT(OFS_PARM1);
-       if(ent->priv.required->free)
+       if(ent->free)
        {
                VM_Warning(prog, "VM_writetofile: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
                return;
@@ -2034,7 +2082,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)
@@ -2058,7 +2106,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)
@@ -2083,7 +2131,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;
@@ -2101,7 +2149,7 @@ void VM_getentityfieldstring(prvm_prog_t *prog)
        
        // get the entity
        ent = PRVM_G_EDICT(OFS_PARM1);
-       if(ent->priv.required->free)
+       if(ent->free)
        {
                PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, "");
                VM_Warning(prog, "VM_entityfielddata: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
@@ -2133,7 +2181,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);
 
@@ -2148,7 +2196,7 @@ void VM_putentityfieldstring(prvm_prog_t *prog)
 
        // get the entity
        ent = PRVM_G_EDICT(OFS_PARM1);
-       if(ent->priv.required->free)
+       if(ent->free)
        {
                VM_Warning(prog, "VM_entityfielddata: %s: entity %i is free !\n", prog->name, PRVM_NUM_FOR_EDICT(ent));
                PRVM_G_FLOAT(OFS_RETURN) = 0.0f;
@@ -2192,7 +2240,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);
 }
 
@@ -2440,7 +2488,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);
@@ -2546,36 +2594,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 LadyHavoc
-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
@@ -2626,7 +2644,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;
@@ -2794,7 +2812,7 @@ 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;
 }
@@ -2884,7 +2902,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
        {
@@ -2892,23 +2910,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;
                        case 4: // GETTIME_CDTRACK
                                PRVM_G_FLOAT(OFS_RETURN) = CDAudio_GetPosition();
                                break;
                        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;
                }
        }
@@ -2970,7 +2988,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));
 }
@@ -2991,7 +3009,7 @@ void VM_parseentitydata(prvm_prog_t *prog)
 
        // get edict and test it
        ent = PRVM_G_EDICT(OFS_PARM0);
-       if (ent->priv.required->free)
+       if (ent->free)
                prog->error_cmd("VM_parseentitydata: %s: Can only set already spawned entities (entity %i is free)!", prog->name, PRVM_NUM_FOR_EDICT(ent));
 
        data = PRVM_G_STRING(OFS_PARM1);
@@ -3026,963 +3044,219 @@ void VM_loadfromfile(prvm_prog_t *prog)
        }
 
        // not conform with VM_fopen
-       data = (char *)FS_LoadFile(filename, tempmempool, false, NULL);
-       if (data == NULL)
-               PRVM_G_FLOAT(OFS_RETURN) = -1;
-
-       PRVM_ED_LoadFromFile(prog, data);
-
-       if(data)
-               Mem_Free(data);
-}
-
-
-/*
-=========
-VM_modulo
-
-float  mod(float val, float m)
-=========
-*/
-void VM_modulo(prvm_prog_t *prog)
-{
-       prvm_int_t val, m;
-       VM_SAFEPARMCOUNT(2,VM_module);
-
-       val = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM0);
-       m       = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM1);
-
-       PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t) (val % m);
-}
-
-static void VM_Search_Init(prvm_prog_t *prog)
-{
-       int i;
-       for (i = 0;i < PRVM_MAX_OPENSEARCHES;i++)
-               prog->opensearches[i] = NULL;
-}
-
-static void VM_Search_Reset(prvm_prog_t *prog)
-{
-       int i;
-       // reset the fssearch list
-       for(i = 0; i < PRVM_MAX_OPENSEARCHES; i++)
-       {
-               if(prog->opensearches[i])
-                       FS_FreeSearch(prog->opensearches[i]);
-               prog->opensearches[i] = NULL;
-       }
-}
-
-/*
-=========
-VM_search_begin
-
-float search_begin(string pattern, float caseinsensitive, float quiet)
-=========
-*/
-void VM_search_begin(prvm_prog_t *prog)
-{
-       int handle;
-       const char *pattern;
-       int caseinsens, quiet;
-
-       VM_SAFEPARMCOUNT(3, VM_search_begin);
-
-       pattern = PRVM_G_STRING(OFS_PARM0);
-
-       VM_CheckEmptyString(prog, pattern);
-
-       caseinsens = (int)PRVM_G_FLOAT(OFS_PARM1);
-       quiet = (int)PRVM_G_FLOAT(OFS_PARM2);
-
-       for(handle = 0; handle < PRVM_MAX_OPENSEARCHES; handle++)
-               if(!prog->opensearches[handle])
-                       break;
-
-       if(handle >= PRVM_MAX_OPENSEARCHES)
-       {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_search_begin: %s ran out of search handles (%i)\n", prog->name, PRVM_MAX_OPENSEARCHES);
-               return;
-       }
-
-       if(!(prog->opensearches[handle] = FS_Search(pattern,caseinsens, quiet)))
-               PRVM_G_FLOAT(OFS_RETURN) = -1;
-       else
-       {
-               prog->opensearches_origin[handle] = PRVM_AllocationOrigin(prog);
-               PRVM_G_FLOAT(OFS_RETURN) = handle;
-       }
-}
-
-/*
-=========
-VM_search_end
-
-void   search_end(float handle)
-=========
-*/
-void VM_search_end(prvm_prog_t *prog)
-{
-       int handle;
-       VM_SAFEPARMCOUNT(1, VM_search_end);
-
-       handle = (int)PRVM_G_FLOAT(OFS_PARM0);
-
-       if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
-       {
-               VM_Warning(prog, "VM_search_end: invalid handle %i used in %s\n", handle, prog->name);
-               return;
-       }
-       if(prog->opensearches[handle] == NULL)
-       {
-               VM_Warning(prog, "VM_search_end: no such handle %i in %s\n", handle, prog->name);
-               return;
-       }
-
-       FS_FreeSearch(prog->opensearches[handle]);
-       prog->opensearches[handle] = NULL;
-       if(prog->opensearches_origin[handle])
-               PRVM_Free((char *)prog->opensearches_origin[handle]);
-}
-
-/*
-=========
-VM_search_getsize
-
-float  search_getsize(float handle)
-=========
-*/
-void VM_search_getsize(prvm_prog_t *prog)
-{
-       int handle;
-       VM_SAFEPARMCOUNT(1, VM_M_search_getsize);
-
-       handle = (int)PRVM_G_FLOAT(OFS_PARM0);
-
-       if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
-       {
-               VM_Warning(prog, "VM_search_getsize: invalid handle %i used in %s\n", handle, prog->name);
-               return;
-       }
-       if(prog->opensearches[handle] == NULL)
-       {
-               VM_Warning(prog, "VM_search_getsize: no such handle %i in %s\n", handle, prog->name);
-               return;
-       }
-
-       PRVM_G_FLOAT(OFS_RETURN) = prog->opensearches[handle]->numfilenames;
-}
-
-/*
-=========
-VM_search_getfilename
-
-string search_getfilename(float handle, float num)
-=========
-*/
-void VM_search_getfilename(prvm_prog_t *prog)
-{
-       int handle, filenum;
-       VM_SAFEPARMCOUNT(2, VM_search_getfilename);
-
-       handle = (int)PRVM_G_FLOAT(OFS_PARM0);
-       filenum = (int)PRVM_G_FLOAT(OFS_PARM1);
-
-       if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
-       {
-               VM_Warning(prog, "VM_search_getfilename: invalid handle %i used in %s\n", handle, prog->name);
-               return;
-       }
-       if(prog->opensearches[handle] == NULL)
-       {
-               VM_Warning(prog, "VM_search_getfilename: no such handle %i in %s\n", handle, prog->name);
-               return;
-       }
-       if(filenum < 0 || filenum >= prog->opensearches[handle]->numfilenames)
-       {
-               VM_Warning(prog, "VM_search_getfilename: invalid filenum %i in %s\n", filenum, prog->name);
-               return;
-       }
-
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, prog->opensearches[handle]->filenames[filenum]);
-}
-
-/*
-=========
-VM_chr
-
-string chr(float ascii)
-=========
-*/
-void VM_chr(prvm_prog_t *prog)
-{
-       /*
-       char tmp[2];
-       VM_SAFEPARMCOUNT(1, VM_chr);
-
-       tmp[0] = (unsigned char) PRVM_G_FLOAT(OFS_PARM0);
-       tmp[1] = 0;
-
-       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, tmp);
-       */
-       
-       char tmp[8];
-       int len;
-       VM_SAFEPARMCOUNT(1, VM_chr);
-
-       len = u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0), tmp, sizeof(tmp));
-       tmp[len] = 0;
-       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 = CACHEPICFLAG_FAILONMISSING;
-
-       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;
-       }
-
-       if( !Draw_IsPicLoaded(Draw_CachePic_Flags(s, flags)) )
-               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);
-
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
-
-       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);
-
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
-
-       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);
-
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
-
-       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);
-
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
-
-       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;
-       }
+       data = (char *)FS_LoadFile(filename, tempmempool, false, NULL);
+       if (data == NULL)
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
 
-       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")));
+       PRVM_ED_LoadFromFile(prog, data);
 
-       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;
+       if(data)
+               Mem_Free(data);
 }
+
+
 /*
 =========
-VM_drawrotpic
+VM_modulo
 
-float  drawrotpic(vector position, string pic, vector size, vector org, float angle, vector rgb, float alpha, float flag)
+float  mod(float val, float m)
 =========
 */
-void VM_drawrotpic(prvm_prog_t *prog)
+void VM_modulo(prvm_prog_t *prog)
 {
-       const char *picname;
-       prvm_vec_t *size, *pos, *org, *rgb;
-       int flag;
-
-       VM_SAFEPARMCOUNT(8,VM_drawrotpic);
-
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
+       prvm_int_t val, m;
+       VM_SAFEPARMCOUNT(2, VM_modulo);
 
-       picname = PRVM_G_STRING(OFS_PARM1);
-       VM_CheckEmptyString(prog, picname);
+       val = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM0);
+       m       = (prvm_int_t) PRVM_G_FLOAT(OFS_PARM1);
 
-       // 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;
-       }
+       PRVM_G_FLOAT(OFS_RETURN) = (prvm_vec_t) (val % m);
+}
 
-       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);
+static void VM_Search_Init(prvm_prog_t *prog)
+{
+       int i;
+       for (i = 0;i < PRVM_MAX_OPENSEARCHES;i++)
+               prog->opensearches[i] = NULL;
+}
 
-       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
+static void VM_Search_Reset(prvm_prog_t *prog)
+{
+       int i;
+       // reset the fssearch list
+       for(i = 0; i < PRVM_MAX_OPENSEARCHES; i++)
        {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawrotpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
-               return;
+               if(prog->opensearches[i])
+                       FS_FreeSearch(prog->opensearches[i]);
+               prog->opensearches[i] = NULL;
        }
-
-       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)
+VM_search_begin
 
+float search_begin(string pattern, float caseinsensitive, float quiet[, string packfile])
 =========
 */
-void VM_drawsubpic(prvm_prog_t *prog)
+void VM_search_begin(prvm_prog_t *prog)
 {
-       const char *picname;
-       prvm_vec_t *size, *pos, *rgb, *srcPos, *srcSize, alpha;
-       int flag;
+       int handle;
+       const char *packfile = NULL, *pattern;
+       int caseinsens, quiet;
 
-       VM_SAFEPARMCOUNT(8,VM_drawsubpic);
+       VM_SAFEPARMCOUNTRANGE(3, 4, VM_search_begin);
 
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
+       pattern = PRVM_G_STRING(OFS_PARM0);
 
-       picname = PRVM_G_STRING(OFS_PARM2);
-       VM_CheckEmptyString(prog, picname);
+       VM_CheckEmptyString(prog, pattern);
 
-       // 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;
-       }
+       caseinsens = (int)PRVM_G_FLOAT(OFS_PARM1);
+       quiet = (int)PRVM_G_FLOAT(OFS_PARM2);
 
-       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);
+       // 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;
 
-       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
+       if(handle >= PRVM_MAX_OPENSEARCHES)
        {
                PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawsubpic: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
+               VM_Warning(prog, "VM_search_begin: %s ran out of search handles (%i)\n", prog->name, PRVM_MAX_OPENSEARCHES);
                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;
+       if(!(prog->opensearches[handle] = FS_Search(pattern,caseinsens, quiet, packfile)))
+               PRVM_G_FLOAT(OFS_RETURN) = -1;
+       else
+       {
+               prog->opensearches_origin[handle] = PRVM_AllocationOrigin(prog);
+               PRVM_G_FLOAT(OFS_RETURN) = handle;
+       }
 }
 
 /*
 =========
-VM_drawfill
+VM_search_end
 
-float drawfill(vector position, vector size, vector rgb, float alpha, float flag)
+void   search_end(float handle)
 =========
 */
-void VM_drawfill(prvm_prog_t *prog)
+void VM_search_end(prvm_prog_t *prog)
 {
-       prvm_vec_t *size, *pos, *rgb;
-       int flag;
-
-       VM_SAFEPARMCOUNT(5,VM_drawfill);
-
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
+       int handle;
+       VM_SAFEPARMCOUNT(1, VM_search_end);
 
-       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);
+       handle = (int)PRVM_G_FLOAT(OFS_PARM0);
 
-       if(flag < DRAWFLAG_NORMAL || flag >=DRAWFLAG_NUMFLAGS)
+       if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
        {
-               PRVM_G_FLOAT(OFS_RETURN) = -2;
-               VM_Warning(prog, "VM_drawfill: %s: wrong DRAWFLAG %i !\n",prog->name,flag);
+               VM_Warning(prog, "VM_search_end: invalid handle %i used in %s\n", handle, prog->name);
+               return;
+       }
+       if(prog->opensearches[handle] == NULL)
+       {
+               VM_Warning(prog, "VM_search_end: no such handle %i in %s\n", handle, prog->name);
                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;
+       FS_FreeSearch(prog->opensearches[handle]);
+       prog->opensearches[handle] = NULL;
+       if(prog->opensearches_origin[handle])
+               PRVM_Free((char *)prog->opensearches_origin[handle]);
 }
 
 /*
 =========
-VM_drawsetcliparea
+VM_search_getsize
 
-drawsetcliparea(float x, float y, float width, float height)
+float  search_getsize(float handle)
 =========
 */
-void VM_drawsetcliparea(prvm_prog_t *prog)
+void VM_search_getsize(prvm_prog_t *prog)
 {
-       float x,y,w,h;
-       VM_SAFEPARMCOUNT(4,VM_drawsetcliparea);
+       int handle;
+       VM_SAFEPARMCOUNT(1, VM_search_getsize);
 
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
+       handle = (int)PRVM_G_FLOAT(OFS_PARM0);
 
-       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));
+       if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
+       {
+               VM_Warning(prog, "VM_search_getsize: invalid handle %i used in %s\n", handle, prog->name);
+               return;
+       }
+       if(prog->opensearches[handle] == NULL)
+       {
+               VM_Warning(prog, "VM_search_getsize: no such handle %i in %s\n", handle, prog->name);
+               return;
+       }
 
-       DrawQ_SetClipArea(x, y, w, h);
+       PRVM_G_FLOAT(OFS_RETURN) = prog->opensearches[handle]->numfilenames;
 }
 
 /*
 =========
-VM_drawresetcliparea
+VM_search_getfilename
 
-drawresetcliparea()
+string search_getfilename(float handle, float num)
 =========
 */
-void VM_drawresetcliparea(prvm_prog_t *prog)
+void VM_search_getfilename(prvm_prog_t *prog)
 {
-       VM_SAFEPARMCOUNT(0,VM_drawresetcliparea);
+       int handle, filenum;
+       VM_SAFEPARMCOUNT(2, VM_search_getfilename);
+
+       handle = (int)PRVM_G_FLOAT(OFS_PARM0);
+       filenum = (int)PRVM_G_FLOAT(OFS_PARM1);
 
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
+       if(handle < 0 || handle >= PRVM_MAX_OPENSEARCHES)
+       {
+               VM_Warning(prog, "VM_search_getfilename: invalid handle %i used in %s\n", handle, prog->name);
+               return;
+       }
+       if(prog->opensearches[handle] == NULL)
+       {
+               VM_Warning(prog, "VM_search_getfilename: no such handle %i in %s\n", handle, prog->name);
+               return;
+       }
+       if(filenum < 0 || filenum >= prog->opensearches[handle]->numfilenames)
+       {
+               VM_Warning(prog, "VM_search_getfilename: invalid filenum %i in %s\n", filenum, prog->name);
+               return;
+       }
 
-       DrawQ_ResetClipArea();
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, prog->opensearches[handle]->filenames[filenum]);
 }
 
 /*
 =========
-VM_getimagesize
+VM_chr
 
-vector getimagesize(string pic)
+string chr(float ascii)
 =========
 */
-void VM_getimagesize(prvm_prog_t *prog)
+void VM_chr(prvm_prog_t *prog)
 {
-       const char *p;
-       cachepic_t *pic;
+       /*
+       char tmp[2];
+       VM_SAFEPARMCOUNT(1, VM_chr);
 
-       VM_SAFEPARMCOUNT(1,VM_getimagesize);
+       tmp[0] = (unsigned char) PRVM_G_FLOAT(OFS_PARM0);
+       tmp[1] = 0;
 
-       p = PRVM_G_STRING(OFS_PARM0);
-       VM_CheckEmptyString(prog, p);
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, tmp);
+       */
+       
+       char tmp[8];
+       int len;
+       VM_SAFEPARMCOUNT(1, VM_chr);
 
-       pic = Draw_CachePic_Flags (p, CACHEPICFLAG_NOTPERSISTENT);
-       if (!Draw_IsPicLoaded(pic))
-       {
-               PRVM_G_VECTOR(OFS_RETURN)[0] = 0;
-               PRVM_G_VECTOR(OFS_RETURN)[1] = 0;
-       }
-       else
-       {
-               PRVM_G_VECTOR(OFS_RETURN)[0] = Draw_GetPicWidth(pic);
-               PRVM_G_VECTOR(OFS_RETURN)[1] = Draw_GetPicHeight(pic);
-       }
-       PRVM_G_VECTOR(OFS_RETURN)[2] = 0;
+       len = u8_fromchar((Uchar)PRVM_G_FLOAT(OFS_PARM0), tmp, sizeof(tmp));
+       tmp[len] = 0;
+       PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString(prog, tmp);
 }
 
 /*
@@ -4048,7 +3322,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));
 }
@@ -4063,7 +3337,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
@@ -4082,7 +3356,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
@@ -4103,7 +3377,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;
@@ -4119,130 +3393,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
@@ -4366,33 +3523,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);
-
-       // polygonbegin without draw2d arg has to guess
-       prog->polygonbegin_guess2d = true;
-
-       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)
 {
@@ -4768,9 +3898,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"))
        {
@@ -4889,7 +4019,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;
 ========================
 */
@@ -5028,7 +4158,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;
 ========================
 */
@@ -5334,7 +4464,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;
 
@@ -5367,7 +4497,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;
@@ -5382,7 +4512,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;
@@ -5428,9 +4558,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)
@@ -5462,7 +4592,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);
@@ -5500,7 +4630,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;
@@ -5516,7 +4646,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;
@@ -5559,7 +4689,7 @@ void VM_changeyaw (prvm_prog_t *prog)
                VM_Warning(prog, "changeyaw: can not modify world entity\n");
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "changeyaw: can not modify free entity\n");
                return;
@@ -5615,7 +4745,7 @@ void VM_changepitch (prvm_prog_t *prog)
                VM_Warning(prog, "changepitch: can not modify world entity\n");
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "changepitch: can not modify free entity\n");
                return;
@@ -5662,7 +4792,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);
        
 }
@@ -6017,7 +5147,7 @@ void VM_digest_hex(prvm_prog_t *prog)
 void VM_wasfreed (prvm_prog_t *prog)
 {
        VM_SAFEPARMCOUNT(1, VM_wasfreed);
-       PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_EDICT(OFS_PARM0)->priv.required->free;
+       PRVM_G_FLOAT(OFS_RETURN) = PRVM_G_EDICT(OFS_PARM0)->free;
 }
 
 void VM_SetTraceGlobals(prvm_prog_t *prog, const trace_t *trace)
@@ -6223,7 +5353,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;
@@ -6475,7 +5605,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
@@ -6813,6 +5943,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)
                                                        {
@@ -6854,7 +5985,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);
@@ -6866,7 +5997,7 @@ static dp_model_t *getmodel(prvm_prog_t *prog, prvm_edict_t *ed)
 
 struct animatemodel_cache
 {
-       dp_model_t *model;
+       model_t *model;
        frameblend_t frameblend[MAX_FRAMEBLENDS];
        skeleton_t *skeleton_p;
        skeleton_t skeleton;
@@ -6892,11 +6023,11 @@ static void animatemodel_reset(prvm_prog_t *prog)
        Mem_Free(prog->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)
        {
@@ -6990,7 +6121,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;
@@ -7027,18 +6158,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
@@ -7055,7 +6186,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;
@@ -7083,13 +6214,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))))
@@ -7153,7 +6284,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;
@@ -7172,7 +6303,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;
@@ -7187,7 +6318,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);
@@ -7195,7 +6326,7 @@ void VM_getsurfacenearpoint(prvm_prog_t *prog)
        ed = PRVM_G_EDICT(OFS_PARM0);
        VectorCopy(PRVM_G_VECTOR(OFS_PARM1), point);
 
-       if (!ed || ed->priv.server->free)
+       if (!ed || ed->free)
                return;
        model = getmodel(prog, ed);
        if (!model || !model->num_surfaces)
@@ -7206,9 +6337,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];
@@ -7223,7 +6354,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;
                        }
                }
@@ -7234,10 +6365,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))))
@@ -7252,9 +6383,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))))
        {
@@ -7269,10 +6400,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))))
@@ -7288,6 +6419,7 @@ void VM_getsurfacetriangle(prvm_prog_t *prog)
 // physics builtins
 //
 
+#ifdef USEODE
 #define VM_physics_ApplyCmd(ed,f) if (!ed->priv.server->ode_body) VM_physics_newstackfunction(prog, ed, f); else World_Physics_ApplyCmd(ed, f)
 
 static edict_odefunc_t *VM_physics_newstackfunction(prvm_prog_t *prog, prvm_edict_t *ed, edict_odefunc_t *f)
@@ -7306,14 +6438,17 @@ static edict_odefunc_t *VM_physics_newstackfunction(prvm_prog_t *prog, prvm_edic
        }
        return newfunc;
 }
+#endif
 
 // void(entity e, float physics_enabled) physics_enable = #;
 void VM_physics_enable(prvm_prog_t *prog)
 {
+#ifdef USEODE
        prvm_edict_t *ed;
        edict_odefunc_t f;
-       
+#endif
        VM_SAFEPARMCOUNT(2, VM_physics_enable);
+#ifdef USEODE
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!ed)
        {
@@ -7329,15 +6464,18 @@ void VM_physics_enable(prvm_prog_t *prog)
        }
        f.type = PRVM_G_FLOAT(OFS_PARM1) == 0 ? ODEFUNC_DISABLE : ODEFUNC_ENABLE;
        VM_physics_ApplyCmd(ed, &f);
+#endif
 }
 
 // void(entity e, vector force, vector relative_ofs) physics_addforce = #;
 void VM_physics_addforce(prvm_prog_t *prog)
 {
+#ifdef USEODE
        prvm_edict_t *ed;
        edict_odefunc_t f;
-       
+#endif
        VM_SAFEPARMCOUNT(3, VM_physics_addforce);
+#ifdef USEODE
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!ed)
        {
@@ -7355,15 +6493,18 @@ void VM_physics_addforce(prvm_prog_t *prog)
        VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f.v1);
        VectorCopy(PRVM_G_VECTOR(OFS_PARM2), f.v2);
        VM_physics_ApplyCmd(ed, &f);
+#endif
 }
 
 // void(entity e, vector torque) physics_addtorque = #;
 void VM_physics_addtorque(prvm_prog_t *prog)
 {
+#ifdef USEODE
        prvm_edict_t *ed;
        edict_odefunc_t f;
-       
+#endif
        VM_SAFEPARMCOUNT(2, VM_physics_addtorque);
+#ifdef USEODE
        ed = PRVM_G_EDICT(OFS_PARM0);
        if (!ed)
        {
@@ -7380,6 +6521,7 @@ void VM_physics_addtorque(prvm_prog_t *prog)
        f.type = ODEFUNC_TORQUE;
        VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f.v1);
        VM_physics_ApplyCmd(ed, &f);
+#endif
 }
 
 extern cvar_t prvm_coverage;