]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - svvm_cmds.c
added PRVM_64 define which upgrades the QC VM to double precision
[xonotic/darkplaces.git] / svvm_cmds.c
index 1faeeafd811e0a5e3c249b764173d36e1bc3c765..a68a525896ad26a9f49394952bb3088398e1bd53 100644 (file)
@@ -32,9 +32,12 @@ const char *vm_sv_extensions =
 "DP_CSQC_QUERYRENDERENTITY "
 "DP_CSQC_ROTATEMOVES "
 "DP_CSQC_SETPAUSE "
+"DP_CSQC_V_CALCREFDEF_WIP1 "
+"DP_CSQC_V_CALCREFDEF_WIP2 "
 "DP_EF_ADDITIVE "
 "DP_EF_BLUE "
 "DP_EF_DOUBLESIDED "
+"DP_EF_DYNAMICMODELLIGHT "
 "DP_EF_FLAME "
 "DP_EF_FULLBRIGHT "
 "DP_EF_NODEPTHTEST "
@@ -122,6 +125,7 @@ const char *vm_sv_extensions =
 "DP_QC_STRFTIME "
 "DP_QC_STRINGBUFFERS "
 "DP_QC_STRINGBUFFERS_CVARLIST "
+"DP_QC_STRINGBUFFERS_EXT_WIP "
 "DP_QC_STRINGCOLORFUNCTIONS "
 "DP_QC_STRING_CASE_FUNCTIONS "
 "DP_QC_STRREPLACE "
@@ -235,7 +239,6 @@ setorigin (entity, origin)
 static void VM_SV_setorigin(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
-       float   *org;
 
        VM_SAFEPARMCOUNT(2, VM_setorigin);
 
@@ -250,8 +253,7 @@ static void VM_SV_setorigin(prvm_prog_t *prog)
                VM_Warning(prog, "setorigin: can not modify free entity\n");
                return;
        }
-       org = PRVM_G_VECTOR(OFS_PARM1);
-       VectorCopy (org, PRVM_serveredictvector(e, origin));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), PRVM_serveredictvector(e, origin));
        if(e->priv.required->mark == PRVM_EDICT_MARK_WAIT_FOR_SETORIGIN)
                e->priv.required->mark = PRVM_EDICT_MARK_SETORIGIN_CAUGHT;
        SV_LinkEdict(e);
@@ -287,7 +289,7 @@ setsize (entity, minvector, maxvector)
 static void VM_SV_setsize(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
-       float   *min, *max;
+       vec3_t mins, maxs;
 
        VM_SAFEPARMCOUNT(3, VM_setsize);
 
@@ -302,9 +304,9 @@ static void VM_SV_setsize(prvm_prog_t *prog)
                VM_Warning(prog, "setsize: can not modify free entity\n");
                return;
        }
-       min = PRVM_G_VECTOR(OFS_PARM1);
-       max = PRVM_G_VECTOR(OFS_PARM2);
-       SetMinMaxSize(prog, e, min, max, false);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), mins);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), maxs);
+       SetMinMaxSize(prog, e, mins, maxs, false);
 }
 
 
@@ -437,14 +439,14 @@ particle(origin, color, count)
 */
 static void VM_SV_particle(prvm_prog_t *prog)
 {
-       float           *org, *dir;
+       vec3_t          org, dir;
        float           color;
        float           count;
 
        VM_SAFEPARMCOUNT(4, VM_SV_particle);
 
-       org = PRVM_G_VECTOR(OFS_PARM0);
-       dir = PRVM_G_VECTOR(OFS_PARM1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), dir);
        color = PRVM_G_FLOAT(OFS_PARM2);
        count = PRVM_G_FLOAT(OFS_PARM3);
        SV_StartParticle (org, dir, (int)color, (int)count);
