]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - clvm_cmds.c
fix a few more redundancies with PRVM_64
[xonotic/darkplaces.git] / clvm_cmds.c
index ed960e8e8c539b875216951b4444dd0a5b8dc70e..bbb29e248a5a34ce2662de30c95c58ffd8fe8e1a 100644 (file)
@@ -29,15 +29,20 @@ r_refdef_view_t csqc_main_r_refdef_view;
 // #1 void(vector ang) makevectors
 static void VM_CL_makevectors (prvm_prog_t *prog)
 {
+       vec3_t angles, forward, right, up;
        VM_SAFEPARMCOUNT(1, VM_CL_makevectors);
-       AngleVectors (PRVM_G_VECTOR(OFS_PARM0), PRVM_clientglobalvector(v_forward), PRVM_clientglobalvector(v_right), PRVM_clientglobalvector(v_up));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), angles);
+       AngleVectors(angles, forward, right, up);
+       VectorCopy(forward, PRVM_clientglobalvector(v_forward));
+       VectorCopy(right, PRVM_clientglobalvector(v_right));
+       VectorCopy(up, PRVM_clientglobalvector(v_up));
 }
 
 // #2 void(entity e, vector o) setorigin
 static void VM_CL_setorigin (prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
-       float   *org;
+       prvm_vec_t      *org;
        VM_SAFEPARMCOUNT(2, VM_CL_setorigin);
 
        e = PRVM_G_EDICT(OFS_PARM0);
@@ -58,7 +63,7 @@ static void VM_CL_setorigin (prvm_prog_t *prog)
        CL_LinkEdict(e);
 }
 
-static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float *max)
+static void SetMinMaxSizePRVM (prvm_prog_t *prog, prvm_edict_t *e, prvm_vec_t *min, prvm_vec_t *max)
 {
        int             i;
 
@@ -74,6 +79,14 @@ static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float
        CL_LinkEdict (e);
 }
 
+static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, const vec_t *min, const vec_t *max)
+{
+       prvm_vec3_t mins, maxs;
+       VectorCopy(min, mins);
+       VectorCopy(max, maxs);
+       SetMinMaxSizePRVM(prog, e, mins, maxs);
+}
+
 // #3 void(entity e, string m) setmodel
 static void VM_CL_setmodel (prvm_prog_t *prog)
 {
@@ -116,7 +129,8 @@ static void VM_CL_setmodel (prvm_prog_t *prog)
 
        if( mod ) {
                // TODO: check if this breaks needed consistency and maybe add a cvar for it too?? [1/10/2008 Black]
-               //SetMinMaxSize (e, mod->normalmins, mod->normalmaxs);
+               // LordHavoc: erm you broke it by commenting this out - setmodel must do setsize or else the qc can't find out the model size, and ssqc does this by necessity, consistency.
+               SetMinMaxSize (prog, e, mod->normalmins, mod->normalmaxs);
        }
        else
        {
@@ -129,7 +143,7 @@ static void VM_CL_setmodel (prvm_prog_t *prog)
 static void VM_CL_setsize (prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
-       float                   *min, *max;
+       vec3_t          mins, maxs;
        VM_SAFEPARMCOUNT(3, VM_CL_setsize);
 
        e = PRVM_G_EDICT(OFS_PARM0);
@@ -143,10 +157,10 @@ static void VM_CL_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);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), mins);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), maxs);
 
-       SetMinMaxSize( prog, e, min, max );
+       SetMinMaxSize( prog, e, mins, maxs );
 
        CL_LinkEdict(e);
 }
@@ -257,7 +271,7 @@ static void CL_VM_SetTraceGlobals(prvm_prog_t *prog, const trace_t *trace, int s
 // #16 void(vector v1, vector v2, float movetype, entity ignore) traceline
 static void VM_CL_traceline (prvm_prog_t *prog)
 {
-       float   *v1, *v2;
+       vec3_t  v1, v2;
        trace_t trace;
        int             move, svent;
        prvm_edict_t    *ent;
@@ -268,12 +282,12 @@ static void VM_CL_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 = CL_TraceLine(v1, v2, move, ent, CL_GenericHitSuperContentsMask(ent), CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true, false);
@@ -296,7 +310,7 @@ tracebox (vector1, vector mins, vector maxs, vector2, tryents)
 // LordHavoc: added this for my own use, VERY useful, similar to traceline
 static void VM_CL_tracebox (prvm_prog_t *prog)
 {
-       float   *v1, *v2, *m1, *m2;
+       vec3_t  v1, v2, m1, m2;
        trace_t trace;
        int             move, svent;
        prvm_edict_t    *ent;
@@ -306,14 +320,14 @@ static void VM_CL_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 = CL_TraceBox(v1, m1, m2, v2, move, ent, CL_GenericHitSuperContentsMask(ent), CL_HitNetworkBrushModels(move), CL_HitNetworkPlayers(move), &svent, true);
@@ -326,7 +340,7 @@ static trace_t CL_Trace_Toss (prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edi
 {
        int i;
        float gravity;
-       vec3_t move, end;
+       vec3_t start, end, mins, maxs, move;
        vec3_t original_origin;
        vec3_t original_velocity;
        vec3_t original_angles;
@@ -349,7 +363,10 @@ static trace_t CL_Trace_Toss (prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edi
                VectorMA (PRVM_clientedictvector(tossent, angles), 0.05, PRVM_clientedictvector(tossent, avelocity), PRVM_clientedictvector(tossent, angles));
                VectorScale (PRVM_clientedictvector(tossent, velocity), 0.05, move);
                VectorAdd (PRVM_clientedictvector(tossent, origin), move, end);
-               trace = CL_TraceBox(PRVM_clientedictvector(tossent, origin), PRVM_clientedictvector(tossent, mins), PRVM_clientedictvector(tossent, maxs), end, MOVE_NORMAL, tossent, CL_GenericHitSuperContentsMask(tossent), true, true, NULL, true);
+               VectorCopy(PRVM_clientedictvector(tossent, origin), start);
+               VectorCopy(PRVM_clientedictvector(tossent, mins), mins);
+               VectorCopy(PRVM_clientedictvector(tossent, maxs), maxs);
+               trace = CL_TraceBox(start, mins, maxs, end, MOVE_NORMAL, tossent, CL_GenericHitSuperContentsMask(tossent), true, true, NULL, true);
                VectorCopy (trace.endpos, PRVM_clientedictvector(tossent, origin));
 
                if (trace.fraction < 1)
@@ -513,7 +530,7 @@ static void VM_CL_findradius (prvm_prog_t *prog)
 static void VM_CL_droptofloor (prvm_prog_t *prog)
 {
        prvm_edict_t            *ent;
-       vec3_t                          end;
+       vec3_t                          start, end, mins, maxs;
        trace_t                         trace;
 
        VM_SAFEPARMCOUNTRANGE(0, 2, VM_CL_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
@@ -533,10 +550,13 @@ static void VM_CL_droptofloor (prvm_prog_t *prog)
                return;
        }
 
-       VectorCopy (PRVM_clientedictvector(ent, origin), end);
+       VectorCopy(PRVM_clientedictvector(ent, origin), start);
+       VectorCopy(PRVM_clientedictvector(ent, mins), mins);
+       VectorCopy(PRVM_clientedictvector(ent, maxs), maxs);
+       VectorCopy(PRVM_clientedictvector(ent, origin), end);
        end[2] -= 256;
 
-       trace = CL_TraceBox(PRVM_clientedictvector(ent, origin), PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
+       trace = CL_TraceBox(start, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, NULL, true);
 
        if (trace.fraction != 1)
        {
@@ -643,20 +663,22 @@ realcheck:
 // #41 float(vector v) pointcontents
 static void VM_CL_pointcontents (prvm_prog_t *prog)
 {
+       vec3_t point;
        VM_SAFEPARMCOUNT(1, VM_CL_pointcontents);
-       PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, CL_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), point);
+       PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, CL_PointSuperContents(point));
 }
 
 // #48 void(vector o, vector d, float color, float count) particle
 static void VM_CL_particle (prvm_prog_t *prog)
 {
-       float   *org, *dir;
+       vec3_t org, dir;
        int             count;
        unsigned char   color;
        VM_SAFEPARMCOUNT(4, VM_CL_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 = (int)PRVM_G_FLOAT(OFS_PARM2);
        count = (int)PRVM_G_FLOAT(OFS_PARM3);
        CL_ParticleEffect(EFFECT_SVC_PARTICLE, count, org, org, dir, dir, NULL, color);
@@ -665,11 +687,11 @@ static void VM_CL_particle (prvm_prog_t *prog)
 // #74 void(vector pos, string samp, float vol, float atten) ambientsound
 static void VM_CL_ambientsound (prvm_prog_t *prog)
 {
-       float   *f;
+       vec3_t f;
        sfx_t   *s;
        VM_SAFEPARMCOUNT(4, VM_CL_ambientsound);
        s = S_FindName(PRVM_G_STRING(OFS_PARM0));
-       f = PRVM_G_VECTOR(OFS_PARM1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f);
        S_StaticSound (s, f, PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM3)*64);
 }
 
@@ -677,11 +699,11 @@ static void VM_CL_ambientsound (prvm_prog_t *prog)
 static void VM_CL_getlight (prvm_prog_t *prog)
 {
        vec3_t ambientcolor, diffusecolor, diffusenormal;
-       vec_t *p;
+       vec3_t p;
 
        VM_SAFEPARMCOUNTRANGE(1, 3, VM_CL_getlight);
 
-       p = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), p);
        VectorClear(ambientcolor);
        VectorClear(diffusecolor);
        VectorClear(diffusenormal);
@@ -783,7 +805,7 @@ static void VM_CL_R_AddEntity (prvm_prog_t *prog)
 static void VM_CL_R_SetView (prvm_prog_t *prog)
 {
        int             c;
-       float   *f;
+       prvm_vec_t      *f;
        float   k;
 
        VM_SAFEPARMCOUNTRANGE(1, 3, VM_CL_R_SetView);
@@ -911,6 +933,9 @@ static void VM_CL_R_SetView (prvm_prog_t *prog)
                case VF_FOG_FADEDEPTH:
                        PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_fadedepth;
                        break;
+               case VF_MINFPS_QUALITY:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.view.quality;
+                       break;
                default:
                        PRVM_G_FLOAT(OFS_RETURN) = 0;
                        VM_Warning(prog, "VM_CL_R_GetView : unknown parm %i\n", c);
@@ -1061,6 +1086,9 @@ static void VM_CL_R_SetView (prvm_prog_t *prog)
        case VF_FOG_FADEDEPTH:
                r_refdef.fog_fadedepth = k;
                break;
+       case VF_MINFPS_QUALITY:
+               r_refdef.view.quality = k;
+               break;
        default:
                PRVM_G_FLOAT(OFS_RETURN) = 0;
                VM_Warning(prog, "VM_CL_R_SetView : unknown parm %i\n", c);
@@ -1073,9 +1101,9 @@ static void VM_CL_R_SetView (prvm_prog_t *prog)
 static void VM_CL_R_AddDynamicLight (prvm_prog_t *prog)
 {
        double t = Sys_DirtyTime();
-       vec_t *org;
+       vec3_t org;
        float radius = 300;
-       vec_t *col;
+       vec3_t col;
        int style = -1;
        const char *cubemapname = NULL;
        int pflags = PFLAGS_CORONA | PFLAGS_FULLDYNAMIC;
@@ -1093,9 +1121,9 @@ static void VM_CL_R_AddDynamicLight (prvm_prog_t *prog)
        if (r_refdef.scene.numlights >= MAX_DLIGHTS)
                return;
 
-       org = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
        radius = PRVM_G_FLOAT(OFS_PARM1);
-       col = PRVM_G_VECTOR(OFS_PARM2);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), col);
        if (prog->argc >= 4)
        {
                style = (int)PRVM_G_FLOAT(OFS_PARM3);
@@ -1128,29 +1156,31 @@ static void VM_CL_R_AddDynamicLight (prvm_prog_t *prog)
 //#310 vector (vector v) cs_unproject (EXT_CSQC)
 static void VM_CL_unproject (prvm_prog_t *prog)
 {
-       float   *f;
-       vec3_t  temp;
+       vec3_t f;
+       vec3_t temp;
+       vec3_t result;
 
        VM_SAFEPARMCOUNT(1, VM_CL_unproject);
-       f = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), f);
        VectorSet(temp,
                f[2],
                (-1.0 + 2.0 * (f[0] / vid_conwidth.integer)) * f[2] * -r_refdef.view.frustum_x,
                (-1.0 + 2.0 * (f[1] / vid_conheight.integer)) * f[2] * -r_refdef.view.frustum_y);
        if(v_flipped.integer)
                temp[1] = -temp[1];
-       Matrix4x4_Transform(&r_refdef.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
+       Matrix4x4_Transform(&r_refdef.view.matrix, temp, result);
+       VectorCopy(result, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 //#311 vector (vector v) cs_project (EXT_CSQC)
 static void VM_CL_project (prvm_prog_t *prog)
 {
-       float   *f;
-       vec3_t  v;
+       vec3_t f;
+       vec3_t v;
        matrix4x4_t m;
 
        VM_SAFEPARMCOUNT(1, VM_CL_project);
-       f = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), f);
        Matrix4x4_Invert_Simple(&m, &r_refdef.view.matrix);
        Matrix4x4_Transform(&m, f, v);
        if(v_flipped.integer)
@@ -1299,18 +1329,19 @@ static void VM_CL_particleeffectnum (prvm_prog_t *prog)
 static void VM_CL_trailparticles (prvm_prog_t *prog)
 {
        int                             i;
-       float                   *start, *end;
+       vec3_t                  start, end, velocity;
        prvm_edict_t    *t;
        VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_trailparticles);
 
        t = PRVM_G_EDICT(OFS_PARM0);
        i               = (int)PRVM_G_FLOAT(OFS_PARM1);
-       start   = PRVM_G_VECTOR(OFS_PARM2);
-       end             = PRVM_G_VECTOR(OFS_PARM3);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), start);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM3), end);
+       VectorCopy(PRVM_clientedictvector(t, velocity), velocity);
 
        if (i < 0)
                return;
-       CL_ParticleEffect(i, 1, start, end, PRVM_clientedictvector(t, velocity), PRVM_clientedictvector(t, velocity), NULL, prog->argc >= 5 ? (int)PRVM_G_FLOAT(OFS_PARM4) : 0);
+       CL_ParticleEffect(i, 1, start, end, velocity, velocity, NULL, prog->argc >= 5 ? (int)PRVM_G_FLOAT(OFS_PARM4) : 0);
 }
 
 //#337 void(float effectnum, vector origin, vector dir, float count[, float color]) pointparticles (EXT_CSQC)
@@ -1318,11 +1349,11 @@ static void VM_CL_pointparticles (prvm_prog_t *prog)
 {
        int                     i;
        float n;
-       float           *f, *v;
+       vec3_t f, v;
        VM_SAFEPARMCOUNTRANGE(4, 5, VM_CL_pointparticles);
        i = (int)PRVM_G_FLOAT(OFS_PARM0);
-       f = PRVM_G_VECTOR(OFS_PARM1);
-       v = PRVM_G_VECTOR(OFS_PARM2);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), f);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), v);
        n = PRVM_G_FLOAT(OFS_PARM3);
        if (i < 0)
                return;
@@ -1334,7 +1365,7 @@ static void VM_CL_boxparticles (prvm_prog_t *prog)
 {
        int effectnum;
        // prvm_edict_t *own;
-       float *origin_from, *origin_to, *dir_from, *dir_to;
+       vec3_t origin_from, origin_to, dir_from, dir_to;
        float count;
        int flags;
        float tintmins[4], tintmaxs[4];
@@ -1342,10 +1373,10 @@ static void VM_CL_boxparticles (prvm_prog_t *prog)
 
        effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
        // own = PRVM_G_EDICT(OFS_PARM1); // TODO find use for this
-       origin_from = PRVM_G_VECTOR(OFS_PARM2);
-       origin_to = PRVM_G_VECTOR(OFS_PARM3);
-       dir_from = PRVM_G_VECTOR(OFS_PARM4);
-       dir_to = PRVM_G_VECTOR(OFS_PARM5);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), origin_from);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM3), origin_to  );
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM4), dir_from   );
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM5), dir_to     );
        count = PRVM_G_FLOAT(OFS_PARM6);
        if(prog->argc >= 8)
                flags = PRVM_G_FLOAT(OFS_PARM7);
@@ -1416,6 +1447,7 @@ static void VM_CL_getinputstate (prvm_prog_t *prog)
                        PRVM_clientglobalvector(input_movevalues)[1] = cl.movecmd[i].sidemove;
                        PRVM_clientglobalvector(input_movevalues)[2] = cl.movecmd[i].upmove;
                        PRVM_clientglobalfloat(input_timelength) = cl.movecmd[i].frametime;
+                       // this probably shouldn't be here
                        if(cl.movecmd[i].crouch)
                        {
                                VectorCopy(cl.playercrouchmins, PRVM_clientglobalvector(pmove_mins));
@@ -1439,37 +1471,74 @@ static void VM_CL_setsensitivityscale (prvm_prog_t *prog)
 }
 
 //#347 void() runstandardplayerphysics (EXT_CSQC)
+#define PMF_JUMP_HELD 1 // matches FTEQW
+#define PMF_LADDER 2 // not used by DP, FTEQW sets this in runplayerphysics but does not read it
+#define PMF_DUCKED 4 // FIXME FTEQW doesn't have this for Q1 like movement because Q1 cannot crouch
+#define PMF_ONGROUND 8 // FIXME FTEQW doesn't have this for Q1 like movement and expects CSQC code to do its own trace, this is stupid CPU waste
 static void VM_CL_runplayerphysics (prvm_prog_t *prog)
 {
        cl_clientmovement_state_t s;
        prvm_edict_t *ent;
 
-       VM_SAFEPARMCOUNT(1, VM_CL_runplayerphysics);
+       memset(&s, 0, sizeof(s));
+
+       VM_SAFEPARMCOUNTRANGE(0, 1, VM_CL_runplayerphysics);
+
+       ent = (prog->argc == 1 ? PRVM_G_EDICT(OFS_PARM0) : prog->edicts);
+       if(ent == prog->edicts)
+       {
+               // deprecated use
+               s.self = NULL;
+               VectorCopy(PRVM_clientglobalvector(pmove_org), s.origin);
+               VectorCopy(PRVM_clientglobalvector(pmove_vel), s.velocity);
+               VectorCopy(PRVM_clientglobalvector(pmove_mins), s.mins);
+               VectorCopy(PRVM_clientglobalvector(pmove_maxs), s.maxs);
+               s.crouched = 0;
+               s.waterjumptime = PRVM_clientglobalfloat(pmove_waterjumptime);
+               s.cmd.canjump = (int)PRVM_clientglobalfloat(pmove_jump_held) == 0;
+       }
+       else
+       {
+               // new use
+               s.self = ent;
+               VectorCopy(PRVM_clientedictvector(ent, origin), s.origin);
+               VectorCopy(PRVM_clientedictvector(ent, velocity), s.velocity);
+               VectorCopy(PRVM_clientedictvector(ent, mins), s.mins);
+               VectorCopy(PRVM_clientedictvector(ent, maxs), s.maxs);
+               s.crouched = ((int)PRVM_clientedictfloat(ent, pmove_flags) & PMF_DUCKED) != 0;
+               s.waterjumptime = 0; // FIXME where do we get this from? FTEQW lacks support for this too
+               s.cmd.canjump = ((int)PRVM_clientedictfloat(ent, pmove_flags) & PMF_JUMP_HELD) == 0;
+       }
 
-       ent = PRVM_G_EDICT(OFS_PARM0);
-       VectorCopy(PRVM_clientedictvector(ent, origin), s.origin);
-       VectorCopy(PRVM_clientedictvector(ent, velocity), s.velocity);
-       VectorCopy(PRVM_clientglobalvector(pmove_mins), s.mins);
-       VectorCopy(PRVM_clientglobalvector(pmove_maxs), s.maxs);
-       s.onground = 0; // ???
-       s.crouched = 0; // ???
-       s.watertype = 0; // ???
-       s.waterlevel = 0; // ???
-       s.waterjumptime = 0; // ???
        VectorCopy(PRVM_clientglobalvector(input_angles), s.cmd.viewangles);
        s.cmd.forwardmove = PRVM_clientglobalvector(input_movevalues)[0];
        s.cmd.sidemove = PRVM_clientglobalvector(input_movevalues)[1];
        s.cmd.upmove = PRVM_clientglobalvector(input_movevalues)[2];
        s.cmd.buttons = PRVM_clientglobalfloat(input_buttons);
        s.cmd.frametime = PRVM_clientglobalfloat(input_timelength);
-       s.cmd.canjump = 1; // ???
        s.cmd.jump = (s.cmd.buttons & 2) != 0;
        s.cmd.crouch = (s.cmd.buttons & 16) != 0;
 
-       CL_ClientMovement_PlayerMove(&s);
+       CL_ClientMovement_PlayerMove_Frame(&s);
 
-       VectorCopy(s.origin, PRVM_clientedictvector(ent, origin));
-       VectorCopy(s.velocity, PRVM_clientedictvector(ent, velocity));
+       if(ent == prog->edicts)
+       {
+               // deprecated use
+               VectorCopy(s.origin, PRVM_clientglobalvector(pmove_org));
+               VectorCopy(s.velocity, PRVM_clientglobalvector(pmove_vel));
+               PRVM_clientglobalfloat(pmove_jump_held) = !s.cmd.canjump;
+               PRVM_clientglobalfloat(pmove_waterjumptime) = s.waterjumptime;
+       }
+       else
+       {
+               // new use
+               VectorCopy(s.origin, PRVM_clientedictvector(ent, origin));
+               VectorCopy(s.velocity, PRVM_clientedictvector(ent, velocity));
+               PRVM_clientedictfloat(ent, pmove_flags) =
+                       (s.crouched ? PMF_DUCKED : 0) |
+                       (s.cmd.canjump ? 0 : PMF_JUMP_HELD) |
+                       (s.onground ? PMF_ONGROUND : 0);
+       }
 }
 
 //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