@@ -460,13 +462,13 @@ VM_SV_ambientsound
 static void VM_SV_ambientsound(prvm_prog_t *prog)
 {
        const char      *samp;
-       float           *pos;
+       vec3_t          pos;
        float           vol, attenuation;
        int                     soundnum, large;
 
        VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
 
-       pos = PRVM_G_VECTOR (OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        samp = PRVM_G_STRING(OFS_PARM1);
        vol = PRVM_G_FLOAT(OFS_PARM2);
        attenuation = PRVM_G_FLOAT(OFS_PARM3);
@@ -631,7 +633,7 @@ traceline (vector1, vector2, movetype, ignore)
 */
 static void VM_SV_traceline(prvm_prog_t *prog)
 {
-       float   *v1, *v2;
+       vec3_t  v1, v2;
        trace_t trace;
        int             move;
        prvm_edict_t    *ent;
@@ -640,12 +642,12 @@ static void VM_SV_traceline(prvm_prog_t *prog)
 
        prog->xfunction->builtinsprofile += 30;
 
-       v1 = PRVM_G_VECTOR(OFS_PARM0);
-       v2 = PRVM_G_VECTOR(OFS_PARM1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), v1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), v2);
        move = (int)PRVM_G_FLOAT(OFS_PARM2);
        ent = PRVM_G_EDICT(OFS_PARM3);
 
-       if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
+       if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
                prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
        trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
@@ -668,7 +670,7 @@ tracebox (vector1, vector mins, vector maxs, vector2, tryents)
 // LordHavoc: added this for my own use, VERY useful, similar to traceline
 static void VM_SV_tracebox(prvm_prog_t *prog)
 {
-       float   *v1, *v2, *m1, *m2;
+       vec3_t v1, v2, m1, m2;
        trace_t trace;
        int             move;
        prvm_edict_t    *ent;
@@ -677,14 +679,14 @@ static void VM_SV_tracebox(prvm_prog_t *prog)
 
        prog->xfunction->builtinsprofile += 30;
 
-       v1 = PRVM_G_VECTOR(OFS_PARM0);
-       m1 = PRVM_G_VECTOR(OFS_PARM1);
-       m2 = PRVM_G_VECTOR(OFS_PARM2);
-       v2 = PRVM_G_VECTOR(OFS_PARM3);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), v1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), m1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), m2);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM3), v2);
        move = (int)PRVM_G_FLOAT(OFS_PARM4);
        ent = PRVM_G_EDICT(OFS_PARM5);
 
-       if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
+       if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
                prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
        trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
@@ -696,7 +698,7 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic
 {
        int i;
        float gravity;
-       vec3_t move, end;
+       vec3_t move, end, tossentorigin, tossentmins, tossentmaxs;
        vec3_t original_origin;
        vec3_t original_velocity;
        vec3_t original_angles;
@@ -720,7 +722,10 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic
                VectorMA (PRVM_serveredictvector(tossent, angles), 0.05, PRVM_serveredictvector(tossent, avelocity), PRVM_serveredictvector(tossent, angles));
                VectorScale (PRVM_serveredictvector(tossent, velocity), 0.05, move);
                VectorAdd (PRVM_serveredictvector(tossent, origin), move, end);
-               trace = SV_TraceBox(PRVM_serveredictvector(tossent, origin), PRVM_serveredictvector(tossent, mins), PRVM_serveredictvector(tossent, maxs), end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
+               VectorCopy(PRVM_serveredictvector(tossent, origin), tossentorigin);
+               VectorCopy(PRVM_serveredictvector(tossent, mins), tossentmins);
+               VectorCopy(PRVM_serveredictvector(tossent, maxs), tossentmaxs);
+               trace = SV_TraceBox(tossentorigin, tossentmins, tossentmaxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
                VectorCopy (trace.endpos, PRVM_serveredictvector(tossent, origin));
                PRVM_serveredictvector(tossent, velocity)[2] -= gravity;
 
@@ -870,7 +875,7 @@ float checkpvs(vector viewpos, entity viewee) = #240;
 */
 static void VM_SV_checkpvs(prvm_prog_t *prog)
 {
-       vec3_t viewpos;
+       vec3_t viewpos, absmin, absmax;
        prvm_edict_t *viewee;
 #if 1
        unsigned char *pvs;
@@ -891,7 +896,7 @@ static void VM_SV_checkpvs(prvm_prog_t *prog)
        }
 
 #if 1
-       if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+       if(!sv.worldmodel || !sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
        {
                // no PVS support on this worldmodel... darn
                PRVM_G_FLOAT(OFS_RETURN) = 3;
@@ -904,10 +909,12 @@ static void VM_SV_checkpvs(prvm_prog_t *prog)
                PRVM_G_FLOAT(OFS_RETURN) = 2;
                return;
        }
-       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, PRVM_serveredictvector(viewee, absmin), PRVM_serveredictvector(viewee, absmax));
+       VectorCopy(PRVM_serveredictvector(viewee, absmin), absmin);
+       VectorCopy(PRVM_serveredictvector(viewee, absmax), absmax);
+       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, absmin, absmax);
 #else
        // using fat PVS like FTEQW does (slow)
-       if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+       if(!sv.worldmodel || !sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
        {
                // no PVS support on this worldmodel... darn
                PRVM_G_FLOAT(OFS_RETURN) = 3;
@@ -920,7 +927,9 @@ static void VM_SV_checkpvs(prvm_prog_t *prog)
                PRVM_G_FLOAT(OFS_RETURN) = 2;
                return;
        }
-       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, PRVM_serveredictvector(viewee, absmin), PRVM_serveredictvector(viewee, absmax));
+       VectorCopy(PRVM_serveredictvector(viewee, absmin), absmin);
+       VectorCopy(PRVM_serveredictvector(viewee, absmax), absmax);
+       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, absmin, absmax);
 #endif
 }
 