@@ -1533,7 +1602,7 @@ static void VM_CL_getplayerkey (prvm_prog_t *prog)
                        {
                                vec3_t origin;
                                Matrix4x4_OriginFromMatrix(&e->render.matrix, origin);
-                               dpsnprintf(t, sizeof(t), "%.9g %.9g %.9g", origin[0], origin[1], origin[2]);
+                               dpsnprintf(t, sizeof(t), VECTOR_LOSSLESS_FORMAT, origin[0], origin[1], origin[2]);
                        }
                }
        if(!t[0])
@@ -1544,8 +1613,13 @@ static void VM_CL_getplayerkey (prvm_prog_t *prog)
 //#351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
 static void VM_CL_setlistener (prvm_prog_t *prog)
 {
+       vec3_t origin, forward, left, up;
        VM_SAFEPARMCOUNT(4, VM_CL_setlistener);
-       Matrix4x4_FromVectors(&cl.csqc_listenermatrix, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), PRVM_G_VECTOR(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), origin);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), forward);
+       VectorNegate(PRVM_G_VECTOR(OFS_PARM2), left);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM3), up);
+       Matrix4x4_FromVectors(&cl.csqc_listenermatrix, forward, left, up, origin);
        cl.csqc_usecsqclistener = true; //use csqc listener at this frame
 }
 
@@ -1725,9 +1799,12 @@ static void VM_CL_makestatic (prvm_prog_t *prog)
                renderflags = (int)PRVM_clientedictfloat(ent, renderflags);
                if (renderflags & RF_USEAXIS)
                {
-                       vec3_t left;
+                       vec3_t forward, left, up, origin;
+                       VectorCopy(PRVM_clientglobalvector(v_forward), forward);
                        VectorNegate(PRVM_clientglobalvector(v_right), left);
-                       Matrix4x4_FromVectors(&staticent->render.matrix, PRVM_clientglobalvector(v_forward), left, PRVM_clientglobalvector(v_up), PRVM_clientedictvector(ent, origin));
+                       VectorCopy(PRVM_clientglobalvector(v_up), up);
+                       VectorCopy(PRVM_clientedictvector(ent, origin), origin);
+                       Matrix4x4_FromVectors(&staticent->render.matrix, forward, left, up, origin);
                        Matrix4x4_Scale(&staticent->render.matrix, staticent->render.scale, 1);
                }
                else
@@ -1798,7 +1875,7 @@ static void VM_CL_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));
        CL_LinkEdict(out);
 }
 
@@ -1807,28 +1884,34 @@ static void VM_CL_copyentity (prvm_prog_t *prog)
 // #404 void(vector org, string modelname, float startframe, float endframe, float framerate) effect (DP_SV_EFFECT)
 static void VM_CL_effect (prvm_prog_t *prog)
 {
+#if 1
+       Con_Printf("WARNING: VM_CL_effect not implemented\n"); // FIXME: this needs to take modelname not modelindex, the csqc defs has it as string and so it shall be
+#else
+       vec3_t org;
        VM_SAFEPARMCOUNT(5, VM_CL_effect);
-       CL_Effect(PRVM_G_VECTOR(OFS_PARM0), (int)PRVM_G_FLOAT(OFS_PARM1), (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+       CL_Effect(org, (int)PRVM_G_FLOAT(OFS_PARM1), (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), PRVM_G_FLOAT(OFS_PARM4));
+#endif
 }
 
 // #405 void(vector org, vector velocity, float howmany) te_blood (DP_TE_BLOOD)
 static void VM_CL_te_blood (prvm_prog_t *prog)
 {
-       float   *pos;
-       vec3_t  pos2;
+       vec3_t pos, vel, pos2;
        VM_SAFEPARMCOUNT(3, VM_CL_te_blood);
        if (PRVM_G_FLOAT(OFS_PARM2) < 1)
                return;
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), vel);
        CL_FindNonSolidLocation(pos, pos2, 4);
-       CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
+       CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, vel, vel, NULL, 0);
 }
 
 // #406 void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower (DP_TE_BLOODSHOWER)
 static void VM_CL_te_bloodshower (prvm_prog_t *prog)
 {
        vec_t speed;
-       vec3_t vel1, vel2;
+       vec3_t mincorner, maxcorner, vel1, vel2;
        VM_SAFEPARMCOUNT(4, VM_CL_te_bloodshower);
        if (PRVM_G_FLOAT(OFS_PARM3) < 1)
                return;
@@ -1839,17 +1922,19 @@ static void VM_CL_te_bloodshower (prvm_prog_t *prog)
        vel2[0] = speed;
        vel2[1] = speed;
        vel2[2] = speed;
-       CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM3), PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), vel1, vel2, NULL, 0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), mincorner);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), maxcorner);
+       CL_ParticleEffect(EFFECT_TE_BLOOD, PRVM_G_FLOAT(OFS_PARM3), mincorner, maxcorner, vel1, vel2, NULL, 0);
 }
 
 // #407 void(vector org, vector color) te_explosionrgb (DP_TE_EXPLOSIONRGB)
 static void VM_CL_te_explosionrgb (prvm_prog_t *prog)
 {
-       float           *pos;
+       vec3_t          pos;
        vec3_t          pos2;
        matrix4x4_t     tempmatrix;
        VM_SAFEPARMCOUNT(2, VM_CL_te_explosionrgb);
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 10);
        CL_ParticleExplosion(pos2);
        Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
@@ -1859,46 +1944,57 @@ static void VM_CL_te_explosionrgb (prvm_prog_t *prog)
 // #408 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube (DP_TE_PARTICLECUBE)
 static void VM_CL_te_particlecube (prvm_prog_t *prog)
 {
+       vec3_t mincorner, maxcorner, vel;
        VM_SAFEPARMCOUNT(7, VM_CL_te_particlecube);
-       CL_ParticleCube(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), PRVM_G_FLOAT(OFS_PARM5), PRVM_G_FLOAT(OFS_PARM6));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), mincorner);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), maxcorner);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
+       CL_ParticleCube(mincorner, maxcorner, vel, (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), PRVM_G_FLOAT(OFS_PARM5), PRVM_G_FLOAT(OFS_PARM6));
 }
 
 // #409 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain (DP_TE_PARTICLERAIN)
 static void VM_CL_te_particlerain (prvm_prog_t *prog)
 {
+       vec3_t mincorner, maxcorner, vel;
        VM_SAFEPARMCOUNT(5, VM_CL_te_particlerain);
-       CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), mincorner);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), maxcorner);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
+       CL_ParticleRain(mincorner, maxcorner, vel, (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 0);
 }
 
 // #410 void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow (DP_TE_PARTICLESNOW)
 static void VM_CL_te_particlesnow (prvm_prog_t *prog)
 {
+       vec3_t mincorner, maxcorner, vel;
        VM_SAFEPARMCOUNT(5, VM_CL_te_particlesnow);
-       CL_ParticleRain(PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), mincorner);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), maxcorner);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), vel);
+       CL_ParticleRain(mincorner, maxcorner, vel, (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4), 1);
 }
 
 // #411 void(vector org, vector vel, float howmany) te_spark
 static void VM_CL_te_spark (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t pos, pos2, vel;
        VM_SAFEPARMCOUNT(3, VM_CL_te_spark);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), vel);
        CL_FindNonSolidLocation(pos, pos2, 4);
-       CL_ParticleEffect(EFFECT_TE_SPARK, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
+       CL_ParticleEffect(EFFECT_TE_SPARK, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, vel, vel, NULL, 0);
 }
 
 extern cvar_t cl_sound_ric_gunshot;
 // #412 void(vector org) te_gunshotquad (DP_QUADEFFECTS1)
 static void VM_CL_te_gunshotquad (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        int                     rnd;
        VM_SAFEPARMCOUNT(1, VM_CL_te_gunshotquad);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_GUNSHOTQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        if(cl_sound_ric_gunshot.integer >= 2)
@@ -1917,12 +2013,11 @@ static void VM_CL_te_gunshotquad (prvm_prog_t *prog)
 // #413 void(vector org) te_spikequad (DP_QUADEFFECTS1)
 static void VM_CL_te_spikequad (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        int                     rnd;
        VM_SAFEPARMCOUNT(1, VM_CL_te_spikequad);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_SPIKEQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        if (rand() % 5)                 S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
@@ -1938,12 +2033,11 @@ static void VM_CL_te_spikequad (prvm_prog_t *prog)
 // #414 void(vector org) te_superspikequad (DP_QUADEFFECTS1)
 static void VM_CL_te_superspikequad (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        int                     rnd;
        VM_SAFEPARMCOUNT(1, VM_CL_te_superspikequad);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_SUPERSPIKEQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        if (rand() % 5)                 S_StartSound(-1, 0, cl.sfx_tink1, pos, 1, 1);
@@ -1959,11 +2053,10 @@ static void VM_CL_te_superspikequad (prvm_prog_t *prog)
 // #415 void(vector org) te_explosionquad (DP_QUADEFFECTS1)
 static void VM_CL_te_explosionquad (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        VM_SAFEPARMCOUNT(1, VM_CL_te_explosionquad);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 10);
        CL_ParticleEffect(EFFECT_TE_EXPLOSIONQUAD, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
@@ -1972,11 +2065,10 @@ static void VM_CL_te_explosionquad (prvm_prog_t *prog)
 // #416 void(vector org) te_smallflash (DP_TE_SMALLFLASH)
 static void VM_CL_te_smallflash (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        VM_SAFEPARMCOUNT(1, VM_CL_te_smallflash);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 10);
        CL_ParticleEffect(EFFECT_TE_SMALLFLASH, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
 }
@@ -1984,12 +2076,11 @@ static void VM_CL_te_smallflash (prvm_prog_t *prog)
 // #417 void(vector org, float radius, float lifetime, vector color) te_customflash (DP_TE_CUSTOMFLASH)
 static void VM_CL_te_customflash (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        matrix4x4_t     tempmatrix;
        VM_SAFEPARMCOUNT(4, VM_CL_te_customflash);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        Matrix4x4_CreateTranslate(&tempmatrix, pos2[0], pos2[1], pos2[2]);
        CL_AllocLightFlash(NULL, &tempmatrix, PRVM_G_FLOAT(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM3)[0], PRVM_G_VECTOR(OFS_PARM3)[1], PRVM_G_VECTOR(OFS_PARM3)[2], PRVM_G_FLOAT(OFS_PARM1) / PRVM_G_FLOAT(OFS_PARM2), PRVM_G_FLOAT(OFS_PARM2), 0, -1, true, 1, 0.25, 1, 1, 1, LIGHTFLAG_NORMALMODE | LIGHTFLAG_REALTIMEMODE);
@@ -1998,12 +2089,11 @@ static void VM_CL_te_customflash (prvm_prog_t *prog)
 // #418 void(vector org) te_gunshot (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_gunshot (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        int                     rnd;
        VM_SAFEPARMCOUNT(1, VM_CL_te_gunshot);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_GUNSHOT, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        if(cl_sound_ric_gunshot.integer == 1 || cl_sound_ric_gunshot.integer == 3)
@@ -2022,12 +2112,11 @@ static void VM_CL_te_gunshot (prvm_prog_t *prog)
 // #419 void(vector org) te_spike (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_spike (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        int                     rnd;
        VM_SAFEPARMCOUNT(1, VM_CL_te_spike);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_SPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        if (rand() % 5)                 S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
@@ -2043,12 +2132,11 @@ static void VM_CL_te_spike (prvm_prog_t *prog)
 // #420 void(vector org) te_superspike (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_superspike (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        int                     rnd;
        VM_SAFEPARMCOUNT(1, VM_CL_te_superspike);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_SUPERSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        if (rand() % 5)                 S_StartSound(-1, 0, cl.sfx_tink1, pos2, 1, 1);
@@ -2064,11 +2152,10 @@ static void VM_CL_te_superspike (prvm_prog_t *prog)
 // #421 void(vector org) te_explosion (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_explosion (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        VM_SAFEPARMCOUNT(1, VM_CL_te_explosion);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 10);
        CL_ParticleEffect(EFFECT_TE_EXPLOSION, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
@@ -2077,11 +2164,10 @@ static void VM_CL_te_explosion (prvm_prog_t *prog)
 // #422 void(vector org) te_tarexplosion (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_tarexplosion (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        VM_SAFEPARMCOUNT(1, VM_CL_te_tarexplosion);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 10);
        CL_ParticleEffect(EFFECT_TE_TAREXPLOSION, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        S_StartSound(-1, 0, cl.sfx_r_exp3, pos2, 1, 1);
@@ -2090,11 +2176,10 @@ static void VM_CL_te_tarexplosion (prvm_prog_t *prog)
 // #423 void(vector org) te_wizspike (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_wizspike (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        VM_SAFEPARMCOUNT(1, VM_CL_te_wizspike);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_WIZSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        S_StartSound(-1, 0, cl.sfx_wizhit, pos2, 1, 1);
@@ -2103,11 +2188,10 @@ static void VM_CL_te_wizspike (prvm_prog_t *prog)
 // #424 void(vector org) te_knightspike (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_knightspike (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        VM_SAFEPARMCOUNT(1, VM_CL_te_knightspike);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_KNIGHTSPIKE, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
        S_StartSound(-1, 0, cl.sfx_knighthit, pos2, 1, 1);
@@ -2116,28 +2200,31 @@ static void VM_CL_te_knightspike (prvm_prog_t *prog)
 // #425 void(vector org) te_lavasplash (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_lavasplash (prvm_prog_t *prog)
 {
+       vec3_t          pos;
        VM_SAFEPARMCOUNT(1, VM_CL_te_lavasplash);
-       CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+       CL_ParticleEffect(EFFECT_TE_LAVASPLASH, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
 }
 
 // #426 void(vector org) te_teleport (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_teleport (prvm_prog_t *prog)
 {
+       vec3_t          pos;
        VM_SAFEPARMCOUNT(1, VM_CL_te_teleport);
-       CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, PRVM_G_VECTOR(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM0), vec3_origin, vec3_origin, NULL, 0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+       CL_ParticleEffect(EFFECT_TE_TELEPORT, 1, pos, pos, vec3_origin, vec3_origin, NULL, 0);
 }
 
 // #427 void(vector org, float colorstart, float colorlength) te_explosion2 (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_explosion2 (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2, color;
+       vec3_t          pos, pos2, color;
        matrix4x4_t     tempmatrix;
        int                     colorStart, colorLength;
        unsigned char           *tempcolor;
        VM_SAFEPARMCOUNT(3, VM_CL_te_explosion2);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        colorStart = (int)PRVM_G_FLOAT(OFS_PARM1);
        colorLength = (int)PRVM_G_FLOAT(OFS_PARM2);
        CL_FindNonSolidLocation(pos, pos2, 10);
@@ -2155,39 +2242,50 @@ static void VM_CL_te_explosion2 (prvm_prog_t *prog)
 // #428 void(entity own, vector start, vector end) te_lightning1 (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_lightning1 (prvm_prog_t *prog)
 {
+       vec3_t          start, end;
        VM_SAFEPARMCOUNT(3, VM_CL_te_lightning1);
-       CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt, true);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), start);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), end);
+       CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), start, end, cl.model_bolt, true);
 }
 
 // #429 void(entity own, vector start, vector end) te_lightning2 (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_lightning2 (prvm_prog_t *prog)
 {
+       vec3_t          start, end;
        VM_SAFEPARMCOUNT(3, VM_CL_te_lightning2);
-       CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt2, true);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), start);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), end);
+       CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), start, end, cl.model_bolt2, true);
 }
 
 // #430 void(entity own, vector start, vector end) te_lightning3 (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_lightning3 (prvm_prog_t *prog)
 {
+       vec3_t          start, end;
        VM_SAFEPARMCOUNT(3, VM_CL_te_lightning3);
-       CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_bolt3, false);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), start);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), end);
+       CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), start, end, cl.model_bolt3, false);
 }
 
 // #431 void(entity own, vector start, vector end) te_beam (DP_TE_STANDARDEFFECTBUILTINS)
 static void VM_CL_te_beam (prvm_prog_t *prog)
 {
+       vec3_t          start, end;
        VM_SAFEPARMCOUNT(3, VM_CL_te_beam);
-       CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM2), cl.model_beam, false);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), start);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), end);
+       CL_NewBeam(PRVM_G_EDICTNUM(OFS_PARM0), start, end, cl.model_beam, false);
 }
 
 // #433 void(vector org) te_plasmaburn (DP_TE_PLASMABURN)
 static void VM_CL_te_plasmaburn (prvm_prog_t *prog)
 {
-       float           *pos;
-       vec3_t          pos2;
+       vec3_t          pos, pos2;
        VM_SAFEPARMCOUNT(1, VM_CL_te_plasmaburn);
 
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        CL_FindNonSolidLocation(pos, pos2, 4);
        CL_ParticleEffect(EFFECT_TE_PLASMABURN, 1, pos2, pos2, vec3_origin, vec3_origin, NULL, 0);
 }
@@ -2195,14 +2293,14 @@ static void VM_CL_te_plasmaburn (prvm_prog_t *prog)
 // #457 void(vector org, vector velocity, float howmany) te_flamejet (DP_TE_FLAMEJET)
 static void VM_CL_te_flamejet (prvm_prog_t *prog)
 {
-       float *pos;
-       vec3_t pos2;
+       vec3_t          pos, pos2, vel;
        VM_SAFEPARMCOUNT(3, VM_CL_te_flamejet);
        if (PRVM_G_FLOAT(OFS_PARM2) < 1)
                return;
-       pos = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), vel);
        CL_FindNonSolidLocation(pos, pos2, 4);
-       CL_ParticleEffect(EFFECT_TE_FLAMEJET, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, PRVM_G_VECTOR(OFS_PARM1), PRVM_G_VECTOR(OFS_PARM1), NULL, 0);
+       CL_ParticleEffect(EFFECT_TE_FLAMEJET, PRVM_G_FLOAT(OFS_PARM2), pos2, pos2, vel, vel, NULL, 0);
 }
 
 
@@ -2336,7 +2434,7 @@ static int CL_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int
         && 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, cl.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);
        }
@@ -2460,7 +2558,8 @@ static void VM_CL_gettagindex (prvm_prog_t *prog)
        {
                tag_index = CL_GetTagIndex(prog, ent, tag_name);
                if (tag_index == 0)
-                       Con_DPrintf("VM_CL_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
+                       if(developer_extra.integer)
+                               Con_DPrintf("VM_CL_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
        }
        PRVM_G_FLOAT(OFS_RETURN) = tag_index;
 }
@@ -2475,7 +2574,7 @@ static void VM_CL_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_CL_gettaginfo);
@@ -2483,21 +2582,24 @@ static void VM_CL_gettaginfo (prvm_prog_t *prog)
        e = PRVM_G_EDICT(OFS_PARM0);
        tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
        returncode = CL_GetTagMatrix(prog, &tag_matrix, e, tagindex);