@@ -1115,7 +1124,7 @@ void() droptofloor
 static void VM_SV_droptofloor(prvm_prog_t *prog)
 {
        prvm_edict_t            *ent;
-       vec3_t          end;
+       vec3_t          end, entorigin, entmins, entmaxs;
        trace_t         trace;
 
        VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
@@ -1142,7 +1151,10 @@ static void VM_SV_droptofloor(prvm_prog_t *prog)
                if (sv_gameplayfix_unstickentities.integer)
                        SV_UnstickEntity(ent);
 
-       trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
+       VectorCopy(PRVM_serveredictvector(ent, origin), entorigin);
+       VectorCopy(PRVM_serveredictvector(ent, mins), entmins);
+       VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs);
+       trace = SV_TraceBox(entorigin, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
        if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
        {
                vec3_t offset, org;
@@ -1249,8 +1261,10 @@ VM_SV_pointcontents
 */
 static void VM_SV_pointcontents(prvm_prog_t *prog)
 {
+       vec3_t point;
        VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
-       PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), point);
+       PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(point));
 }
 
 /*
@@ -1597,9 +1611,9 @@ getlight(vector)
 static void VM_SV_getlight(prvm_prog_t *prog)
 {
        vec3_t ambientcolor, diffusecolor, diffusenormal;
-       vec_t *p;
+       vec3_t p;
        VM_SAFEPARMCOUNT(1, VM_SV_getlight);
-       p = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), p);
        VectorClear(ambientcolor);
        VectorClear(diffusecolor);
        VectorClear(diffusenormal);
@@ -1749,7 +1763,7 @@ static void VM_SV_copyentity(prvm_prog_t *prog)
                VM_Warning(prog, "copyentity: can not modify free entity\n");
                return;
        }
-       memcpy(out->fields.vp, in->fields.vp, prog->entityfields * 4);
+       memcpy(out->fields.fp, in->fields.fp, prog->entityfields * sizeof(prvm_vec_t));
        SV_LinkEdict(out);
 }
 
@@ -1806,6 +1820,7 @@ static void VM_SV_effect(prvm_prog_t *prog)
 {
        int i;
        const char *s;
+       vec3_t org;
        VM_SAFEPARMCOUNT(5, VM_SV_effect);
        s = PRVM_G_STRING(OFS_PARM1);
        if (!s[0])
@@ -1833,7 +1848,8 @@ static void VM_SV_effect(prvm_prog_t *prog)
                return;
        }
 
-       SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+       SV_StartEffect(org, i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
 }
 
 static void VM_SV_te_blood(prvm_prog_t *prog)
@@ -2427,7 +2443,7 @@ static int SV_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int
        if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
        {
                VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
-               VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
+               VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model, sv.time);
                VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
                return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
        }
@@ -2466,7 +2482,7 @@ static int SV_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *e
        model = SV_GetModelByIndex(modelindex);
 
        VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
-       VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
+       VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model, sv.time);
        VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
 
        tagmatrix = identitymatrix;
@@ -2577,7 +2593,7 @@ static void VM_SV_gettaginfo(prvm_prog_t *prog)
        int parentindex;
        const char *tagname;
        int returncode;
-       vec3_t fo, le, up, trans;
+       vec3_t forward, left, up, origin;
        const dp_model_t *model;
 
        VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
@@ -2586,21 +2602,24 @@ static void VM_SV_gettaginfo(prvm_prog_t *prog)
        tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
 
        returncode = SV_GetTagMatrix(prog, &tag_matrix, e, tagindex);
-       Matrix4x4_ToVectors(&tag_matrix, PRVM_serverglobalvector(v_forward), le, PRVM_serverglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));
-       VectorScale(le, -1, PRVM_serverglobalvector(v_right));
+       Matrix4x4_ToVectors(&tag_matrix, forward, left, up, origin);
+       VectorCopy(forward, PRVM_serverglobalvector(v_forward));
+       VectorNegate(left, PRVM_serverglobalvector(v_right));
+       VectorCopy(up, PRVM_serverglobalvector(v_up));
+       VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
        model = SV_GetModelFromEdict(e);
        VM_GenerateFrameGroupBlend(prog, e->priv.server->framegroupblend, e);
-       VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
+       VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model, sv.time);
        VM_UpdateEdictSkeleton(prog, e, model, e->priv.server->frameblend);
        SV_GetExtendedTagInfo(prog, e, tagindex, &parentindex, &tagname, &tag_localmatrix);
-       Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
+       Matrix4x4_ToVectors(&tag_localmatrix, forward, left, up, origin);
 
        PRVM_serverglobalfloat(gettaginfo_parent) = parentindex;
        PRVM_serverglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0;
-       VectorCopy(trans, PRVM_serverglobalvector(gettaginfo_offset));
-       VectorCopy(fo, PRVM_serverglobalvector(gettaginfo_forward));
-       VectorScale(le, -1, PRVM_serverglobalvector(gettaginfo_right));
+       VectorCopy(forward, PRVM_serverglobalvector(gettaginfo_forward));
+       VectorNegate(left, PRVM_serverglobalvector(gettaginfo_right));
        VectorCopy(up, PRVM_serverglobalvector(gettaginfo_up));
+       VectorCopy(origin, PRVM_serverglobalvector(gettaginfo_offset));
 
        switch(returncode)
        {
@@ -2784,6 +2803,7 @@ static void VM_SV_particleeffectnum(prvm_prog_t *prog)
 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
 static void VM_SV_trailparticles(prvm_prog_t *prog)
 {
+       vec3_t start, end;
        VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
 
        if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
@@ -2792,8 +2812,10 @@ static void VM_SV_trailparticles(prvm_prog_t *prog)
        MSG_WriteByte(&sv.datagram, svc_trailparticles);
        MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
        MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
-       MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
-       MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), start);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM3), end);
+       MSG_WriteVector(&sv.datagram, start, sv.protocol);
+       MSG_WriteVector(&sv.datagram, end, sv.protocol);
        SV_FlushBroadcastMessages();
 }
 
@@ -2864,7 +2886,7 @@ static void VM_SV_skel_create(prvm_prog_t *prog)
                        break;
        if (i == MAX_EDICTS)
                return;
-       prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
+       prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(prog->progs_mempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
        PRVM_G_FLOAT(OFS_RETURN) = i + 1;
        skeleton->model = model;
        skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
@@ -2899,7 +2921,7 @@ static void VM_SV_skel_build(prvm_prog_t *prog)
        lastbone = min(lastbone, model->num_bones - 1);
        lastbone = min(lastbone, skeleton->model->num_bones - 1);
        VM_GenerateFrameGroupBlend(prog, framegroupblend, ed);
-       VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
+       VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model, sv.time);
        blendfrac = 1.0f - retainfrac;
        for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
                frameblend[numblends].lerp *= blendfrac;
@@ -2909,7 +2931,7 @@ static void VM_SV_skel_build(prvm_prog_t *prog)
                Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
                for (blendindex = 0;blendindex < numblends;blendindex++)
                {
-                       Matrix4x4_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
+                       Matrix4x4_FromBonePose7s(&matrix, model->num_posescale, model->data_poses7s + 7 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
                        Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
                }
                skeleton->relativetransforms[bonenum] = blendedmatrix;
@@ -3698,10 +3720,10 @@ VM_SV_setpause,                                 // #531 void(float pause) setpause = #531;
 VM_log,                                                        // #532
 VM_getsoundtime,                               // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
 VM_soundlength,                                        // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
-NULL,                                                  // #535
-NULL,                                                  // #536
-NULL,                                                  // #537
-NULL,                                                  // #538
+VM_buf_loadfile,                // #535 float(string filename, float bufhandle) buf_loadfile (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_buf_writefile,               // #536 float(float filehandle, float bufhandle, float startpos, float numstrings) buf_writefile (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_bufstr_find,                 // #537 float(float bufhandle, string match, float matchrule, float startpos) bufstr_find (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_matchpattern,                // #538 float(string s, string pattern, float matchrule) matchpattern (DP_QC_STRINGBUFFERS_EXT_WIP)
 NULL,                                                  // #539
 VM_physics_enable,                             // #540 void(entity e, float physics_enabled) physics_enable = #540; (DP_PHYSICS_ODE)
 VM_physics_addforce,                   // #541 void(entity e, vector force, vector relative_ofs) physics_addforce = #541; (DP_PHYSICS_ODE)