-       Matrix4x4_ToVectors(&tag_matrix, PRVM_clientglobalvector(v_forward), le, PRVM_clientglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));
-       VectorScale(le, -1, PRVM_clientglobalvector(v_right));
+       Matrix4x4_ToVectors(&tag_matrix, forward, left, up, origin);
+       VectorCopy(forward, PRVM_clientglobalvector(v_forward));
+       VectorScale(left, -1, PRVM_clientglobalvector(v_right));
+       VectorCopy(up, PRVM_clientglobalvector(v_up));
+       VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
        model = CL_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, cl.time);
        VM_UpdateEdictSkeleton(prog, e, model, e->priv.server->frameblend);
        CL_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_clientglobalfloat(gettaginfo_parent) = parentindex;
        PRVM_clientglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0;
-       VectorCopy(trans, PRVM_clientglobalvector(gettaginfo_offset));
-       VectorCopy(fo, PRVM_clientglobalvector(gettaginfo_forward));
-       VectorScale(le, -1, PRVM_clientglobalvector(gettaginfo_right));
+       VectorCopy(forward, PRVM_clientglobalvector(gettaginfo_forward));
+       VectorScale(left, -1, PRVM_clientglobalvector(gettaginfo_right));
        VectorCopy(up, PRVM_clientglobalvector(gettaginfo_up));
+       VectorCopy(origin, PRVM_clientglobalvector(gettaginfo_offset));
 
        switch(returncode)
        {
@@ -2568,35 +2670,6 @@ typedef struct vmparticlespawner_s
        qboolean                        verified;
        vmparticletheme_t       *themes;
        int                                     max_themes;
-       // global addresses
-       float *particle_type;
-       float *particle_blendmode; 
-       float *particle_orientation;
-       float *particle_color1;
-       float *particle_color2;
-       float *particle_tex;
-       float *particle_size;
-       float *particle_sizeincrease;
-       float *particle_alpha;
-       float *particle_alphafade;
-       float *particle_time;
-       float *particle_gravity;
-       float *particle_bounce;
-       float *particle_airfriction;
-       float *particle_liquidfriction;
-       float *particle_originjitter;
-       float *particle_velocityjitter;
-       float *particle_qualityreduction;
-       float *particle_stretch;
-       float *particle_staincolor1;
-       float *particle_staincolor2;
-       float *particle_stainalpha;
-       float *particle_stainsize;
-       float *particle_staintex;
-       float *particle_delayspawn;
-       float *particle_delaycollision;
-       float *particle_angle;
-       float *particle_spin;
 }vmparticlespawner_t;
 
 vmparticlespawner_t vmpartspawner;
@@ -2620,38 +2693,6 @@ static void VM_InitParticleSpawner (prvm_prog_t *prog, int maxthemes)
        vmpartspawner.max_themes = maxthemes;
        vmpartspawner.initialized = true;
        vmpartspawner.verified = true;
-       // get field addresses for fast querying (we can do 1000 calls of spawnparticle in a frame)
-       vmpartspawner.particle_type = &PRVM_clientglobalfloat(particle_type);
-       vmpartspawner.particle_blendmode = &PRVM_clientglobalfloat(particle_blendmode);
-       vmpartspawner.particle_orientation = &PRVM_clientglobalfloat(particle_orientation);
-       vmpartspawner.particle_color1 = PRVM_clientglobalvector(particle_color1);
-       vmpartspawner.particle_color2 = PRVM_clientglobalvector(particle_color2);
-       vmpartspawner.particle_tex = &PRVM_clientglobalfloat(particle_tex);
-       vmpartspawner.particle_size = &PRVM_clientglobalfloat(particle_size);
-       vmpartspawner.particle_sizeincrease = &PRVM_clientglobalfloat(particle_sizeincrease);
-       vmpartspawner.particle_alpha = &PRVM_clientglobalfloat(particle_alpha);
-       vmpartspawner.particle_alphafade = &PRVM_clientglobalfloat(particle_alphafade);
-       vmpartspawner.particle_time = &PRVM_clientglobalfloat(particle_time);
-       vmpartspawner.particle_gravity = &PRVM_clientglobalfloat(particle_gravity);
-       vmpartspawner.particle_bounce = &PRVM_clientglobalfloat(particle_bounce);
-       vmpartspawner.particle_airfriction = &PRVM_clientglobalfloat(particle_airfriction);
-       vmpartspawner.particle_liquidfriction = &PRVM_clientglobalfloat(particle_liquidfriction);
-       vmpartspawner.particle_originjitter = &PRVM_clientglobalfloat(particle_originjitter);
-       vmpartspawner.particle_velocityjitter = &PRVM_clientglobalfloat(particle_velocityjitter);
-       vmpartspawner.particle_qualityreduction = &PRVM_clientglobalfloat(particle_qualityreduction);
-       vmpartspawner.particle_stretch = &PRVM_clientglobalfloat(particle_stretch);
-       vmpartspawner.particle_staincolor1 = PRVM_clientglobalvector(particle_staincolor1);
-       vmpartspawner.particle_staincolor2 = PRVM_clientglobalvector(particle_staincolor2);
-       vmpartspawner.particle_stainalpha = &PRVM_clientglobalfloat(particle_stainalpha);
-       vmpartspawner.particle_stainsize = &PRVM_clientglobalfloat(particle_stainsize);
-       vmpartspawner.particle_staintex = &PRVM_clientglobalfloat(particle_staintex);
-       vmpartspawner.particle_staintex = &PRVM_clientglobalfloat(particle_staintex);
-       vmpartspawner.particle_delayspawn = &PRVM_clientglobalfloat(particle_delayspawn);
-       vmpartspawner.particle_delaycollision = &PRVM_clientglobalfloat(particle_delaycollision);
-       vmpartspawner.particle_angle = &PRVM_clientglobalfloat(particle_angle);
-       vmpartspawner.particle_spin = &PRVM_clientglobalfloat(particle_spin);
-       #undef getglobal
-       #undef getglobalvector
 }
 
 // reset particle theme to default values
@@ -2687,77 +2728,70 @@ static void VM_ResetParticleTheme (vmparticletheme_t *theme)
 }
 
 // particle theme -> QC globals
-static void VM_CL_ParticleThemeToGlobals(vmparticletheme_t *theme)
-{
-       *vmpartspawner.particle_type = theme->typeindex;
-       *vmpartspawner.particle_blendmode = theme->blendmode;
-       *vmpartspawner.particle_orientation = theme->orientation;
-       vmpartspawner.particle_color1[0] = (theme->color1 >> 16) & 0xFF; // VorteX: int only can store 0-255, not 0-256 which means 0 - 0,99609375...
-       vmpartspawner.particle_color1[1] = (theme->color1 >> 8) & 0xFF;
-       vmpartspawner.particle_color1[2] = (theme->color1 >> 0) & 0xFF;
-       vmpartspawner.particle_color2[0] = (theme->color2 >> 16) & 0xFF;
-       vmpartspawner.particle_color2[1] = (theme->color2 >> 8) & 0xFF;
-       vmpartspawner.particle_color2[2] = (theme->color2 >> 0) & 0xFF;
-       *vmpartspawner.particle_tex = (float)theme->tex;
-       *vmpartspawner.particle_size = theme->size;
-       *vmpartspawner.particle_sizeincrease = theme->sizeincrease;
-       *vmpartspawner.particle_alpha = theme->alpha/256;
-       *vmpartspawner.particle_alphafade = theme->alphafade/256;
-       *vmpartspawner.particle_time = theme->lifetime;
-       *vmpartspawner.particle_gravity = theme->gravity;
-       *vmpartspawner.particle_bounce = theme->bounce;
-       *vmpartspawner.particle_airfriction = theme->airfriction;
-       *vmpartspawner.particle_liquidfriction = theme->liquidfriction;
-       *vmpartspawner.particle_originjitter = theme->originjitter;
-       *vmpartspawner.particle_velocityjitter = theme->velocityjitter;
-       *vmpartspawner.particle_qualityreduction = theme->qualityreduction;
-       *vmpartspawner.particle_stretch = theme->stretch;
-       vmpartspawner.particle_staincolor1[0] = ((int)theme->staincolor1 >> 16) & 0xFF;
-       vmpartspawner.particle_staincolor1[1] = ((int)theme->staincolor1 >> 8) & 0xFF;
-       vmpartspawner.particle_staincolor1[2] = ((int)theme->staincolor1 >> 0) & 0xFF;
-       vmpartspawner.particle_staincolor2[0] = ((int)theme->staincolor2 >> 16) & 0xFF;
-       vmpartspawner.particle_staincolor2[1] = ((int)theme->staincolor2 >> 8) & 0xFF;
-       vmpartspawner.particle_staincolor2[2] = ((int)theme->staincolor2 >> 0) & 0xFF;
-       *vmpartspawner.particle_staintex = (float)theme->staintex;
-       *vmpartspawner.particle_stainalpha = (float)theme->stainalpha/256;
-       *vmpartspawner.particle_stainsize = (float)theme->stainsize;
-       *vmpartspawner.particle_delayspawn = theme->delayspawn;
-       *vmpartspawner.particle_delaycollision = theme->delaycollision;
-       *vmpartspawner.particle_angle = theme->angle;
-       *vmpartspawner.particle_spin = theme->spin;
+static void VM_CL_ParticleThemeToGlobals(vmparticletheme_t *theme, prvm_prog_t *prog)
+{
+       PRVM_clientglobalfloat(particle_type) = theme->typeindex;
+       PRVM_clientglobalfloat(particle_blendmode) = theme->blendmode;
+       PRVM_clientglobalfloat(particle_orientation) = theme->orientation;
+       // VorteX: int only can store 0-255, not 0-256 which means 0 - 0,99609375...
+       VectorSet(PRVM_clientglobalvector(particle_color1), (theme->color1 >> 16) & 0xFF, (theme->color1 >> 8) & 0xFF, (theme->color1 >> 0) & 0xFF);
+       VectorSet(PRVM_clientglobalvector(particle_color2), (theme->color2 >> 16) & 0xFF, (theme->color2 >> 8) & 0xFF, (theme->color2 >> 0) & 0xFF);
+       PRVM_clientglobalfloat(particle_tex) = (prvm_vec_t)theme->tex;
+       PRVM_clientglobalfloat(particle_size) = theme->size;
+       PRVM_clientglobalfloat(particle_sizeincrease) = theme->sizeincrease;
+       PRVM_clientglobalfloat(particle_alpha) = theme->alpha/256;
+       PRVM_clientglobalfloat(particle_alphafade) = theme->alphafade/256;
+       PRVM_clientglobalfloat(particle_time) = theme->lifetime;
+       PRVM_clientglobalfloat(particle_gravity) = theme->gravity;
+       PRVM_clientglobalfloat(particle_bounce) = theme->bounce;
+       PRVM_clientglobalfloat(particle_airfriction) = theme->airfriction;
+       PRVM_clientglobalfloat(particle_liquidfriction) = theme->liquidfriction;
+       PRVM_clientglobalfloat(particle_originjitter) = theme->originjitter;
+       PRVM_clientglobalfloat(particle_velocityjitter) = theme->velocityjitter;
+       PRVM_clientglobalfloat(particle_qualityreduction) = theme->qualityreduction;
+       PRVM_clientglobalfloat(particle_stretch) = theme->stretch;
+       VectorSet(PRVM_clientglobalvector(particle_staincolor1), ((int)theme->staincolor1 >> 16) & 0xFF, ((int)theme->staincolor1 >> 8) & 0xFF, ((int)theme->staincolor1 >> 0) & 0xFF);
+       VectorSet(PRVM_clientglobalvector(particle_staincolor2), ((int)theme->staincolor2 >> 16) & 0xFF, ((int)theme->staincolor2 >> 8) & 0xFF, ((int)theme->staincolor2 >> 0) & 0xFF);
+       PRVM_clientglobalfloat(particle_staintex) = (prvm_vec_t)theme->staintex;
+       PRVM_clientglobalfloat(particle_stainalpha) = (prvm_vec_t)theme->stainalpha/256;
+       PRVM_clientglobalfloat(particle_stainsize) = (prvm_vec_t)theme->stainsize;
+       PRVM_clientglobalfloat(particle_delayspawn) = theme->delayspawn;
+       PRVM_clientglobalfloat(particle_delaycollision) = theme->delaycollision;
+       PRVM_clientglobalfloat(particle_angle) = theme->angle;
+       PRVM_clientglobalfloat(particle_spin) = theme->spin;
 }
 
 // QC globals ->  particle theme
-static void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme)
-{
-       theme->typeindex = (unsigned short)*vmpartspawner.particle_type;
-       theme->blendmode = (pblend_t)(int)*vmpartspawner.particle_blendmode;
-       theme->orientation = (porientation_t)(int)*vmpartspawner.particle_orientation;
-       theme->color1 = ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]);
-       theme->color2 = ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]);
-       theme->tex = (int)*vmpartspawner.particle_tex;
-       theme->size = *vmpartspawner.particle_size;
-       theme->sizeincrease = *vmpartspawner.particle_sizeincrease;
-       theme->alpha = *vmpartspawner.particle_alpha*256;
-       theme->alphafade = *vmpartspawner.particle_alphafade*256;
-       theme->lifetime = *vmpartspawner.particle_time;
-       theme->gravity = *vmpartspawner.particle_gravity;
-       theme->bounce = *vmpartspawner.particle_bounce;
-       theme->airfriction = *vmpartspawner.particle_airfriction;
-       theme->liquidfriction = *vmpartspawner.particle_liquidfriction;
-       theme->originjitter = *vmpartspawner.particle_originjitter;
-       theme->velocityjitter = *vmpartspawner.particle_velocityjitter;
-       theme->qualityreduction = (*vmpartspawner.particle_qualityreduction) ? true : false;
-       theme->stretch = *vmpartspawner.particle_stretch;
-       theme->staincolor1 = ((int)vmpartspawner.particle_staincolor1[0])*65536 + (int)(vmpartspawner.particle_staincolor1[1])*256 + (int)(vmpartspawner.particle_staincolor1[2]);
-       theme->staincolor2 = (int)(vmpartspawner.particle_staincolor2[0])*65536 + (int)(vmpartspawner.particle_staincolor2[1])*256 + (int)(vmpartspawner.particle_staincolor2[2]);
-       theme->staintex =(int)*vmpartspawner.particle_staintex;
-       theme->stainalpha = *vmpartspawner.particle_stainalpha*256;
-       theme->stainsize = *vmpartspawner.particle_stainsize;
-       theme->delayspawn = *vmpartspawner.particle_delayspawn;
-       theme->delaycollision = *vmpartspawner.particle_delaycollision;
-       theme->angle = *vmpartspawner.particle_angle;
-       theme->spin = *vmpartspawner.particle_spin;
+static void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme, prvm_prog_t *prog)
+{
+       theme->typeindex = (unsigned short)PRVM_clientglobalfloat(particle_type);
+       theme->blendmode = (pblend_t)(int)PRVM_clientglobalfloat(particle_blendmode);
+       theme->orientation = (porientation_t)(int)PRVM_clientglobalfloat(particle_orientation);
+       theme->color1 = ((int)PRVM_clientglobalvector(particle_color1)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color1)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color1)[2]);
+       theme->color2 = ((int)PRVM_clientglobalvector(particle_color2)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color2)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color2)[2]);
+       theme->tex = (int)PRVM_clientglobalfloat(particle_tex);
+       theme->size = PRVM_clientglobalfloat(particle_size);
+       theme->sizeincrease = PRVM_clientglobalfloat(particle_sizeincrease);
+       theme->alpha = PRVM_clientglobalfloat(particle_alpha)*256;
+       theme->alphafade = PRVM_clientglobalfloat(particle_alphafade)*256;
+       theme->lifetime = PRVM_clientglobalfloat(particle_time);
+       theme->gravity = PRVM_clientglobalfloat(particle_gravity);
+       theme->bounce = PRVM_clientglobalfloat(particle_bounce);
+       theme->airfriction = PRVM_clientglobalfloat(particle_airfriction);
+       theme->liquidfriction = PRVM_clientglobalfloat(particle_liquidfriction);
+       theme->originjitter = PRVM_clientglobalfloat(particle_originjitter);
+       theme->velocityjitter = PRVM_clientglobalfloat(particle_velocityjitter);
+       theme->qualityreduction = PRVM_clientglobalfloat(particle_qualityreduction) != 0 ? true : false;
+       theme->stretch = PRVM_clientglobalfloat(particle_stretch);
+       theme->staincolor1 = ((int)PRVM_clientglobalvector(particle_staincolor1)[0])*65536 + (int)(PRVM_clientglobalvector(particle_staincolor1)[1])*256 + (int)(PRVM_clientglobalvector(particle_staincolor1)[2]);
+       theme->staincolor2 = (int)(PRVM_clientglobalvector(particle_staincolor2)[0])*65536 + (int)(PRVM_clientglobalvector(particle_staincolor2)[1])*256 + (int)(PRVM_clientglobalvector(particle_staincolor2)[2]);
+       theme->staintex =(int)PRVM_clientglobalfloat(particle_staintex);
+       theme->stainalpha = PRVM_clientglobalfloat(particle_stainalpha)*256;
+       theme->stainsize = PRVM_clientglobalfloat(particle_stainsize);
+       theme->delayspawn = PRVM_clientglobalfloat(particle_delayspawn);
+       theme->delaycollision = PRVM_clientglobalfloat(particle_delaycollision);
+       theme->angle = PRVM_clientglobalfloat(particle_angle);
+       theme->spin = PRVM_clientglobalfloat(particle_spin);
 }
 
 // init particle spawner interface
@@ -2780,7 +2814,7 @@ static void VM_CL_ResetParticle (prvm_prog_t *prog)
                VM_Warning(prog, "VM_CL_ResetParticle: particle spawner not initialized\n");
                return;
        }
-       VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
+       VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0], prog);
 }
 
 // void(float themenum) particletheme
@@ -2798,17 +2832,17 @@ static void VM_CL_ParticleTheme (prvm_prog_t *prog)
        if (themenum < 0 || themenum >= vmpartspawner.max_themes)
        {
                VM_Warning(prog, "VM_CL_ParticleTheme: bad theme number %i\n", themenum);
-               VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
+               VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0], prog);
                return;
        }
        if (vmpartspawner.themes[themenum].initialized == false)
        {
                VM_Warning(prog, "VM_CL_ParticleTheme: theme #%i not exists\n", themenum);
-               VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
+               VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0], prog);
                return;
        }
        // load particle theme into globals
-       VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[themenum]);
+       VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[themenum], prog);
 }
 
 // float() saveparticletheme
@@ -2839,7 +2873,7 @@ static void VM_CL_ParticleThemeSave (prvm_prog_t *prog)
                        return;
                }
                vmpartspawner.themes[themenum].initialized = true;
-               VM_CL_ParticleThemeFromGlobals(&vmpartspawner.themes[themenum]);
+               VM_CL_ParticleThemeFromGlobals(&vmpartspawner.themes[themenum], prog);
                PRVM_G_FLOAT(OFS_RETURN) = themenum;
                return;
        }
@@ -2851,7 +2885,7 @@ static void VM_CL_ParticleThemeSave (prvm_prog_t *prog)
                return;
        }
        vmpartspawner.themes[themenum].initialized = true;
-       VM_CL_ParticleThemeFromGlobals(&vmpartspawner.themes[themenum]);
+       VM_CL_ParticleThemeFromGlobals(&vmpartspawner.themes[themenum], prog);
 }
 
 // void(float themenum) freeparticletheme
@@ -2875,7 +2909,7 @@ static void VM_CL_ParticleThemeFree (prvm_prog_t *prog)
        if (vmpartspawner.themes[themenum].initialized == false)
        {
                VM_Warning(prog, "VM_CL_ParticleThemeFree: theme #%i already freed\n", themenum);
-               VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0]);
+               VM_CL_ParticleThemeToGlobals(&vmpartspawner.themes[0], prog);
                return;
        }
        // free theme
@@ -2887,7 +2921,7 @@ static void VM_CL_ParticleThemeFree (prvm_prog_t *prog)
 // returns 0 if failed, 1 if succesful
 static void VM_CL_SpawnParticle (prvm_prog_t *prog)
 {
-       float *org, *dir;
+       vec3_t org, dir;
        vmparticletheme_t *theme;
        particle_t *part;
        int themenum;
@@ -2899,21 +2933,54 @@ static void VM_CL_SpawnParticle (prvm_prog_t *prog)
                PRVM_G_FLOAT(OFS_RETURN) = 0; 
                return;
        }
-       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);
        
        if (prog->argc < 3) // global-set particle
        {
-               part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)(vmpartspawner.particle_color1[0]) << 16) + ((int)(vmpartspawner.particle_color1[1]) << 8) + ((int)(vmpartspawner.particle_color1[2])), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)(int)*vmpartspawner.particle_blendmode, (porientation_t)(int)*vmpartspawner.particle_orientation, (int)(vmpartspawner.particle_staincolor1[0])*65536 + (int)(vmpartspawner.particle_staincolor1[1])*256 + (int)(vmpartspawner.particle_staincolor1[2]), (int)(vmpartspawner.particle_staincolor2[0])*65536 + (int)(vmpartspawner.particle_staincolor2[1])*256 + (int)(vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
+               part = CL_NewParticle(org,
+                       (unsigned short)PRVM_clientglobalfloat(particle_type),
+                       ((int)PRVM_clientglobalvector(particle_color1)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color1)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color1)[2]),
+                       ((int)PRVM_clientglobalvector(particle_color2)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color2)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color2)[2]),
+                       (int)PRVM_clientglobalfloat(particle_tex),
+                       PRVM_clientglobalfloat(particle_size),
+                       PRVM_clientglobalfloat(particle_sizeincrease),
+                       PRVM_clientglobalfloat(particle_alpha)*256,
+                       PRVM_clientglobalfloat(particle_alphafade)*256,
+                       PRVM_clientglobalfloat(particle_gravity),
+                       PRVM_clientglobalfloat(particle_bounce),
+                       org[0],
+                       org[1],
+                       org[2],
+                       dir[0],
+                       dir[1],
+                       dir[2],
+                       PRVM_clientglobalfloat(particle_airfriction),
+                       PRVM_clientglobalfloat(particle_liquidfriction),
+                       PRVM_clientglobalfloat(particle_originjitter),
+                       PRVM_clientglobalfloat(particle_velocityjitter),
+                       (PRVM_clientglobalfloat(particle_qualityreduction)) ? true : false,
+                       PRVM_clientglobalfloat(particle_time),
+                       PRVM_clientglobalfloat(particle_stretch),
+                       (pblend_t)(int)PRVM_clientglobalfloat(particle_blendmode),
+                       (porientation_t)(int)PRVM_clientglobalfloat(particle_orientation),
+                       (int)(PRVM_clientglobalvector(particle_staincolor1)[0])*65536 + (int)(PRVM_clientglobalvector(particle_staincolor1)[1])*256 + (int)(PRVM_clientglobalvector(particle_staincolor1)[2]),
+                       (int)(PRVM_clientglobalvector(particle_staincolor2)[0])*65536 + (int)(PRVM_clientglobalvector(particle_staincolor2)[1])*256 + (int)(PRVM_clientglobalvector(particle_staincolor2)[2]),
+                       (int)PRVM_clientglobalfloat(particle_staintex),
+                       PRVM_clientglobalfloat(particle_stainalpha)*256,
+                       PRVM_clientglobalfloat(particle_stainsize),
+                       PRVM_clientglobalfloat(particle_angle),
+                       PRVM_clientglobalfloat(particle_spin),
+                       NULL);
                if (!part)
                {
                        PRVM_G_FLOAT(OFS_RETURN) = 0; 
                        return;
                }
-               if (*vmpartspawner.particle_delayspawn)
-                       part->delayedspawn = cl.time + *vmpartspawner.particle_delayspawn;
-               //if (*vmpartspawner.particle_delaycollision)
-               //      part->delayedcollisions = cl.time + *vmpartspawner.particle_delaycollision;
+               if (PRVM_clientglobalfloat(particle_delayspawn))
+                       part->delayedspawn = cl.time + PRVM_clientglobalfloat(particle_delayspawn);
+               //if (PRVM_clientglobalfloat(particle_delaycollision))
+               //      part->delayedcollisions = cl.time + PRVM_clientglobalfloat(particle_delaycollision);
        }
        else // quick themed particle
        {
@@ -2925,7 +2992,40 @@ static void VM_CL_SpawnParticle (prvm_prog_t *prog)
                        return;
                }
                theme = &vmpartspawner.themes[themenum];
-               part = CL_NewParticle(org, theme->typeindex, theme->color1, theme->color2, theme->tex, theme->size, theme->sizeincrease, theme->alpha, theme->alphafade, theme->gravity, theme->bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], theme->airfriction, theme->liquidfriction, theme->originjitter, theme->velocityjitter, theme->qualityreduction, theme->lifetime, theme->stretch, theme->blendmode, theme->orientation, theme->staincolor1, theme->staincolor2, theme->staintex, theme->stainalpha, theme->stainsize, theme->angle, theme->spin, NULL);
+               part = CL_NewParticle(org,
+                       theme->typeindex,
+                       theme->color1,
+                       theme->color2,
+                       theme->tex,
+                       theme->size,
+                       theme->sizeincrease,
+                       theme->alpha,
+                       theme->alphafade,
+                       theme->gravity,
+                       theme->bounce,
+                       org[0],
+                       org[1],
+                       org[2],
+                       dir[0],
+                       dir[1],
+                       dir[2],
+                       theme->airfriction,
+                       theme->liquidfriction,
+                       theme->originjitter,
+                       theme->velocityjitter,
+                       theme->qualityreduction,
+                       theme->lifetime,
+                       theme->stretch,
+                       theme->blendmode,
+                       theme->orientation,
+                       theme->staincolor1,
+                       theme->staincolor2,
+                       theme->staintex,
+                       theme->stainalpha,
+                       theme->stainsize,
+                       theme->angle,
+                       theme->spin,
+                       NULL);
                if (!part)
                {
                        PRVM_G_FLOAT(OFS_RETURN) = 0; 
@@ -2943,7 +3043,7 @@ static void VM_CL_SpawnParticle (prvm_prog_t *prog)
 // returns 0 if failed, 1 if success
 static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog)
 {
-       float *org, *dir;
+       vec3_t org, dir;
        vmparticletheme_t *theme;
        particle_t *part;
        int themenum;
@@ -2955,10 +3055,43 @@ static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog)
                PRVM_G_FLOAT(OFS_RETURN) = 0; 
                return;
        }
-       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);
        if (prog->argc < 5) // global-set particle
-               part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)(int)*vmpartspawner.particle_blendmode, (porientation_t)(int)*vmpartspawner.particle_orientation, ((int)vmpartspawner.particle_staincolor1[0] << 16) + ((int)vmpartspawner.particle_staincolor1[1] << 8) + ((int)vmpartspawner.particle_staincolor1[2]), ((int)vmpartspawner.particle_staincolor2[0] << 16) + ((int)vmpartspawner.particle_staincolor2[1] << 8) + ((int)vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
+               part = CL_NewParticle(org,
+                       (unsigned short)PRVM_clientglobalfloat(particle_type),
+                       ((int)PRVM_clientglobalvector(particle_color1)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color1)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color1)[2]),
+                       ((int)PRVM_clientglobalvector(particle_color2)[0] << 16) + ((int)PRVM_clientglobalvector(particle_color2)[1] << 8) + ((int)PRVM_clientglobalvector(particle_color2)[2]),
+                       (int)PRVM_clientglobalfloat(particle_tex),
+                       PRVM_clientglobalfloat(particle_size),
+                       PRVM_clientglobalfloat(particle_sizeincrease),
+                       PRVM_clientglobalfloat(particle_alpha)*256,
+                       PRVM_clientglobalfloat(particle_alphafade)*256,
+                       PRVM_clientglobalfloat(particle_gravity),
+                       PRVM_clientglobalfloat(particle_bounce),
+                       org[0],
+                       org[1],
+                       org[2],
+                       dir[0],
+                       dir[1],
+                       dir[2],
+                       PRVM_clientglobalfloat(particle_airfriction),
+                       PRVM_clientglobalfloat(particle_liquidfriction),
+                       PRVM_clientglobalfloat(particle_originjitter),
+                       PRVM_clientglobalfloat(particle_velocityjitter),
+                       (PRVM_clientglobalfloat(particle_qualityreduction)) ? true : false,
+                       PRVM_clientglobalfloat(particle_time),
+                       PRVM_clientglobalfloat(particle_stretch),
+                       (pblend_t)(int)PRVM_clientglobalfloat(particle_blendmode),
+                       (porientation_t)(int)PRVM_clientglobalfloat(particle_orientation),
+                       ((int)PRVM_clientglobalvector(particle_staincolor1)[0] << 16) + ((int)PRVM_clientglobalvector(particle_staincolor1)[1] << 8) + ((int)PRVM_clientglobalvector(particle_staincolor1)[2]),
+                       ((int)PRVM_clientglobalvector(particle_staincolor2)[0] << 16) + ((int)PRVM_clientglobalvector(particle_staincolor2)[1] << 8) + ((int)PRVM_clientglobalvector(particle_staincolor2)[2]),
+                       (int)PRVM_clientglobalfloat(particle_staintex),
+                       PRVM_clientglobalfloat(particle_stainalpha)*256,
+                       PRVM_clientglobalfloat(particle_stainsize),
+                       PRVM_clientglobalfloat(particle_angle),
+                       PRVM_clientglobalfloat(particle_spin),
+                       NULL);
        else // themed particle
        {
                themenum = (int)PRVM_G_FLOAT(OFS_PARM4);
@@ -2969,7 +3102,40 @@ static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog)
                        return;
                }
                theme = &vmpartspawner.themes[themenum];
-               part = CL_NewParticle(org, theme->typeindex, theme->color1, theme->color2, theme->tex, theme->size, theme->sizeincrease, theme->alpha, theme->alphafade, theme->gravity, theme->bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], theme->airfriction, theme->liquidfriction, theme->originjitter, theme->velocityjitter, theme->qualityreduction, theme->lifetime, theme->stretch, theme->blendmode, theme->orientation, theme->staincolor1, theme->staincolor2, theme->staintex, theme->stainalpha, theme->stainsize, theme->angle, theme->spin, NULL);
+               part = CL_NewParticle(org,
+                       theme->typeindex,
+                       theme->color1,
+                       theme->color2,
+                       theme->tex,
+                       theme->size,
+                       theme->sizeincrease,
+                       theme->alpha,
+                       theme->alphafade,
+                       theme->gravity,
+                       theme->bounce,
+                       org[0],
+                       org[1],
+                       org[2],
+                       dir[0],
+                       dir[1],
+                       dir[2],
+                       theme->airfriction,
+                       theme->liquidfriction,
+                       theme->originjitter,
+                       theme->velocityjitter,
+                       theme->qualityreduction,
+                       theme->lifetime,
+                       theme->stretch,
+                       theme->blendmode,
+                       theme->orientation,
+                       theme->staincolor1,
+                       theme->staincolor2,
+                       theme->staintex,
+                       theme->stainalpha,
+                       theme->stainsize,
+                       theme->angle,
+                       theme->spin,
+                       NULL);
        }
        if (!part) 
        { 
@@ -2992,7 +3158,7 @@ static void VM_CL_SpawnParticleDelayed (prvm_prog_t *prog)
 static void VM_CL_GetEntity (prvm_prog_t *prog)
 {
        int entnum, fieldnum;
-       float org[3], v1[3], v2[3];
+       vec3_t forward, left, up, org;
        VM_SAFEPARMCOUNT(2, VM_CL_GetEntityVec);
 
        entnum = PRVM_G_FLOAT(OFS_PARM0);
@@ -3008,22 +3174,30 @@ static void VM_CL_GetEntity (prvm_prog_t *prog)
                        PRVM_G_FLOAT(OFS_RETURN) = cl.entities_active[entnum];
                        break;
                case 1: // origin
-                       Matrix4x4_OriginFromMatrix(&cl.entities[entnum].render.matrix, PRVM_G_VECTOR(OFS_RETURN));
+                       Matrix4x4_OriginFromMatrix(&cl.entities[entnum].render.matrix, org);
+                       VectorCopy(org, PRVM_G_VECTOR(OFS_RETURN));
                        break; 
                case 2: // forward
-                       Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, PRVM_G_VECTOR(OFS_RETURN), v1, v2, org);        
+                       Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org);
+                       VectorCopy(forward, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                case 3: // right
-                       Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, v1, PRVM_G_VECTOR(OFS_RETURN), v2, org);        
+                       Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org);
+                       VectorNegate(left, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                case 4: // up
-                       Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, v1, v2, PRVM_G_VECTOR(OFS_RETURN), org);        
+                       Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org);
+                       VectorCopy(up, PRVM_G_VECTOR(OFS_RETURN));
                        break;
                case 5: // scale
                        PRVM_G_FLOAT(OFS_RETURN) = Matrix4x4_ScaleFromMatrix(&cl.entities[entnum].render.matrix);
                        break;  
                case 6: // origin + v_forward, v_right, v_up
-                       Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, PRVM_clientglobalvector(v_forward), PRVM_clientglobalvector(v_right), PRVM_clientglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));        
+                       Matrix4x4_ToVectors(&cl.entities[entnum].render.matrix, forward, left, up, org);
+                       VectorCopy(forward, PRVM_clientglobalvector(v_forward));
+                       VectorNegate(left, PRVM_clientglobalvector(v_right));
+                       VectorCopy(up, PRVM_clientglobalvector(v_up));
+                       VectorCopy(org, PRVM_G_VECTOR(OFS_RETURN));
                        break;  
                case 7: // alpha
                        PRVM_G_FLOAT(OFS_RETURN) = cl.entities[entnum].render.alpha;
@@ -3502,11 +3676,14 @@ static qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qb
        prvm_prog_t *prog = CLVM_prog;
        float           dz;
        vec3_t          oldorg, neworg, end, traceendpos;
+       vec3_t          mins, maxs, start;
        trace_t         trace;
        int                     i, svent;
        prvm_edict_t            *enemy;
 
 // try the move
+       VectorCopy(PRVM_clientedictvector(ent, mins), mins);
+       VectorCopy(PRVM_clientedictvector(ent, maxs), maxs);
        VectorCopy (PRVM_clientedictvector(ent, origin), oldorg);
        VectorAdd (PRVM_clientedictvector(ent, origin), move, neworg);
 
@@ -3526,7 +3703,8 @@ static qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qb
                                if (dz < 30)
                                        neworg[2] += 8;
                        }
-                       trace = CL_TraceBox(PRVM_clientedictvector(ent, origin), PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), neworg, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
+                       VectorCopy(PRVM_clientedictvector(ent, origin), start);
+                       trace = CL_TraceBox(start, mins, maxs, neworg, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
                        if (settrace)
                                CL_VM_SetTraceGlobals(prog, &trace, svent);
 
@@ -3554,14 +3732,14 @@ static qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qb
        VectorCopy (neworg, end);
        end[2] -= sv_stepheight.value*2;
 
-       trace = CL_TraceBox(neworg, PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
+       trace = CL_TraceBox(neworg, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
        if (settrace)
                CL_VM_SetTraceGlobals(prog, &trace, svent);
 
        if (trace.startsolid)
        {
                neworg[2] -= sv_stepheight.value;
-               trace = CL_TraceBox(neworg, PRVM_clientedictvector(ent, mins), PRVM_clientedictvector(ent, maxs), end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
+               trace = CL_TraceBox(neworg, mins, maxs, end, MOVE_NORMAL, ent, CL_GenericHitSuperContentsMask(ent), true, true, &svent, true);
                if (settrace)
                        CL_VM_SetTraceGlobals(prog, &trace, svent);
                if (trace.startsolid)
@@ -3718,36 +3896,36 @@ static void VM_CL_checkpvs (prvm_prog_t *prog)
        VectorAdd(PRVM_serveredictvector(viewee, origin), PRVM_serveredictvector(viewee, maxs), ma);
 
 #if 1
-       if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+       if(!cl.worldmodel || !cl.worldmodel->brush.GetPVS || !cl.worldmodel->brush.BoxTouchingPVS)
        {
                // no PVS support on this worldmodel... darn
                PRVM_G_FLOAT(OFS_RETURN) = 3;
                return;
        }
-       pvs = sv.worldmodel->brush.GetPVS(sv.worldmodel, viewpos);
+       pvs = cl.worldmodel->brush.GetPVS(cl.worldmodel, viewpos);
        if(!pvs)
        {
                // viewpos isn't in any PVS... darn
                PRVM_G_FLOAT(OFS_RETURN) = 2;
                return;
        }
-       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, mi, ma);
+       PRVM_G_FLOAT(OFS_RETURN) = cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, pvs, mi, ma);
 #else
        // using fat PVS like FTEQW does (slow)
-       if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+       if(!cl.worldmodel || !cl.worldmodel->brush.FatPVS || !cl.worldmodel->brush.BoxTouchingPVS)
        {
                // no PVS support on this worldmodel... darn
                PRVM_G_FLOAT(OFS_RETURN) = 3;
                return;
        }
-       fatpvsbytes = sv.worldmodel->brush.FatPVS(sv.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
+       fatpvsbytes = cl.worldmodel->brush.FatPVS(cl.worldmodel, viewpos, 8, fatpvs, sizeof(fatpvs), false);
        if(!fatpvsbytes)
        {
                // viewpos isn't in any PVS... darn
                PRVM_G_FLOAT(OFS_RETURN) = 2;
                return;
        }
-       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, mi, ma);
+       PRVM_G_FLOAT(OFS_RETURN) = cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, fatpvs, mi, ma);
 #endif
 }
 
@@ -3801,7 +3979,7 @@ static void VM_CL_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, cl.time);
        blendfrac = 1.0f - retainfrac;
        for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
                frameblend[numblends].lerp *= blendfrac;
@@ -3811,7 +3989,7 @@ static void VM_CL_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;
@@ -4090,9 +4268,10 @@ static void VM_CL_RotateMoves(prvm_prog_t *prog)
     */
        matrix4x4_t m;
        vec3_t v = {0, 0, 0};
-       vec3_t x, y, z;
+       vec3_t a, x, y, z;
        VM_SAFEPARMCOUNT(1, VM_CL_RotateMoves);
-       AngleVectorsFLU(PRVM_G_VECTOR(OFS_PARM0), x, y, z);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), a);
+       AngleVectorsFLU(a, x, y, z);
        Matrix4x4_FromVectors(&m, x, y, z, v);
        CL_RotateMoves(&m);
 }
@@ -4107,6 +4286,47 @@ static void VM_CL_loadcubemap(prvm_prog_t *prog)
        R_GetCubemap(name);
 }
 
+#define REFDEFFLAG_TELEPORTED 1
+#define REFDEFFLAG_JUMPING 2
+#define REFDEFFLAG_DEAD 4
+#define REFDEFFLAG_INTERMISSION 8
+static void VM_CL_V_CalcRefdef(prvm_prog_t *prog)
+{
+       matrix4x4_t entrendermatrix;
+       vec3_t clviewangles;
+       vec3_t clvelocity;
+       qboolean teleported;
+       qboolean clonground;
+       qboolean clcmdjump;
+       qboolean cldead;
+       qboolean clintermission;
+       float clstatsviewheight;
+       prvm_edict_t *ent;
+       int flags;
+
+       VM_SAFEPARMCOUNT(2, VM_CL_V_CalcRefdef);
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       flags = PRVM_G_FLOAT(OFS_PARM1);
+
+       // use the CL_GetTagMatrix function on self to ensure consistent behavior (duplicate code would be bad)
+       CL_GetTagMatrix(prog, &entrendermatrix, ent, 0);
+
+       VectorCopy(cl.csqc_viewangles, clviewangles);
+       teleported = (flags & REFDEFFLAG_TELEPORTED) != 0;
+       clonground = ((int)PRVM_clientedictfloat(ent, pmove_flags) & PMF_ONGROUND) != 0;
+       clcmdjump = (flags & REFDEFFLAG_JUMPING) != 0;
+       clstatsviewheight = PRVM_clientedictvector(ent, view_ofs)[2];
+       cldead = (flags & REFDEFFLAG_DEAD) != 0;
+       clintermission = (flags & REFDEFFLAG_INTERMISSION) != 0;
+       VectorCopy(PRVM_clientedictvector(ent, velocity), clvelocity);
+
+       V_CalcRefdefUsing(&entrendermatrix, clviewangles, teleported, clonground, clcmdjump, clstatsviewheight, cldead, clintermission, clvelocity);
+
+       VectorCopy(cl.csqc_vieworiginfromengine, cl.csqc_vieworigin);
+       VectorCopy(cl.csqc_viewanglesfromengine, cl.csqc_viewangles);
+       CSQC_R_RecalcView();
+}
+
 //============================================================================
 
 // To create a almost working builtin file from this replace:
@@ -4656,10 +4876,10 @@ VM_CL_setpause,                                 // #531 float(float ispaused) setpause = #531 (DP_CSQC_SETPA
 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)
@@ -4761,7 +4981,8 @@ NULL,                                                     // #636
 NULL,                                                  // #637
 VM_CL_RotateMoves,                                     // #638
 VM_digest_hex,                                         // #639
-NULL,                                                  // #640
+VM_CL_V_CalcRefdef,                                    // #640 void(entity e) V_CalcRefdef (DP_CSQC_V_CALCREFDEF)
+NULL,                                                  // #641
 };
 
 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);