removed NULL checks for PRVM_EDICTFIELDVALUE/GLOBALFIELDVALUE
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 8 May 2011 18:34:47 +0000 (18:34 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 8 May 2011 18:34:47 +0000 (18:34 +0000)
added PRVM_EDICTFIELDFLOAT/VECTOR/STRING/EDICT/FUNCTION variants
added PRVM_GLOBALFIELDFLOAT/VECTOR/STRING/EDICT/FUNCTION variants
this should improve performance slightly, and make code audits easier
updated required fields lists, added required globals lists

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11128 d7cf8633-e32d-0410-b094-e92efae38249

20 files changed:
cl_collision.c
clvm_cmds.c
csprogs.c
cvar.c
host_cmd.c
mvm_cmds.c
pr_comp.h
progsvm.h
protocol.c
prvm_cmds.c
prvm_edict.c
prvm_exec.c
prvm_execprogram.h
sv_demo.c
sv_main.c
sv_phys.c
sv_user.c
svvm_cmds.c
todo
world.c

index 93ba659..7998953 100644 (file)
@@ -197,12 +197,11 @@ void CL_LinkEdict(prvm_edict_t *ent)
 
 int CL_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
 {
-       prvm_eval_t *val;
        if (passedict)
        {
-               val = PRVM_EDICTFIELDVALUE(passedict, prog->fieldoffsets.dphitcontentsmask);
-               if (val && val->_float)
-                       return (int)val->_float;
+               int dphitcontentsmask = (int)PRVM_EDICTFIELDFLOAT(passedict, prog->fieldoffsets.dphitcontentsmask);
+               if (dphitcontentsmask)
+                       return dphitcontentsmask;
                else if (passedict->fields.client->solid == SOLID_SLIDEBOX)
                {
                        if ((int)passedict->fields.client->flags & FL_MONSTER)
index 98c3426..87ee706 100644 (file)
@@ -234,10 +234,8 @@ static void VM_CL_spawn (void)
 
 void CL_VM_SetTraceGlobals(const trace_t *trace, int svent)
 {
-       prvm_eval_t *val;
        VM_SetTraceGlobals(trace);
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_networkentity)))
-               val->_float = svent;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_networkentity) = svent;
 }
 
 #define CL_HitNetworkBrushModels(move) !((move) == MOVE_WORLDONLY)
@@ -320,7 +318,6 @@ trace_t CL_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore, int *svent)
        vec3_t original_velocity;
        vec3_t original_angles;
        vec3_t original_avelocity;
-       prvm_eval_t *val;
        trace_t trace;
 
        VectorCopy(tossent->fields.client->origin   , original_origin   );
@@ -328,11 +325,9 @@ trace_t CL_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore, int *svent)
        VectorCopy(tossent->fields.client->angles   , original_angles   );
        VectorCopy(tossent->fields.client->avelocity, original_avelocity);
 
-       val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
-       if (val != NULL && val->_float != 0)
-               gravity = val->_float;
-       else
-               gravity = 1.0;
+       gravity = PRVM_EDICTFIELDFLOAT(tossent, prog->fieldoffsets.gravity);
+       if (!gravity)
+               gravity = 1.0f;
        gravity *= cl.movevars_gravity * 0.05;
 
        for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
@@ -493,7 +488,7 @@ static void VM_CL_findradius (void)
                        VectorMAMAM(1, eorg, -0.5f, ent->fields.client->mins, -0.5f, ent->fields.client->maxs, eorg);
                if (DotProduct(eorg, eorg) < radius2)
                {
-                       PRVM_EDICTFIELDVALUE(ent, chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
+                       PRVM_EDICTFIELDEDICT(ent, chainfield) = PRVM_EDICT_TO_PROG(chain);
                        chain = ent;
                }
        }
@@ -505,7 +500,6 @@ static void VM_CL_findradius (void)
 static void VM_CL_droptofloor (void)
 {
        prvm_edict_t            *ent;
-       prvm_eval_t                     *val;
        vec3_t                          end;
        trace_t                         trace;
 
@@ -535,8 +529,7 @@ static void VM_CL_droptofloor (void)
        {
                VectorCopy (trace.endpos, ent->fields.client->origin);
                ent->fields.client->flags = (int)ent->fields.client->flags | FL_ONGROUND;
-               if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.groundentity)))
-                       val->edict = PRVM_EDICT_TO_PROG(trace.ent);
+               PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.groundentity) = PRVM_EDICT_TO_PROG(trace.ent);
                PRVM_G_FLOAT(OFS_RETURN) = 1;
                // if support is destroyed, keep suspended (gross hack for floating items in various maps)
 //             ent->priv.server->suspendedinairflag = true;
@@ -1266,7 +1259,6 @@ static void VM_CL_boxparticles (void)
        float count;
        int flags;
        float tintmins[4], tintmaxs[4];
-       prvm_eval_t *val;
        VM_SAFEPARMCOUNTRANGE(7, 8, VM_CL_boxparticles);
 
        effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
@@ -1284,17 +1276,13 @@ static void VM_CL_boxparticles (void)
        Vector4Set(tintmaxs, 1, 1, 1, 1);
        if(flags & 1) // read alpha
        {
-               if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.particles_alphamin)))
-                       tintmins[3] = val->_float;
-               if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.particles_alphamax)))
-                       tintmaxs[3] = val->_float;
+               tintmins[3] = PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.particles_alphamin);
+               tintmaxs[3] = PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.particles_alphamax);
        }
        if(flags & 2) // read color
        {
-               if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.particles_colormin)))
-                       VectorCopy(val->vector, tintmins);
-               if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.particles_colormax)))
-                       VectorCopy(val->vector, tintmaxs);
+               VectorCopy(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.particles_colormin), tintmins);
+               VectorCopy(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.particles_colormax), tintmaxs);
        }
        if (effectnum < 0)
                return;
@@ -1586,7 +1574,6 @@ static void VM_CL_makestatic (void)
        if (cl.num_static_entities < cl.max_static_entities)
        {
                int renderflags;
-               prvm_eval_t *val;
                entity_t *staticent = &cl.static_entities[cl.num_static_entities++];
 
                // copy it to the current state
@@ -1598,19 +1585,22 @@ static void VM_CL_makestatic (void)
                staticent->render.framegroupblend[0].start = lhrandom(-10, -1);
                staticent->render.skinnum = (int)ent->fields.client->skin;
                staticent->render.effects = (int)ent->fields.client->effects;
-               staticent->render.alpha = 1;
-               if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.alpha)) && val->_float) staticent->render.alpha = val->_float;
-               staticent->render.scale = 1;
-               if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)) && val->_float) staticent->render.scale = val->_float;
-               if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, staticent->render.colormod);
-               if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.glowmod)) && VectorLength2(val->vector)) VectorCopy(val->vector, staticent->render.glowmod);
+               staticent->render.alpha = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.alpha);
+               staticent->render.scale = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.scale);
+               VectorCopy(PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.colormod), staticent->render.colormod);
+               VectorCopy(PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.glowmod), staticent->render.glowmod);
+
+               // sanitize values
+               if (!staticent->render.alpha)
+                       staticent->render.alpha = 1.0f;
+               if (!staticent->render.scale)
+                       staticent->render.scale = 1.0f;
                if (!VectorLength2(staticent->render.colormod))
                        VectorSet(staticent->render.colormod, 1, 1, 1);
                if (!VectorLength2(staticent->render.glowmod))
                        VectorSet(staticent->render.glowmod, 1, 1, 1);
 
-               renderflags = 0;
-               if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && val->_float) renderflags = (int)val->_float;
+               renderflags = (int)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.renderflags);
                if (renderflags & RF_USEAXIS)
                {
                        vec3_t left;
@@ -1686,7 +1676,7 @@ static void VM_CL_copyentity (void)
                VM_Warning("copyentity: can not modify free entity\n");
                return;
        }
-       memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
+       memcpy(out->fields.vp, in->fields.vp, prog->entityfields * 4);
        CL_LinkEdict(out);
 }
 
@@ -2100,8 +2090,8 @@ void VM_CL_setattachment (void)
        prvm_edict_t *e;
        prvm_edict_t *tagentity;
        const char *tagname;
-       prvm_eval_t *v;
        int modelindex;
+       int tagindex;
        dp_model_t *model;
        VM_SAFEPARMCOUNT(3, VM_CL_setattachment);
 
@@ -2123,26 +2113,23 @@ void VM_CL_setattachment (void)
        if (tagentity == NULL)
                tagentity = prog->edicts;
 
-       v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
-       if (v)
-               v->edict = PRVM_EDICT_TO_PROG(tagentity);
-
-       v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
-       if (v)
-               v->_float = 0;
+       tagindex = 0;
        if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
        {
                modelindex = (int)tagentity->fields.client->modelindex;
                model = CL_GetModelByIndex(modelindex);
                if (model)
                {
-                       v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.client->skin, tagname);
-                       if (v->_float == 0)
+                       tagindex = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.client->skin, tagname);
+                       if (tagindex == 0)
                                Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name);
                }
                else
                        Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity));
        }
+
+       PRVM_EDICTFIELDEDICT(e, prog->fieldoffsets.tag_entity) = PRVM_EDICT_TO_PROG(tagentity);
+       PRVM_EDICTFIELDFLOAT(e, prog->fieldoffsets.tag_index) = tagindex;
 }
 
 /////////////////////////////////////////
@@ -2191,18 +2178,16 @@ int CL_GetPitchSign(prvm_edict_t *ent)
 
 void CL_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
 {
-       prvm_eval_t *val;
        float scale;
        float pitchsign = 1;
 
-       scale = 1;
-       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
-       if (val && val->_float != 0)
-               scale = val->_float;
+       scale = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.scale);
+       if (!scale)
+               scale = 1.0f;
 
        if(viewmatrix)
                *out = r_refdef.view.matrix;
-       else if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && ((int)val->_float & RF_USEAXIS))
+       else if ((int)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.renderflags) & RF_USEAXIS)
        {
                vec3_t forward;
                vec3_t left;
@@ -2250,7 +2235,6 @@ extern cvar_t cl_bobup;
 int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 {
        int ret;
-       prvm_eval_t *val;
        int attachloop;
        matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
        dp_model_t *model;
@@ -2281,10 +2265,10 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
                Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
                // next iteration we process the parent entity
-               if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
+               if (PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.tag_entity))
                {
-                       tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
-                       ent = PRVM_EDICT_NUM(val->edict);
+                       tagindex = (int)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.tag_index);
+                       ent = PRVM_EDICT_NUM(PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.tag_entity));
                }
                else
                        break;
@@ -2292,7 +2276,7 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
        }
 
        // RENDER_VIEWMODEL magic
-       if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && (RF_VIEWMODEL & (int)val->_float))
+       if ((int)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.renderflags) & RF_VIEWMODEL)
        {
                Matrix4x4_Copy(&tagmatrix, out);
 
@@ -2369,7 +2353,6 @@ void VM_CL_gettaginfo (void)
        int parentindex;
        const char *tagname;
        int returncode;
-       prvm_eval_t *val;
        vec3_t fo, le, up, trans;
        const dp_model_t *model;
 
@@ -2387,18 +2370,12 @@ void VM_CL_gettaginfo (void)
        CL_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
        Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
 
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
-               val->_float = parentindex;
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
-               val->string = tagname ? PRVM_SetTempString(tagname) : 0;
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
-               VectorCopy(trans, val->vector);
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
-               VectorCopy(fo, val->vector);
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
-               VectorScale(le, -1, val->vector);
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
-               VectorCopy(up, val->vector);
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.gettaginfo_parent) = parentindex;
+       PRVM_GLOBALFIELDSTRING(prog->globaloffsets.gettaginfo_name) = tagname ? PRVM_SetTempString(tagname) : 0;
+       VectorCopy(trans, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.gettaginfo_offset));
+       VectorCopy(fo, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.gettaginfo_forward));
+       VectorScale(le, -1, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.gettaginfo_right));
+       VectorCopy(up, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.gettaginfo_up));
 
        switch(returncode)
        {
@@ -2505,8 +2482,6 @@ vmparticlespawner_t vmpartspawner;
 // TODO: automatic max_themes grow
 static void VM_InitParticleSpawner (int maxthemes)
 {
-       prvm_eval_t *val;
-
        // bound max themes to not be an insane value
        if (maxthemes < 4)
                maxthemes = 4;
@@ -2524,8 +2499,8 @@ static void VM_InitParticleSpawner (int maxthemes)
        vmpartspawner.initialized = true;
        vmpartspawner.verified = true;
        // get field addresses for fast querying (we can do 1000 calls of spawnparticle in a frame)
-       #define getglobal(v,s) val = PRVM_GLOBALFIELDVALUE(PRVM_ED_FindGlobalOffset(s)); if (val) { vmpartspawner.v = &val->_float; } else { VM_Warning("VM_InitParticleSpawner: missing global '%s', spawner cannot work\n", s); vmpartspawner.verified = false; }
-       #define getglobalvector(v,s) val = PRVM_GLOBALFIELDVALUE(PRVM_ED_FindGlobalOffset(s)); if (val) { vmpartspawner.v = (float *)val->vector; } else { VM_Warning("VM_InitParticleSpawner: missing global '%s', spawner cannot work\n", s); vmpartspawner.verified = false; }
+       #define getglobal(v,s) vmpartspawner.v = &PRVM_GLOBALFIELDFLOAT(PRVM_ED_FindGlobalOffset(s))
+       #define getglobalvector(v,s) vmpartspawner.v = PRVM_GLOBALFIELDVECTOR(PRVM_ED_FindGlobalOffset(s))
        getglobal(particle_type, "particle_type");
        getglobal(particle_blendmode, "particle_blendmode");
        getglobal(particle_orientation, "particle_orientation");
@@ -3445,7 +3420,6 @@ qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean
        trace_t         trace;
        int                     i, svent;
        prvm_edict_t            *enemy;
-       prvm_eval_t     *val;
 
 // try the move
        VectorCopy (ent->fields.client->origin, oldorg);
@@ -3542,8 +3516,7 @@ qboolean CL_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean
        if ( (int)ent->fields.client->flags & FL_PARTIALGROUND )
                ent->fields.client->flags = (int)ent->fields.client->flags & ~FL_PARTIALGROUND;
 
-       if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.groundentity)))
-               val->edict = PRVM_EDICT_TO_PROG(trace.ent);
+       PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.groundentity) = PRVM_EDICT_TO_PROG(trace.ent);
 
 // the move is ok
        if (relink)
index bb31432..faf87dd 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -19,13 +19,11 @@ static prvm_prog_t *csqc_tmpprog;
 
 void CL_VM_PreventInformationLeaks(void)
 {
-       prvm_eval_t *val;
        if(!cl.csqc_loaded)
                return;
        CSQC_BEGIN
                VM_ClearTraceGlobals();
-               if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_networkentity)))
-                       val->_float = 0;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_networkentity) = 0;
        CSQC_END
 }
 
@@ -62,46 +60,30 @@ void CL_VM_Error (const char *format, ...)  //[515]: hope it will be never execut
 }
 void CL_VM_UpdateDmgGlobals (int dmg_take, int dmg_save, vec3_t dmg_origin)
 {
-       prvm_eval_t *val;
        if(cl.csqc_loaded)
        {
                CSQC_BEGIN
-               val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_take);
-               if(val)
-                       val->_float = dmg_take;
-               val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_save);
-               if(val)
-                       val->_float = dmg_save;
-               val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.dmg_origin);
-               if(val)
-               {
-                       val->vector[0] = dmg_origin[0];
-                       val->vector[1] = dmg_origin[1];
-                       val->vector[2] = dmg_origin[2];
-               }
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.dmg_take) = dmg_take;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.dmg_save) = dmg_save;
+               VectorCopy(dmg_origin, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.dmg_origin));
                CSQC_END
        }
 }
 
 void CSQC_UpdateNetworkTimes(double newtime, double oldtime)
 {
-       prvm_eval_t *val;
        if(!cl.csqc_loaded)
                return;
        CSQC_BEGIN
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.servertime)))
-               val->_float = newtime;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.serverprevtime)))
-               val->_float = oldtime;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.serverdeltatime)))
-               val->_float = newtime - oldtime;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.servertime) = newtime;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.serverprevtime) = oldtime;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.serverdeltatime) = newtime - oldtime;
        CSQC_END
 }
 
 //[515]: set globals before calling R_UpdateView, WEIRD CRAP
 static void CSQC_SetGlobals (void)
 {
-       prvm_eval_t *val;
        CSQC_BEGIN
                prog->globals.client->time = cl.time;
                prog->globals.client->frametime = max(0, cl.time - cl.oldtime);
@@ -120,12 +102,9 @@ static void CSQC_SetGlobals (void)
                Matrix4x4_OriginFromMatrix(&cl.entities[cl.viewentity].render.matrix, prog->globals.client->pmove_org);
                VectorCopy(cl.movement_velocity, prog->globals.client->pmove_vel);
 
-               if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.view_angles)))
-                       VectorCopy(cl.viewangles, val->vector);
-               if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.view_punchangle)))
-                       VectorCopy(cl.punchangle, val->vector);
-               if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.view_punchvector)))
-                       VectorCopy(cl.punchvector, val->vector);
+               VectorCopy(cl.viewangles, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.view_angles));
+               VectorCopy(cl.punchangle, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.view_punchangle));
+               VectorCopy(cl.punchvector, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.view_punchvector));
                prog->globals.client->maxclients = cl.maxclients;
        CSQC_END
 }
@@ -162,7 +141,6 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
        int renderflags;
        int c;
        float scale;
-       prvm_eval_t *val;
        entity_render_t *entrender;
        dp_model_t *model;
 
@@ -192,22 +170,24 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
                        return false;
        }
 
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.userwavefunc_param0)))    entrender->userwavefunc_param[0] = val->_float;
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.userwavefunc_param1)))    entrender->userwavefunc_param[1] = val->_float;
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.userwavefunc_param2)))    entrender->userwavefunc_param[2] = val->_float;
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.userwavefunc_param3)))    entrender->userwavefunc_param[3] = val->_float;
+       entrender->userwavefunc_param[0] = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.userwavefunc_param0);
+       entrender->userwavefunc_param[1] = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.userwavefunc_param1);
+       entrender->userwavefunc_param[2] = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.userwavefunc_param2);
+       entrender->userwavefunc_param[3] = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.userwavefunc_param3);
 
        entrender->model = model;
        entrender->skinnum = (int)ed->fields.client->skin;
        entrender->effects |= entrender->model->effects;
-       scale = 1;
-       renderflags = 0;
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.renderflags)) && val->_float)     renderflags = (int)val->_float;
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.alpha)) && val->_float)           entrender->alpha = val->_float;
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.scale)) && val->_float)           entrender->scale = scale = val->_float;
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.colormod)) && VectorLength2(val->vector)) VectorCopy(val->vector, entrender->colormod);
-       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.glowmod)) && VectorLength2(val->vector))  VectorCopy(val->vector, entrender->glowmod);
+       renderflags = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.renderflags);
+       entrender->alpha = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.alpha);
+       entrender->scale = scale = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.scale);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.colormod), entrender->colormod);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.glowmod), entrender->glowmod);
        if(ed->fields.client->effects)  entrender->effects |= (int)ed->fields.client->effects;
+       if (!entrender->alpha)
+               entrender->alpha = 1.0f;
+       if (!entrender->scale)
+               entrender->scale = scale = 1.0f;
        if (!VectorLength2(entrender->colormod))
                VectorSet(entrender->colormod, 1, 1, 1);
        if (!VectorLength2(entrender->glowmod))
@@ -220,11 +200,11 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
        VM_GenerateFrameGroupBlend(ed->priv.server->framegroupblend, ed);
        VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model);
        VM_UpdateEdictSkeleton(ed, model, ed->priv.server->frameblend);
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.shadertime))) entrender->shadertime = val->_float;
+       entrender->shadertime = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.shadertime);
 
        // transparent offset
-       if ((renderflags & RF_USETRANSPARENTOFFSET) && (val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.transparent_offset)))
-               entrender->transparent_offset = val->_float;
+       if (renderflags & RF_USETRANSPARENTOFFSET)
+               entrender->transparent_offset = PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.transparent_offset);
 
        if(renderflags)
        {
@@ -533,25 +513,19 @@ void CL_VM_Parse_CenterPrint (const char *msg)
 
 void CL_VM_UpdateIntermissionState (int intermission)
 {
-       prvm_eval_t *val;
        if(cl.csqc_loaded)
        {
                CSQC_BEGIN
-               val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.intermission);
-               if(val)
-                       val->_float = intermission;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.intermission) = intermission;
                CSQC_END
        }
 }
 void CL_VM_UpdateShowingScoresState (int showingscores)
 {
-       prvm_eval_t *val;
        if(cl.csqc_loaded)
        {
                CSQC_BEGIN
-               val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.sb_showscores);
-               if(val)
-                       val->_float = showingscores;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.sb_showscores) = showingscores;
                CSQC_END
        }
 }
@@ -585,7 +559,6 @@ void CL_VM_UpdateCoopDeathmatchGlobals (int gametype)
        int localcoop;
        int localdeathmatch;
 
-       prvm_eval_t *val;
        if(cl.csqc_loaded)
        {
                if(gametype == GAME_COOP)
@@ -607,12 +580,8 @@ void CL_VM_UpdateCoopDeathmatchGlobals (int gametype)
                        localdeathmatch = 0;
                }
                CSQC_BEGIN
-               val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.coop);
-               if(val)
-                       val->_float = localcoop;
-               val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.deathmatch);
-               if(val)
-                       val->_float = localdeathmatch;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.coop) = localcoop;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.deathmatch) = localdeathmatch;
                CSQC_END
        }
 }
@@ -816,6 +785,146 @@ qboolean MakeDownloadPacket(const char *filename, unsigned char *data, size_t le
        return false;
 }
 
+#define CL_REQFIELDS (sizeof(cl_reqfields) / sizeof(prvm_required_field_t))
+
+prvm_required_field_t cl_reqfields[] =
+{
+       {ev_entity, "groundentity"},
+       {ev_entity, "tag_entity"},
+       {ev_float, "alpha"},
+       {ev_float, "dimension_hit"},
+       {ev_float, "dimension_solid"},
+       {ev_float, "dphitcontentsmask"},
+       {ev_float, "frame"},
+       {ev_float, "frame1time"},
+       {ev_float, "frame2"},
+       {ev_float, "frame2time"},
+       {ev_float, "frame3"},
+       {ev_float, "frame3time"},
+       {ev_float, "frame4"},
+       {ev_float, "frame4time"},
+       {ev_float, "gravity"},
+       {ev_float, "idealpitch"},
+       {ev_float, "lerpfrac"},
+       {ev_float, "lerpfrac3"},
+       {ev_float, "lerpfrac4"},
+       {ev_float, "movetype"}, // used by ODE code
+       {ev_float, "nextthink"},
+       {ev_float, "pitch_speed"},
+       {ev_float, "renderflags"},
+       {ev_float, "scale"},
+       {ev_float, "shadertime"},
+       {ev_float, "skeletonindex"},
+       {ev_float, "solid"}, // used by ODE code
+       {ev_float, "tag_index"},
+       {ev_float, "userwavefunc_param0"},
+       {ev_float, "userwavefunc_param1"},
+       {ev_float, "userwavefunc_param2"},
+       {ev_float, "userwavefunc_param3"},
+       {ev_function, "camera_transform"},
+       {ev_function, "think"},
+       {ev_string, "classname"},
+       {ev_vector, "colormod"},
+       {ev_vector, "glowmod"},
+
+       // physics
+       //{ev_float, "solid"},
+       //{ev_float, "movetype"},
+       //{ev_float, "modelindex"},
+       {ev_vector, "mass"},
+       //{ev_vector, "origin"},
+       //{ev_vector, "velocity"},
+       //{ev_vector, "axis_forward"},
+       //{ev_vector, "axis_left"},
+       //{ev_vector, "axis_up"},
+       //{ev_vector, "spinvelocity"},
+       //{ev_vector, "angles"},
+       //{ev_vector, "avelocity"},
+};
+
+#define CL_REQGLOBALS (sizeof(cl_reqglobals) / sizeof(prvm_required_field_t))
+
+prvm_required_field_t cl_reqglobals[] =
+{
+       {ev_entity, "self"},
+       {ev_entity, "trace_ent"},
+       {ev_entity, "trace_networkentity"},
+       {ev_float, "coop"},
+       {ev_float, "deathmatch"},
+       {ev_float, "dmg_save"},
+       {ev_float, "dmg_take"},
+       {ev_float, "drawfont"},
+       {ev_float, "drawfontscale"},
+       {ev_float, "gettaginfo_parent"},
+       {ev_float, "intermission"},
+       {ev_float, "particle_airfriction"},
+       {ev_float, "particle_alpha"},
+       {ev_float, "particle_alphafade"},
+       {ev_float, "particle_angle"},
+       {ev_float, "particle_blendmode"},
+       {ev_float, "particle_bounce"},
+       {ev_float, "particle_delaycollision"},
+       {ev_float, "particle_delayspawn"},
+       {ev_float, "particle_gravity"},
+       {ev_float, "particle_liquidfriction"},
+       {ev_float, "particle_orientation"},
+       {ev_float, "particle_originjitter"},
+       {ev_float, "particle_qualityreduction"},
+       {ev_float, "particle_size"},
+       {ev_float, "particle_sizeincrease"},
+       {ev_float, "particle_spin"},
+       {ev_float, "particle_stainalpha"},
+       {ev_float, "particle_stainsize"},
+       {ev_float, "particle_staintex"},
+       {ev_float, "particle_staintex"},
+       {ev_float, "particle_stretch"},
+       {ev_float, "particle_tex"},
+       {ev_float, "particle_time"},
+       {ev_float, "particle_type"},
+       {ev_float, "particle_velocityjitter"},
+       {ev_float, "particles_alphamax"},
+       {ev_float, "particles_alphamin"},
+       {ev_float, "require_spawnfunc_prefix"},
+       {ev_float, "sb_showscores"},
+       {ev_float, "serverdeltatime"},
+       {ev_float, "serverprevtime"},
+       {ev_float, "servertime"},
+       {ev_float, "time"},
+       {ev_float, "trace_allsolid"},
+       {ev_float, "trace_dphitcontents"},
+       {ev_float, "trace_dphitq3surfaceflags"},
+       {ev_float, "trace_dpstartcontents"},
+       {ev_float, "trace_fraction"},
+       {ev_float, "trace_inopen"},
+       {ev_float, "trace_inwater"},
+       {ev_float, "trace_plane_dist"},
+       {ev_float, "trace_startsolid"},
+       {ev_float, "transparent_offset"},
+       {ev_string, "SV_InitCmd"},
+       {ev_string, "gettaginfo_name"},
+       {ev_string, "trace_dphittexturename"},
+       {ev_string, "worldstatus"},
+       {ev_vector, "dmg_origin"},
+       {ev_vector, "gettaginfo_forward"},
+       {ev_vector, "gettaginfo_offset"},
+       {ev_vector, "gettaginfo_right"},
+       {ev_vector, "gettaginfo_up"},
+       {ev_vector, "particle_color1"},
+       {ev_vector, "particle_color2"},
+       {ev_vector, "particle_staincolor1"},
+       {ev_vector, "particle_staincolor2"},
+       {ev_vector, "particles_colormax"},
+       {ev_vector, "particles_colormin"},
+       {ev_vector, "trace_endpos"},
+       {ev_vector, "trace_plane_normal"},
+       {ev_vector, "v_forward"},
+       {ev_vector, "v_right"},
+       {ev_vector, "v_up"},
+       {ev_vector, "view_angles"},
+       {ev_vector, "view_punchangle"},
+       {ev_vector, "view_punchvector"},
+};
+
 void CL_VM_Init (void)
 {
        const char* csprogsfn;
@@ -823,7 +932,6 @@ void CL_VM_Init (void)
        fs_offset_t csprogsdatasize;
        int csprogsdatacrc, requiredcrc;
        int requiredsize;
-       prvm_eval_t *val;
 
        // reset csqc_progcrc after reading it, so that changing servers doesn't
        // expect csqc on the next server
@@ -908,7 +1016,7 @@ void CL_VM_Init (void)
        prog->error_cmd = CL_VM_Error;
        prog->ExecuteProgram = CLVM_ExecuteProgram;
 
-       PRVM_LoadProgs(csprogsfn, cl_numrequiredfunc, cl_required_func, 0, NULL, 0, NULL);
+       PRVM_LoadProgs(csprogsfn, cl_numrequiredfunc, cl_required_func, CL_REQFIELDS, cl_reqfields, CL_REQGLOBALS, cl_reqglobals);
 
        if (!prog->loaded)
        {
@@ -957,9 +1065,7 @@ void CL_VM_Init (void)
        prog->globals.client->player_localentnum = cl.playerentity;
 
        // set map description (use world entity 0)
-       val = PRVM_EDICTFIELDVALUE(prog->edicts, prog->fieldoffsets.message);
-       if(val)
-               val->string = PRVM_SetEngineString(cl.worldmessage);
+       PRVM_EDICTFIELDSTRING(prog->edicts, prog->fieldoffsets.message) = PRVM_SetEngineString(cl.worldmessage);
        VectorCopy(cl.world.mins, prog->edicts->fields.client->mins);
        VectorCopy(cl.world.maxs, prog->edicts->fields.client->maxs);
 
@@ -1027,7 +1133,6 @@ qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clip
 {
        qboolean ret = false;
        prvm_edict_t *ed;
-       prvm_eval_t *val, *valforward, *valright, *valup, *valendpos;
        vec3_t forward, left, up, origin, ang;
        matrix4x4_t mat, matq;
 
@@ -1035,38 +1140,31 @@ qboolean CL_VM_TransformView(int entnum, matrix4x4_t *viewmatrix, mplane_t *clip
                ed = PRVM_EDICT_NUM(entnum);
                // camera:
                //   camera_transform
-               if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.camera_transform)) && val->function)
+               if(PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.camera_transform))
                {
                        ret = true;
                        if(viewmatrix || clipplane || visorigin)
                        {
-                               valforward = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_forward);
-                               valright = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_right);
-                               valup = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_up);
-                               valendpos = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_endpos);
-                               if(valforward && valright && valup && valendpos)
-                               {
-                                       Matrix4x4_ToVectors(viewmatrix, forward, left, up, origin);
-                                       AnglesFromVectors(ang, forward, up, false);
-                                       prog->globals.client->time = cl.time;
-                                       prog->globals.client->self = entnum;
-                                       VectorCopy(origin, PRVM_G_VECTOR(OFS_PARM0));
-                                       VectorCopy(ang, PRVM_G_VECTOR(OFS_PARM1));
-                                       VectorCopy(forward, valforward->vector);
-                                       VectorScale(left, -1, valright->vector);
-                                       VectorCopy(up, valup->vector);
-                                       VectorCopy(origin, valendpos->vector);
-                                       PRVM_ExecuteProgram(val->function, "QC function e.camera_transform is missing");
-                                       VectorCopy(PRVM_G_VECTOR(OFS_RETURN), origin);
-                                       VectorCopy(valforward->vector, forward);
-                                       VectorScale(valright->vector, -1, left);
-                                       VectorCopy(valup->vector, up);
-                                       VectorCopy(valendpos->vector, visorigin);
-                                       Matrix4x4_Invert_Full(&mat, viewmatrix);
-                                       Matrix4x4_FromVectors(viewmatrix, forward, left, up, origin);
-                                       Matrix4x4_Concat(&matq, viewmatrix, &mat);
-                                       Matrix4x4_TransformPositivePlane(&matq, clipplane->normal[0], clipplane->normal[1], clipplane->normal[2], clipplane->dist, &clipplane->normal[0]);
-                               }
+                               Matrix4x4_ToVectors(viewmatrix, forward, left, up, origin);
+                               AnglesFromVectors(ang, forward, up, false);
+                               prog->globals.client->time = cl.time;
+                               prog->globals.client->self = entnum;
+                               VectorCopy(origin, PRVM_G_VECTOR(OFS_PARM0));
+                               VectorCopy(ang, PRVM_G_VECTOR(OFS_PARM1));
+                               VectorCopy(forward, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_forward));
+                               VectorScale(left, -1, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_right));
+                               VectorCopy(up, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_up));
+                               VectorCopy(origin, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_endpos));
+                               PRVM_ExecuteProgram(PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.camera_transform), "QC function e.camera_transform is missing");
+                               VectorCopy(PRVM_G_VECTOR(OFS_RETURN), origin);
+                               VectorCopy(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_forward), forward);
+                               VectorScale(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_right), -1, left);
+                               VectorCopy(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_up), up);
+                               VectorCopy(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_endpos), visorigin);
+                               Matrix4x4_Invert_Full(&mat, viewmatrix);
+                               Matrix4x4_FromVectors(viewmatrix, forward, left, up, origin);
+                               Matrix4x4_Concat(&matq, viewmatrix, &mat);
+                               Matrix4x4_TransformPositivePlane(&matq, clipplane->normal[0], clipplane->normal[1], clipplane->normal[2], clipplane->dist, &clipplane->normal[0]);
                        }
                }
        CSQC_END
diff --git a/cvar.c b/cvar.c
index 707c54c..bb5c3ce 100644 (file)
--- a/cvar.c
+++ b/cvar.c
@@ -265,31 +265,32 @@ static void Cvar_UpdateAutoCvar(cvar_t *var)
                // MUST BE SYNCED WITH prvm_edict.c PRVM_LoadProgs
                int j;
                const char *s;
-               prvm_eval_t *val = (prvm_eval_t *)(prog->globals.generic + prog->globaldefs[var->globaldefindex[i]].ofs);
+               vec3_t v;
                switch(prog->globaldefs[var->globaldefindex[i]].type & ~DEF_SAVEGLOBAL)
                {
                        case ev_float:
-                               val->_float = var->value;
+                               PRVM_GLOBALFIELDFLOAT(prog->globaldefs[var->globaldefindex[i]].ofs) = var->value;
                                break;
                        case ev_vector:
                                s = var->string;
-                               VectorClear(val->vector);
+                               VectorClear(v);
                                for (j = 0;j < 3;j++)
                                {
                                        while (*s && ISWHITESPACE(*s))
                                                s++;
                                        if (!*s)
                                                break;
-                                       val->vector[j] = atof(s);
+                                       v[j] = atof(s);
                                        while (!ISWHITESPACE(*s))
                                                s++;
                                        if (!*s)
                                                break;
                                }
+                               VectorCopy(v, PRVM_GLOBALFIELDVECTOR(prog->globaldefs[var->globaldefindex[i]].ofs));
                                break;
                        case ev_string:
                                PRVM_ChangeEngineString(var->globaldefindex_stringno[i], var->string);
-                               val->string = var->globaldefindex_stringno[i];
+                               PRVM_GLOBALFIELDSTRING(prog->globaldefs[var->globaldefindex[i]].ofs) = var->globaldefindex_stringno[i];
                                break;
                }
        }
index 9b2ee27..bf003e5 100644 (file)
@@ -943,7 +943,7 @@ void Host_Loadgame_f (void)
                        while (entnum >= prog->max_edicts)
                                PRVM_MEM_IncreaseEdicts();
                        ent = PRVM_EDICT_NUM(entnum);
-                       memset (ent->fields.server, 0, prog->progs->entityfields * 4);
+                       memset (ent->fields.server, 0, prog->entityfields * 4);
                        ent->priv.server->free = false;
 
                        if(developer_entityparsing.integer)
@@ -1254,8 +1254,8 @@ void Host_Playermodel_f (void)
 
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->playermodel, newPath, sizeof (host_client->playermodel));
-       if( prog->fieldoffsets.playermodel >= 0 )
-               PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playermodel)->string = PRVM_SetEngineString(host_client->playermodel);
+       if (prog->fieldoffsets.playermodel >= 0)
+               PRVM_EDICTFIELDSTRING(host_client->edict, prog->fieldoffsets.playermodel) = PRVM_SetEngineString(host_client->playermodel);
        if (strcmp(host_client->old_model, host_client->playermodel))
        {
                strlcpy(host_client->old_model, host_client->playermodel, sizeof(host_client->old_model));
@@ -1311,8 +1311,8 @@ void Host_Playerskin_f (void)
 
        // point the string back at updateclient->name to keep it safe
        strlcpy (host_client->playerskin, newPath, sizeof (host_client->playerskin));
-       if( prog->fieldoffsets.playerskin >= 0 )
-               PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playerskin)->string = PRVM_SetEngineString(host_client->playerskin);
+       if (prog->fieldoffsets.playerskin >= 0)
+               PRVM_EDICTFIELDSTRING(host_client->edict, prog->fieldoffsets.playerskin) = PRVM_SetEngineString(host_client->playerskin);
        if (strcmp(host_client->old_skin, host_client->playerskin))
        {
                //if (host_client->spawned)
@@ -1583,11 +1583,9 @@ void Host_Color(int changetop, int changebottom)
        }
        else
        {
-               prvm_eval_t *val;
                if (host_client->edict)
                {
-                       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.clientcolors)))
-                               val->_float = playercolor;
+                       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.clientcolors) = playercolor;
                        host_client->edict->fields.server->team = bottom + 1;
                }
                host_client->colors = playercolor;
@@ -1719,7 +1717,6 @@ cvar_t cl_pmodel = {CVAR_SAVE | CVAR_NQUSERINFOHACK, "_cl_pmodel", "0", "interna
 static void Host_PModel_f (void)
 {
        int i;
-       prvm_eval_t *val;
 
        if (Cmd_Argc () == 1)
        {
@@ -1738,8 +1735,7 @@ static void Host_PModel_f (void)
                return;
        }
 
-       if (host_client->edict && (val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.pmodel)))
-               val->_float = i;
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.pmodel) = i;
 }
 
 //===========================================================================
@@ -2029,7 +2025,6 @@ void Host_Give_f (void)
 {
        const char *t;
        int v;
-       prvm_eval_t *val;
 
        if (!allowcheats)
        {
@@ -2077,20 +2072,17 @@ void Host_Give_f (void)
                break;
 
        case 's':
-               if (gamemode == GAME_ROGUE && (val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_shells1)))
-                       val->_float = v;
+               if (gamemode == GAME_ROGUE)
+                       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ammo_shells1) = v;
 
                host_client->edict->fields.server->ammo_shells = v;
                break;
        case 'n':
                if (gamemode == GAME_ROGUE)
                {
-                       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_nails1)))
-                       {
-                               val->_float = v;
-                               if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
-                                       host_client->edict->fields.server->ammo_nails = v;
-                       }
+                       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ammo_nails1) = v;
+                       if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
+                               host_client->edict->fields.server->ammo_nails = v;
                }
                else
                {
@@ -2100,25 +2092,17 @@ void Host_Give_f (void)
        case 'l':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_lava_nails);
-                       if (val)
-                       {
-                               val->_float = v;
-                               if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
-                                       host_client->edict->fields.server->ammo_nails = v;
-                       }
+                       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ammo_lava_nails) = v;
+                       if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
+                               host_client->edict->fields.server->ammo_nails = v;
                }
                break;
        case 'r':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_rockets1);
-                       if (val)
-                       {
-                               val->_float = v;
-                               if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
-                                       host_client->edict->fields.server->ammo_rockets = v;
-                       }
+                       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ammo_rockets1) = v;
+                       if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
+                               host_client->edict->fields.server->ammo_rockets = v;
                }
                else
                {
@@ -2128,13 +2112,9 @@ void Host_Give_f (void)
        case 'm':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_multi_rockets);
-                       if (val)
-                       {
-                               val->_float = v;
-                               if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
-                                       host_client->edict->fields.server->ammo_rockets = v;
-                       }
+                       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ammo_multi_rockets) = v;
+                       if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
+                               host_client->edict->fields.server->ammo_rockets = v;
                }
                break;
        case 'h':
@@ -2143,13 +2123,9 @@ void Host_Give_f (void)
        case 'c':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_cells1);
-                       if (val)
-                       {
-                               val->_float = v;
-                               if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
-                                       host_client->edict->fields.server->ammo_cells = v;
-                       }
+                       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ammo_cells1) = v;
+                       if (host_client->edict->fields.server->weapon <= IT_LIGHTNING)
+                               host_client->edict->fields.server->ammo_cells = v;
                }
                else
                {
@@ -2159,13 +2135,9 @@ void Host_Give_f (void)
        case 'p':
                if (gamemode == GAME_ROGUE)
                {
-                       val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ammo_plasma);
-                       if (val)
-                       {
-                               val->_float = v;
-                               if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
-                                       host_client->edict->fields.server->ammo_cells = v;
-                       }
+                       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ammo_plasma) = v;
+                       if (host_client->edict->fields.server->weapon > IT_LIGHTNING)
+                               host_client->edict->fields.server->ammo_cells = v;
                }
                break;
        }
index 41c476c..9d154b4 100644 (file)
@@ -736,7 +736,7 @@ static void VM_M_copyentity (void)
        VM_SAFEPARMCOUNT(2,VM_M_copyentity);
        in = PRVM_G_EDICT(OFS_PARM0);
        out = PRVM_G_EDICT(OFS_PARM1);
-       memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
+       memcpy(out->fields.vp, in->fields.vp, prog->entityfields * 4);
 }
 
 //#66 vector() getmousepos (EXT_CSQC)
index 0ffe578..d1643b6 100644 (file)
--- a/pr_comp.h
+++ b/pr_comp.h
@@ -42,7 +42,7 @@ typedef enum etype_e {ev_void, ev_string, ev_float, ev_vector, ev_entity, ev_fie
 #define        RESERVED_OFS    28
 
 
-enum opcode_e
+typedef enum opcode_e
 {
        OP_DONE,
        OP_MUL_F,
@@ -119,7 +119,8 @@ enum opcode_e
 
        OP_BITAND,
        OP_BITOR
-};
+}
+opcode_t;
 
 
 typedef struct statement_s
@@ -183,6 +184,14 @@ typedef struct mfunction_s
 }
 mfunction_t;
 
+typedef struct mstatement_s
+{
+       opcode_t        op;
+       int                     operand[3]; // always a global or -1 for unused
+       int                     jumpabsolute; // only used by IF, IFNOT, GOTO
+}
+mstatement_t;
+
 
 #define        PROG_VERSION    6
 typedef struct dprograms_s
index ac5dd22..5dead05 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -115,8 +115,18 @@ typedef struct prvm_edict_s
        } fields;
 } prvm_edict_t;
 
-#define PRVM_EDICTFIELDVALUE(ed, fieldoffset) (fieldoffset >= 0 ? (prvm_eval_t *)((int *)ed->fields.vp + fieldoffset) : NULL)
-#define PRVM_GLOBALFIELDVALUE(fieldoffset) (fieldoffset >= 0 ? (prvm_eval_t *)((int *)prog->globals.generic + fieldoffset) : NULL)
+#define PRVM_EDICTFIELDVALUE(ed, fieldoffset) ((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))
+#define PRVM_EDICTFIELDFLOAT(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->_float)
+#define PRVM_EDICTFIELDVECTOR(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->vector)
+#define PRVM_EDICTFIELDSTRING(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->string)
+#define PRVM_EDICTFIELDEDICT(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->edict)
+#define PRVM_EDICTFIELDFUNCTION(ed, fieldoffset) (((prvm_eval_t *)((int *)ed->fields.vp + fieldoffset))->function)
+#define PRVM_GLOBALFIELDVALUE(fieldoffset) ((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))
+#define PRVM_GLOBALFIELDFLOAT(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->_float)
+#define PRVM_GLOBALFIELDVECTOR(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->vector)
+#define PRVM_GLOBALFIELDSTRING(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->string)
+#define PRVM_GLOBALFIELDEDICT(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->edict)
+#define PRVM_GLOBALFIELDFUNCTION(fieldoffset) (((prvm_eval_t *)((int *)prog->globals.generic + fieldoffset))->function)
 
 //============================================================================
 #define PRVM_OP_STATE          1
@@ -402,16 +412,34 @@ typedef struct prvm_prog_s
 {
        double              starttime;
        unsigned int            id; // increasing unique id of progs instance
-       dprograms_t                     *progs;
        mfunction_t                     *functions;
        char                            *strings;
        int                                     stringssize;
        ddef_t                          *fielddefs;
        ddef_t                          *globaldefs;
-       dstatement_t            *statements;
+       mstatement_t            *statements;
        int                                     entityfields;                   // number of vec_t fields in progs (some variables are 3)
        int                                     entityfieldsarea;               // LordHavoc: equal to max_edicts * entityfields (for bounds checking)
 
+       // loaded values from the disk format
+       int                                     progs_version;
+       int                                     progs_crc;
+       int                                     progs_numstatements;
+       int                                     progs_numglobaldefs;
+       int                                     progs_numfielddefs;
+       int                                     progs_numfunctions;
+       int                                     progs_numstrings;
+       int                                     progs_numglobals;
+       int                                     progs_entityfields;
+
+       // real values in memory (some modified by loader)
+       int                                     numstatements;
+       int                                     numglobaldefs;
+       int                                     numfielddefs;
+       int                                     numfunctions;
+       int                                     numstrings;
+       int                                     numglobals;
+
        int                                     *statement_linenums; // NULL if not available
 
        double                          *statement_profile; // only incremented if prvm_statementprofiling is on
@@ -723,7 +751,7 @@ Load a program with LoadProgs
 */
 void PRVM_InitProg(int prognr);
 // LoadProgs expects to be called right after InitProg
-void PRVM_LoadProgs (const char *filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, char **required_global);
+void PRVM_LoadProgs (const char *filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global);
 void PRVM_ResetProg(void);
 
 qboolean PRVM_ProgLoaded(int prognr);
index b2d4a37..3a5d540 100644 (file)
@@ -10,7 +10,7 @@
                const char *cname = "(no classname)"; \
                if(prog->fieldoffsets.classname >= 0) \
                { \
-                       string_t handle =  PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.classname)->string; \
+                       string_t handle =  PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.classname); \
                        if (handle) \
                                cname = PRVM_GetString(handle); \
                } \
@@ -279,7 +279,6 @@ static void EntityFrameCSQC_LostAllFrames(client_t *client)
        // mark ALL csqc entities as requiring a FULL resend!
        // I know this is a bad workaround, but better than nothing.
        int i, n;
-       prvm_eval_t *val;
        prvm_edict_t *ed;
 
        if(prog->fieldoffsets.SendEntity < 0 || prog->fieldoffsets.Version < 0)
@@ -291,8 +290,7 @@ static void EntityFrameCSQC_LostAllFrames(client_t *client)
                if(client->csqcentityglobalhistory[i])
                {
                        ed = prog->edicts + i;
-                       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.SendEntity);
-                       if (val->function)
+                       if (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.SendEntity))
                                client->csqcentitysendflags[i] |= 0xFFFFFF; // FULL RESEND
                        else // if it was ever sent to that client as a CSQC entity
                        {
@@ -447,7 +445,6 @@ qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numnumbers
        qboolean sectionstarted = false;
        const unsigned short *n;
        prvm_edict_t *ed;
-       prvm_eval_t *val;
        client_t *client = svs.clients + sv.writeentitiestoclient_clientnumber;
        int dbframe = EntityFrameCSQC_AllocFrame(client, framenum);
        csqcentityframedb_t *db = &client->csqcentityframehistory[dbframe];
@@ -482,8 +479,7 @@ qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numnumbers
                        }
                }
                ed = prog->edicts + number;
-               val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.SendEntity);
-               if (val->function)
+               if (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.SendEntity))
                        client->csqcentityscope[number] = 2;
                else if (client->csqcentityscope[number])
                {
@@ -512,8 +508,7 @@ qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numnumbers
        {
                number = *n;
                ed = prog->edicts + number;
-               val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.SendEntity);
-               if (val->function)
+               if (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.SendEntity))
                        client->csqcentityscope[number] = 2;
        }
        */
@@ -562,8 +557,7 @@ qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numnumbers
                        // save the cursize value in case we overflow and have to rollback
                        int oldcursize = msg->cursize;
                        client->csqcentityscope[number] = 1;
-                       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.SendEntity);
-                       if (val->function)
+                       if (PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.SendEntity))
                        {
                                if(!sectionstarted)
                                        MSG_WriteByte(msg, svc_csqcentities);
@@ -574,7 +568,7 @@ qboolean EntityFrameCSQC_WriteFrame (sizebuf_t *msg, int maxsize, int numnumbers
                                        PRVM_G_INT(OFS_PARM0) = sv.writeentitiestoclient_cliententitynumber;
                                        PRVM_G_FLOAT(OFS_PARM1) = sendflags;
                                        prog->globals.server->self = number;
-                                       PRVM_ExecuteProgram(val->function, "Null SendEntity\n");
+                                       PRVM_ExecuteProgram(PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.SendEntity), "Null SendEntity\n");
                                        msg->allowoverflow = false;
                                        if(PRVM_G_FLOAT(OFS_RETURN) && msg->cursize + 2 <= maxsize)
                                        {
@@ -701,7 +695,6 @@ qboolean EntityFrameQuake_WriteFrame(sizebuf_t *msg, int maxsize, int numstates,
        int i, bits;
        sizebuf_t buf;
        unsigned char data[128];
-       prvm_eval_t *val;
        qboolean success = false;
 
        // prepare the buffer
@@ -713,8 +706,7 @@ qboolean EntityFrameQuake_WriteFrame(sizebuf_t *msg, int maxsize, int numstates,
        {
                ENTITYSIZEPROFILING_START(msg, states[i]->number);
                s = states[i];
-               val = PRVM_EDICTFIELDVALUE((&prog->edicts[s->number]), prog->fieldoffsets.SendEntity);
-               if(val && val->function)
+               if(PRVM_EDICTFIELDFUNCTION((&prog->edicts[s->number]), prog->fieldoffsets.SendEntity))
                        continue;
 
                // prepare the buffer
@@ -1409,7 +1401,6 @@ qboolean EntityFrame_WriteFrame(sizebuf_t *msg, int maxsize, entityframe_databas
        entity_frame_t *o = &d->deltaframe;
        const entity_state_t *ent, *delta;
        vec3_t eye;
-       prvm_eval_t *val;
 
        d->latestframenum++;
 
@@ -1441,8 +1432,7 @@ qboolean EntityFrame_WriteFrame(sizebuf_t *msg, int maxsize, entityframe_databas
                ent = states[i];
                number = ent->number;
 
-               val = PRVM_EDICTFIELDVALUE((&prog->edicts[number]), prog->fieldoffsets.SendEntity);
-               if(val && val->function)
+               if (PRVM_EDICTFIELDFUNCTION((&prog->edicts[number]), prog->fieldoffsets.SendEntity))
                        continue;
                for (;onum < o->numentities && o->entitydata[onum].number < number;onum++)
                {
@@ -1887,7 +1877,6 @@ qboolean EntityFrame4_WriteFrame(sizebuf_t *msg, int maxsize, entityframe4_datab
        int i, n, startnumber;
        sizebuf_t buf;
        unsigned char data[128];
-       prvm_eval_t *val;
 
        // if there isn't enough space to accomplish anything, skip it
        if (msg->cursize + 24 > maxsize)
@@ -1932,8 +1921,7 @@ qboolean EntityFrame4_WriteFrame(sizebuf_t *msg, int maxsize, entityframe4_datab
        d->currententitynumber = 1;
        for (i = 0, n = startnumber;n < prog->max_edicts;n++)
        {
-               val = PRVM_EDICTFIELDVALUE((&prog->edicts[n]), prog->fieldoffsets.SendEntity);
-               if(val && val->function)
+               if (PRVM_EDICTFIELDFUNCTION((&prog->edicts[n]), prog->fieldoffsets.SendEntity))
                        continue;
                // find the old state to delta from
                e = EntityFrame4_GetReferenceEntity(d, n);
@@ -2089,9 +2077,7 @@ void EntityState5_WriteUpdate(int number, const entity_state_t *s, int changedbi
        //dp_model_t *model;
        ENTITYSIZEPROFILING_START(msg, s->number);
 
-       prvm_eval_t *val;
-       val = PRVM_EDICTFIELDVALUE((&prog->edicts[s->number]), prog->fieldoffsets.SendEntity);
-       if(val && val->function)
+       if (PRVM_EDICTFIELDFUNCTION((&prog->edicts[s->number]), prog->fieldoffsets.SendEntity))
                return;
 
        if (s->active != ACTIVE_NETWORK)
index f604516..5222146 100644 (file)
@@ -55,7 +55,6 @@ void VM_CheckEmptyString (const char *s)
 
 void VM_GenerateFrameGroupBlend(framegroupblend_t *framegroupblend, const prvm_edict_t *ed)
 {
-       prvm_eval_t *val;
        // self.frame is the interpolation target (new frame)
        // self.frame1time is the animation base time for the interpolation target
        // self.frame2 is the interpolation start (previous frame)
@@ -65,17 +64,17 @@ void VM_GenerateFrameGroupBlend(framegroupblend_t *framegroupblend, const prvm_e
        // self.lerpfrac4 is the interpolation strength for self.frame4
        // pitch angle on a player model where the animator set up 5 sets of
        // animations and the csqc simply lerps between sets)
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame))) framegroupblend[0].frame = (int) val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2))) framegroupblend[1].frame = (int) val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3))) framegroupblend[2].frame = (int) val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4))) framegroupblend[3].frame = (int) val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame1time))) framegroupblend[0].start = val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2time))) framegroupblend[1].start = val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3time))) framegroupblend[2].start = val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4time))) framegroupblend[3].start = val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac))) framegroupblend[1].lerp = val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac3))) framegroupblend[2].lerp = val->_float;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac4))) framegroupblend[3].lerp = val->_float;
+       framegroupblend[0].frame = (int) PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.frame     );
+       framegroupblend[1].frame = (int) PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.frame2    );
+       framegroupblend[2].frame = (int) PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.frame3    );
+       framegroupblend[3].frame = (int) PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.frame4    );
+       framegroupblend[0].start =       PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.frame1time);
+       framegroupblend[1].start =       PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.frame2time);
+       framegroupblend[2].start =       PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.frame3time);
+       framegroupblend[3].start =       PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.frame4time);
+       framegroupblend[1].lerp  =       PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.lerpfrac  );
+       framegroupblend[2].lerp  =       PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.lerpfrac3 );
+       framegroupblend[3].lerp  =       PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.lerpfrac4 );
        // assume that the (missing) lerpfrac1 is whatever remains after lerpfrac2+lerpfrac3+lerpfrac4 are summed
        framegroupblend[0].lerp = 1 - framegroupblend[1].lerp - framegroupblend[2].lerp - framegroupblend[3].lerp;
 }
@@ -198,8 +197,7 @@ void VM_UpdateEdictSkeleton(prvm_edict_t *ed, const dp_model_t *edmodel, const f
        {
                int skeletonindex = -1;
                skeleton_t *skeleton;
-               prvm_eval_t *val;
-               if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.skeletonindex))) skeletonindex = (int)val->_float - 1;
+               skeletonindex = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.skeletonindex) - 1;
                if (skeletonindex >= 0 && skeletonindex < MAX_EDICTS && (skeleton = prog->skeletons[skeletonindex]) && skeleton->model->num_bones == ed->priv.server->skeleton.model->num_bones)
                {
                        // custom skeleton controlled by the game (FTE_CSQC_SKELETONOBJECTS)
@@ -314,7 +312,7 @@ void VM_error (void)
        Con_Printf("======%s ERROR in %s:\n%s\n", PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string);
        if (prog->globaloffsets.self >= 0)
        {
-               ed = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict);
+               ed = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDEDICT(prog->globaloffsets.self));
                PRVM_ED_Print(ed, NULL);
        }
 
@@ -340,7 +338,7 @@ void VM_objerror (void)
        Con_Printf("======OBJECT ERROR======\n"); // , PRVM_NAME, PRVM_GetString(prog->xfunction->s_name), string); // or include them? FIXME
        if (prog->globaloffsets.self >= 0)
        {
-               ed = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict);
+               ed = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDEDICT(prog->globaloffsets.self));
                PRVM_ED_Print(ed, NULL);
 
                PRVM_ED_Free (ed);
@@ -1115,7 +1113,7 @@ void VM_findchain (void)
                if (strcmp(t,s))
                        continue;
 
-               PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_NUM_FOR_EDICT(chain);
+               PRVM_EDICTFIELDEDICT(ent,chainfield) = PRVM_NUM_FOR_EDICT(chain);
                chain = ent;
        }
 
@@ -1163,7 +1161,7 @@ void VM_findchainfloat (void)
                if (PRVM_E_FLOAT(ent,f) != s)
                        continue;
 
-               PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
+               PRVM_EDICTFIELDEDICT(ent,chainfield) = PRVM_EDICT_TO_PROG(chain);
                chain = ent;
        }
 
@@ -1251,7 +1249,7 @@ void VM_findchainflags (void)
                if (!((int)PRVM_E_FLOAT(ent,f) & s))
                        continue;
 
-               PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
+               PRVM_EDICTFIELDEDICT(ent,chainfield) = PRVM_EDICT_TO_PROG(chain);
                chain = ent;
        }
 
@@ -2019,7 +2017,7 @@ Return the number of entity fields - NOT offsets
 */
 void VM_numentityfields(void)
 {
-       PRVM_G_FLOAT(OFS_RETURN) = prog->progs->numfielddefs;
+       PRVM_G_FLOAT(OFS_RETURN) = prog->numfielddefs;
 }
 
 // KrimZon - DP_QC_ENTITYDATA
@@ -2036,7 +2034,7 @@ void VM_entityfieldname(void)
        ddef_t *d;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
        
-       if (i < 0 || i >= prog->progs->numfielddefs)
+       if (i < 0 || i >= prog->numfielddefs)
        {
         VM_Warning("VM_entityfieldname: %s: field index out of bounds\n", PRVM_NAME);
         PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString("");
@@ -2060,7 +2058,7 @@ void VM_entityfieldtype(void)
        ddef_t *d;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
        
-       if (i < 0 || i >= prog->progs->numfielddefs)
+       if (i < 0 || i >= prog->numfielddefs)
        {
                VM_Warning("VM_entityfieldtype: %s: field index out of bounds\n", PRVM_NAME);
                PRVM_G_FLOAT(OFS_RETURN) = -1.0;
@@ -2088,7 +2086,7 @@ void VM_getentityfieldstring(void)
        prvm_edict_t * ent;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
        
-       if (i < 0 || i >= prog->progs->numfielddefs)
+       if (i < 0 || i >= prog->numfielddefs)
        {
         VM_Warning("VM_entityfielddata: %s: field index out of bounds\n", PRVM_NAME);
                PRVM_G_INT(OFS_RETURN) = PRVM_SetTempString("");
@@ -2135,7 +2133,7 @@ void VM_putentityfieldstring(void)
        prvm_edict_t * ent;
        int i = (int)PRVM_G_FLOAT(OFS_PARM0);
 
-       if (i < 0 || i >= prog->progs->numfielddefs)
+       if (i < 0 || i >= prog->numfielddefs)
        {
         VM_Warning("VM_entityfielddata: %s: field index out of bounds\n", PRVM_NAME);
                PRVM_G_FLOAT(OFS_RETURN) = 0.0f;
@@ -4449,17 +4447,8 @@ void makevectors(vector angle)
 */
 void VM_makevectors (void)
 {
-       prvm_eval_t *valforward, *valright, *valup;
-       valforward = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_forward);
-       valright = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_right);
-       valup = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_up);
-       if (!valforward || !valright || !valup)
-       {
-               VM_Warning("makevectors: could not find v_forward, v_right, or v_up global variables\n");
-               return;
-       }
        VM_SAFEPARMCOUNT(1, VM_makevectors);
-       AngleVectors (PRVM_G_VECTOR(OFS_PARM0), valforward->vector, valright->vector, valup->vector);
+       AngleVectors(PRVM_G_VECTOR(OFS_PARM0), PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_forward), PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_right), PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_up));
 }
 
 /*
@@ -4472,18 +4461,9 @@ vectorvectors(vector)
 */
 void VM_vectorvectors (void)
 {
-       prvm_eval_t *valforward, *valright, *valup;
-       valforward = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_forward);
-       valright = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_right);
-       valup = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.v_up);
-       if (!valforward || !valright || !valup)
-       {
-               VM_Warning("vectorvectors: could not find v_forward, v_right, or v_up global variables\n");
-               return;
-       }
        VM_SAFEPARMCOUNT(1, VM_vectorvectors);
-       VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), valforward->vector);
-       VectorVectors(valforward->vector, valright->vector, valup->vector);
+       VectorNormalize2(PRVM_G_VECTOR(OFS_PARM0), PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_forward));
+       VectorVectors(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_forward), PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_right), PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.v_up));
 }
 
 /*
@@ -5263,7 +5243,7 @@ void VM_changeyaw (void)
        // parameters because they are the parameters to SV_MoveToGoal, not this
        //VM_SAFEPARMCOUNT(0, VM_changeyaw);
 
-       ent = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict);
+       ent = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDEDICT(prog->globaloffsets.self));
        if (ent == prog->edicts)
        {
                VM_Warning("changeyaw: can not modify world entity\n");
@@ -5279,9 +5259,10 @@ void VM_changeyaw (void)
                VM_Warning("changeyaw: angles, ideal_yaw, or yaw_speed field(s) not found\n");
                return;
        }
-       current = ANGLEMOD(PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.angles)->vector[1]);
-       ideal = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.ideal_yaw)->_float;
-       speed = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.yaw_speed)->_float;
+       current = PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.angles)[1];
+       current = ANGLEMOD(current);
+       ideal = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.ideal_yaw);
+       speed = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.yaw_speed);
 
        if (current == ideal)
                return;
@@ -5307,7 +5288,8 @@ void VM_changeyaw (void)
                        move = -speed;
        }
 
-       PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.angles)->vector[1] = ANGLEMOD (current + move);
+       current += move;
+       PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.angles)[1] = ANGLEMOD(current);
 }
 
 /*
@@ -5338,9 +5320,10 @@ void VM_changepitch (void)
                VM_Warning("changepitch: angles, idealpitch, or pitch_speed field(s) not found\n");
                return;
        }
-       current = ANGLEMOD(PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.angles)->vector[0]);
-       ideal = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.idealpitch)->_float;
-       speed = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.pitch_speed)->_float;
+       current = PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.angles)[0];
+       current = ANGLEMOD(current);
+       ideal = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.idealpitch);
+       speed = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.pitch_speed);
 
        if (current == ideal)
                return;
@@ -5366,7 +5349,8 @@ void VM_changepitch (void)
                        move = -speed;
        }
 
-       PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.angles)->vector[0] = ANGLEMOD (current + move);
+       current += move;
+       PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.angles)[0] = ANGLEMOD(current);
 }
 
 
@@ -5689,65 +5673,37 @@ void VM_wasfreed (void)
 
 void VM_SetTraceGlobals(const trace_t *trace)
 {
-       prvm_eval_t *val;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_allsolid)))
-               val->_float = trace->allsolid;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_startsolid)))
-               val->_float = trace->startsolid;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_fraction)))
-               val->_float = trace->fraction;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_inwater)))
-               val->_float = trace->inwater;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_inopen)))
-               val->_float = trace->inopen;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_endpos)))
-               VectorCopy(trace->endpos, val->vector);
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_plane_normal)))
-               VectorCopy(trace->plane.normal, val->vector);
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_plane_dist)))
-               val->_float = trace->plane.dist;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_ent)))
-               val->edict = PRVM_EDICT_TO_PROG(trace->ent ? trace->ent : prog->edicts);
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
-               val->_float = trace->startsupercontents;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
-               val->_float = trace->hitsupercontents;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
-               val->_float = trace->hitq3surfaceflags;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
-               val->string = trace->hittexture ? PRVM_SetTempString(trace->hittexture->name) : 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_allsolid) = trace->allsolid;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_startsolid) = trace->startsolid;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_fraction) = trace->fraction;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_inwater) = trace->inwater;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_inopen) = trace->inopen;
+       VectorCopy(trace->endpos, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_endpos));
+       VectorCopy(trace->plane.normal, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_plane_normal));
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_plane_dist) = trace->plane.dist;
+       PRVM_GLOBALFIELDEDICT(prog->globaloffsets.trace_ent) = PRVM_EDICT_TO_PROG(trace->ent ? trace->ent : prog->edicts);
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dpstartcontents) = trace->startsupercontents;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitcontents) = trace->hitsupercontents;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitq3surfaceflags) = trace->hitq3surfaceflags;
+       PRVM_GLOBALFIELDSTRING(prog->globaloffsets.trace_dphittexturename) = trace->hittexture ? PRVM_SetTempString(trace->hittexture->name) : 0;
 }
 
 void VM_ClearTraceGlobals(void)
 {
        // clean up all trace globals when leaving the VM (anti-triggerbot safeguard)
-       prvm_eval_t *val;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_allsolid)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_startsolid)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_fraction)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_inwater)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_inopen)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_endpos)))
-               VectorClear(val->vector);
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_plane_normal)))
-               VectorClear(val->vector);
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_plane_dist)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_ent)))
-               val->edict = PRVM_EDICT_TO_PROG(prog->edicts);
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
-               val->string = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_allsolid) = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_startsolid) = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_fraction) = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_inwater) = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_inopen) = 0;
+       VectorClear(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_endpos));
+       VectorClear(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_plane_normal));
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_plane_dist) = 0;
+       PRVM_GLOBALFIELDEDICT(prog->globaloffsets.trace_ent) = PRVM_EDICT_TO_PROG(prog->edicts);
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dpstartcontents) = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitcontents) = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitq3surfaceflags) = 0;
+       PRVM_GLOBALFIELDSTRING(prog->globaloffsets.trace_dphittexturename) = 0;
 }
 
 //=============
@@ -6573,7 +6529,6 @@ static animatemodel_cache_t animatemodel_cache;
 
 void animatemodel(dp_model_t *model, prvm_edict_t *ed)
 {
-       prvm_eval_t *val;
        skeleton_t *skeleton;
        int skeletonindex = -1;
        qboolean need = false;
@@ -6591,7 +6546,7 @@ void animatemodel(dp_model_t *model, prvm_edict_t *ed)
        VM_GenerateFrameGroupBlend(ed->priv.server->framegroupblend, ed);
        VM_FrameBlendFromFrameGroupBlend(ed->priv.server->frameblend, ed->priv.server->framegroupblend, model);
        need |= (memcmp(&animatemodel_cache.frameblend, &ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend))) != 0;
-       if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.skeletonindex))) skeletonindex = (int)val->_float - 1;
+       skeletonindex = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.skeletonindex) - 1;
        if (!(skeletonindex >= 0 && skeletonindex < MAX_EDICTS && (skeleton = prog->skeletons[skeletonindex]) && skeleton->model->num_bones == ed->priv.server->skeleton.model->num_bones))
                skeleton = NULL;
        need |= (animatemodel_cache.skeleton_p != skeleton);
index 7ad872f..f2c14db 100644 (file)
@@ -212,7 +212,7 @@ Sets everything to NULL
 */
 void PRVM_ED_ClearEdict (prvm_edict_t *e)
 {
-       memset (e->fields.vp, 0, prog->progs->entityfields * 4);
+       memset (e->fields.vp, 0, prog->entityfields * 4);
        e->priv.required->free = false;
 
        // AK: Let the init_edict function determine if something needs to be initialized
@@ -337,7 +337,7 @@ ddef_t *PRVM_ED_GlobalAtOfs (int ofs)
        ddef_t          *def;
        int                     i;
 
-       for (i=0 ; i<prog->progs->numglobaldefs ; i++)
+       for (i = 0;i < prog->numglobaldefs;i++)
        {
                def = &prog->globaldefs[i];
                if (def->ofs == ofs)
@@ -356,7 +356,7 @@ ddef_t *PRVM_ED_FieldAtOfs (int ofs)
        ddef_t          *def;
        int                     i;
 
-       for (i=0 ; i<prog->progs->numfielddefs ; i++)
+       for (i = 0;i < prog->numfielddefs;i++)
        {
                def = &prog->fielddefs[i];
                if (def->ofs == ofs)
@@ -375,7 +375,7 @@ ddef_t *PRVM_ED_FindField (const char *name)
        ddef_t *def;
        int i;
 
-       for (i=0 ; i<prog->progs->numfielddefs ; i++)
+       for (i = 0;i < prog->numfielddefs;i++)
        {
                def = &prog->fielddefs[i];
                if (!strcmp(PRVM_GetString(def->s_name), name))
@@ -394,7 +394,7 @@ ddef_t *PRVM_ED_FindGlobal (const char *name)
        ddef_t *def;
        int i;
 
-       for (i=0 ; i<prog->progs->numglobaldefs ; i++)
+       for (i = 0;i < prog->numglobaldefs;i++)
        {
                def = &prog->globaldefs[i];
                if (!strcmp(PRVM_GetString(def->s_name), name))
@@ -414,7 +414,7 @@ mfunction_t *PRVM_ED_FindFunction (const char *name)
        mfunction_t             *func;
        int                             i;
 
-       for (i=0 ; i<prog->progs->numfunctions ; i++)
+       for (i = 0;i < prog->numfunctions;i++)
        {
                func = &prog->functions[i];
                if (!strcmp(PRVM_GetString(func->s_name), name))
@@ -645,7 +645,7 @@ void PRVM_ED_Print(prvm_edict_t *ed, const char *wildcard_fieldname)
 
        tempstring[0] = 0;
        dpsnprintf(tempstring, sizeof(tempstring), "\n%s EDICT %i:\n", PRVM_NAME, PRVM_NUM_FOR_EDICT(ed));
-       for (i=1 ; i<prog->progs->numfielddefs ; i++)
+       for (i = 1;i < prog->numfielddefs;i++)
        {
                d = &prog->fielddefs[i];
                name = PRVM_GetString(d->s_name);
@@ -725,7 +725,7 @@ void PRVM_ED_Write (qfile_t *f, prvm_edict_t *ed)
                return;
        }
 
-       for (i=1 ; i<prog->progs->numfielddefs ; i++)
+       for (i = 1;i < prog->numfielddefs;i++)
        {
                d = &prog->fielddefs[i];
                name = PRVM_GetString(d->s_name);
@@ -902,7 +902,7 @@ void PRVM_ED_WriteGlobals (qfile_t *f)
        int                     type;
 
        FS_Print(f,"{\n");
-       for (i=0 ; i<prog->progs->numglobaldefs ; i++)
+       for (i = 0;i < prog->numglobaldefs;i++)
        {
                def = &prog->globaldefs[i];
                type = def->type;
@@ -1430,7 +1430,7 @@ void PRVM_ED_LoadFromFile (const char *data)
 
                // clear it
                if (ent != prog->edicts)        // hack
-                       memset (ent->fields.vp, 0, prog->progs->entityfields * 4);
+                       memset (ent->fields.vp, 0, prog->entityfields * 4);
 
                data = PRVM_ED_ParseEdict (data, ent);
                parsed++;
@@ -1446,7 +1446,7 @@ void PRVM_ED_LoadFromFile (const char *data)
                if (prog->funcoffsets.SV_OnEntityPreSpawnFunction)
                {
                        // self = ent
-                       PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict = PRVM_EDICT_TO_PROG(ent);
+                       PRVM_GLOBALFIELDEDICT(prog->globaloffsets.self) = PRVM_EDICT_TO_PROG(ent);
                        PRVM_ExecuteProgram (prog->funcoffsets.SV_OnEntityPreSpawnFunction, "QC function SV_OnEntityPreSpawnFunction is missing");
                }
 
@@ -1462,7 +1462,7 @@ void PRVM_ED_LoadFromFile (const char *data)
                if(!ent->priv.required->free)
                if(prog->globaloffsets.self >= 0 && prog->fieldoffsets.classname >= 0)
                {
-                       string_t handle =  PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.classname)->string;
+                       string_t handle =  PRVM_EDICTFIELDSTRING(ent, prog->fieldoffsets.classname);
                        if (!handle)
                        {
                                Con_Print("No classname for:\n");
@@ -1475,7 +1475,7 @@ void PRVM_ED_LoadFromFile (const char *data)
                        funcname = PRVM_GetString(handle);
                        func = PRVM_ED_FindFunction (va("spawnfunc_%s", funcname));
                        if(!func)
-                               if(prog->globaloffsets.require_spawnfunc_prefix < 0)
+                               if(!PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.require_spawnfunc_prefix))
                                        func = PRVM_ED_FindFunction (funcname);
 
                        if (!func)
@@ -1484,7 +1484,7 @@ void PRVM_ED_LoadFromFile (const char *data)
                                if (prog->funcoffsets.SV_OnEntityNoSpawnFunction)
                                {
                                        // self = ent
-                                       PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict = PRVM_EDICT_TO_PROG(ent);
+                                       PRVM_GLOBALFIELDEDICT(prog->globaloffsets.self) = PRVM_EDICT_TO_PROG(ent);
                                        PRVM_ExecuteProgram (prog->funcoffsets.SV_OnEntityNoSpawnFunction, "QC function SV_OnEntityNoSpawnFunction is missing");
                                }
                                else
@@ -1501,7 +1501,7 @@ void PRVM_ED_LoadFromFile (const char *data)
                        else
                        {
                                // self = ent
-                               PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict = PRVM_EDICT_TO_PROG(ent);
+                               PRVM_GLOBALFIELDEDICT(prog->globaloffsets.self) = PRVM_EDICT_TO_PROG(ent);
                                PRVM_ExecuteProgram (func - prog->functions, "");
                        }
                }
@@ -1510,7 +1510,7 @@ void PRVM_ED_LoadFromFile (const char *data)
                if (prog->funcoffsets.SV_OnEntityPostSpawnFunction)
                {
                        // self = ent
-                       PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict = PRVM_EDICT_TO_PROG(ent);
+                       PRVM_GLOBALFIELDEDICT(prog->globaloffsets.self) = PRVM_EDICT_TO_PROG(ent);
                        PRVM_ExecuteProgram (prog->funcoffsets.SV_OnEntityPostSpawnFunction, "QC function SV_OnEntityPostSpawnFunction is missing");
                }
 
@@ -2060,7 +2060,8 @@ void PRVM_LoadLNO( const char *progname ) {
 <Spike>    SafeWrite (h, &numstatements, sizeof(int));
 <Spike>    SafeWrite (h, statement_linenums, numstatements*sizeof(int));
 */
-       if( (unsigned) filesize < (6 + prog->progs->numstatements) * sizeof( int ) ) {
+       if ((unsigned int)filesize < (6 + prog->progs_numstatements) * sizeof(int))
+       {
                Mem_Free(lno);
                return;
        }
@@ -2068,13 +2069,13 @@ void PRVM_LoadLNO( const char *progname ) {
        header = (unsigned int *) lno;
        if( header[ 0 ] == *(unsigned int *) "LNOF" &&
                LittleLong( header[ 1 ] ) == 1 &&
-               (unsigned int)LittleLong( header[ 2 ] ) == (unsigned int)prog->progs->numglobaldefs &&
-               (unsigned int)LittleLong( header[ 3 ] ) == (unsigned int)prog->progs->numglobals &&
-               (unsigned int)LittleLong( header[ 4 ] ) == (unsigned int)prog->progs->numfielddefs &&
-               (unsigned int)LittleLong( header[ 5 ] ) == (unsigned int)prog->progs->numstatements )
+               (unsigned int)LittleLong( header[ 2 ] ) == (unsigned int)prog->progs_numglobaldefs &&
+               (unsigned int)LittleLong( header[ 3 ] ) == (unsigned int)prog->progs_numglobals &&
+               (unsigned int)LittleLong( header[ 4 ] ) == (unsigned int)prog->progs_numfielddefs &&
+               (unsigned int)LittleLong( header[ 5 ] ) == (unsigned int)prog->progs_numstatements )
        {
-               prog->statement_linenums = (int *)Mem_Alloc(prog->progs_mempool, prog->progs->numstatements * sizeof( int ) );
-               memcpy( prog->statement_linenums, (int *) lno + 6, prog->progs->numstatements * sizeof( int ) );
+               prog->statement_linenums = (int *)Mem_Alloc(prog->progs_mempool, prog->progs_numstatements * sizeof( int ) );
+               memcpy( prog->statement_linenums, (int *) lno + 6, prog->progs_numstatements * sizeof( int ) );
        }
        Mem_Free( lno );
 }
@@ -2084,43 +2085,73 @@ void PRVM_LoadLNO( const char *progname ) {
 PRVM_LoadProgs
 ===============
 */
-void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, char **required_global)
+void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **required_func, int numrequiredfields, prvm_required_field_t *required_field, int numrequiredglobals, prvm_required_field_t *required_global)
 {
        int i;
-       dstatement_t *st;
+       dprograms_t *dprograms;
+       dstatement_t *instatements;
        ddef_t *infielddefs;
-       dfunction_t *dfunctions;
+       ddef_t *inglobaldefs;
+       float *inglobals;
+       dfunction_t *infunctions;
+       char *instrings;
        fs_offset_t filesize;
+       int requiredglobalspace;
+       int op;
+       int a;
+       int b;
+       int c;
 
-       if( prog->loaded ) {
+       if (prog->loaded)
                PRVM_ERROR ("PRVM_LoadProgs: there is already a %s program loaded!", PRVM_NAME );
-       }
 
-       prog->progs = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false, &filesize);
-       if (prog->progs == NULL || filesize < (fs_offset_t)sizeof(dprograms_t))
+       dprograms = (dprograms_t *)FS_LoadFile (filename, prog->progs_mempool, false, &filesize);
+       if (dprograms == NULL || filesize < (fs_offset_t)sizeof(dprograms_t))
                PRVM_ERROR ("PRVM_LoadProgs: couldn't load %s for %s", filename, PRVM_NAME);
        // TODO bounds check header fields (e.g. numstatements), they must never go behind end of file
 
        Con_DPrintf("%s programs occupy %iK.\n", PRVM_NAME, (int)(filesize/1024));
 
-       prog->filecrc = CRC_Block((unsigned char *)prog->progs, filesize);
-
-// byte swap the header
-       for (i = 0;i < (int) sizeof(*prog->progs) / 4;i++)
-               ((int *)prog->progs)[i] = LittleLong ( ((int *)prog->progs)[i] );
-
-       if (prog->progs->version != PROG_VERSION)
-               PRVM_ERROR ("%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, prog->progs->version, PROG_VERSION);
-       if (prog->progs->crc != prog->headercrc && prog->progs->crc != prog->headercrc2)
-               PRVM_ERROR ("%s: %s system vars have been modified (CRC of progs.dat systemvars %i != engine %i), progdefs.h is out of date", PRVM_NAME, filename, prog->progs->crc, prog->headercrc);
+       requiredglobalspace = 0;
+       for (i = 0;i < numrequiredglobals;i++)
+               requiredglobalspace += required_global[i].type == ev_vector ? 3 : 1;
 
-       //prog->functions = (dfunction_t *)((unsigned char *)progs + progs->ofs_functions);
-       dfunctions = (dfunction_t *)((unsigned char *)prog->progs + prog->progs->ofs_functions);
+       prog->filecrc = CRC_Block((unsigned char *)dprograms, filesize);
 
-       if (prog->progs->ofs_strings + prog->progs->numstrings >= (int)filesize)
+// byte swap the header
+       prog->progs_version = LittleLong(dprograms->version);
+       prog->progs_crc = LittleLong(dprograms->crc);
+       if (prog->progs_version != PROG_VERSION)
+               PRVM_ERROR ("%s: %s has wrong version number (%i should be %i)", PRVM_NAME, filename, prog->progs_version, PROG_VERSION);
+       if (prog->progs_crc != prog->headercrc && prog->progs_crc != prog->headercrc2)
+               PRVM_ERROR ("%s: %s system vars have been modified (CRC of progs.dat systemvars %i != engine %i), progdefs.h is out of date", PRVM_NAME, filename, prog->progs_crc, prog->headercrc);
+       instatements = (dstatement_t *)((unsigned char *)dprograms + LittleLong(dprograms->ofs_statements));
+       prog->progs_numstatements = LittleLong(dprograms->numstatements);
+       inglobaldefs = (ddef_t *)((unsigned char *)dprograms + LittleLong(dprograms->ofs_globaldefs));
+       prog->progs_numglobaldefs = LittleLong(dprograms->numglobaldefs);
+       infielddefs = (ddef_t *)((unsigned char *)dprograms + LittleLong(dprograms->ofs_fielddefs));
+       prog->progs_numfielddefs = LittleLong(dprograms->numfielddefs);
+       infunctions = (dfunction_t *)((unsigned char *)dprograms + LittleLong(dprograms->ofs_functions));
+       prog->progs_numfunctions = LittleLong(dprograms->numfunctions);
+       instrings = (char *)((unsigned char *)dprograms + LittleLong(dprograms->ofs_strings));
+       prog->progs_numstrings = LittleLong(dprograms->numstrings);
+       inglobals = (float *)((unsigned char *)dprograms + LittleLong(dprograms->ofs_globals));
+       prog->progs_numglobals = LittleLong(dprograms->numglobals);
+       prog->progs_entityfields = LittleLong(dprograms->entityfields);
+
+       prog->numstatements = prog->progs_numstatements;
+       prog->numglobaldefs = prog->progs_numglobaldefs;
+       prog->numfielddefs = prog->progs_numfielddefs;
+       prog->numfunctions = prog->progs_numfunctions;
+       prog->numstrings = prog->progs_numstrings;
+       prog->numglobals = prog->progs_numglobals;
+       prog->entityfields = prog->progs_entityfields;
+
+       if (LittleLong(dprograms->ofs_strings) + prog->progs_numstrings >= (int)filesize)
                PRVM_ERROR ("%s: %s strings go past end of file", PRVM_NAME, filename);
-       prog->strings = (char *)prog->progs + prog->progs->ofs_strings;
-       prog->stringssize = prog->progs->numstrings;
+       prog->strings = (char *)Mem_Alloc(prog->progs_mempool, prog->progs_numstrings);
+       memcpy(prog->strings, (char *)dprograms + LittleLong(dprograms->ofs_strings), prog->progs_numstrings);
+       prog->stringssize = prog->progs_numstrings;
 
        prog->numknownstrings = 0;
        prog->maxknownstrings = 0;
@@ -2129,106 +2160,119 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
 
        Mem_ExpandableArray_NewArray(&prog->stringbuffersarray, prog->progs_mempool, sizeof(prvm_stringbuffer_t), 64);
 
-       prog->globaldefs = (ddef_t *)((unsigned char *)prog->progs + prog->progs->ofs_globaldefs);
-
-       // we need to expand the fielddefs list to include all the engine fields,
-       // so allocate a new place for it
-       infielddefs = (ddef_t *)((unsigned char *)prog->progs + prog->progs->ofs_fielddefs);
-       //                                                                                              ( + DPFIELDS                       )
-       prog->fielddefs = (ddef_t *)Mem_Alloc(prog->progs_mempool, (prog->progs->numfielddefs + numrequiredfields) * sizeof(ddef_t));
-
-       prog->statements = (dstatement_t *)((unsigned char *)prog->progs + prog->progs->ofs_statements);
-
-       prog->statement_profile = (double *)Mem_Alloc(prog->progs_mempool, prog->progs->numstatements * sizeof(*prog->statement_profile));
-
-       //pr_global_struct = (globalvars_t *)((unsigned char *)progs + progs->ofs_globals);
-       prog->globals.generic = (float *)((unsigned char *)prog->progs + prog->progs->ofs_globals);
-
-// byte swap the lumps
-       for (i=0 ; i<prog->progs->numstatements ; i++)
-       {
-               prog->statements[i].op = LittleShort(prog->statements[i].op);
-               prog->statements[i].a = LittleShort(prog->statements[i].a);
-               prog->statements[i].b = LittleShort(prog->statements[i].b);
-               prog->statements[i].c = LittleShort(prog->statements[i].c);
-       }
-
-       prog->functions = (mfunction_t *)Mem_Alloc(prog->progs_mempool, sizeof(mfunction_t) * prog->progs->numfunctions);
-       for (i = 0;i < prog->progs->numfunctions;i++)
-       {
-               prog->functions[i].first_statement = LittleLong (dfunctions[i].first_statement);
-               prog->functions[i].parm_start = LittleLong (dfunctions[i].parm_start);
-               prog->functions[i].s_name = LittleLong (dfunctions[i].s_name);
-               prog->functions[i].s_file = LittleLong (dfunctions[i].s_file);
-               prog->functions[i].numparms = LittleLong (dfunctions[i].numparms);
-               prog->functions[i].locals = LittleLong (dfunctions[i].locals);
-               memcpy(prog->functions[i].parm_size, dfunctions[i].parm_size, sizeof(dfunctions[i].parm_size));
-               if(prog->functions[i].first_statement >= prog->progs->numstatements)
+       // we need to expand the globaldefs and fielddefs to include engine defs
+       prog->globaldefs = (ddef_t *)Mem_Alloc(prog->progs_mempool, (prog->progs_numglobaldefs + numrequiredglobals) * sizeof(ddef_t));
+       prog->globals.generic = (float *)Mem_Alloc(prog->progs_mempool, (prog->progs_numglobals + requiredglobalspace) * sizeof(float));
+       prog->fielddefs = (ddef_t *)Mem_Alloc(prog->progs_mempool, (prog->progs_numfielddefs + numrequiredfields) * sizeof(ddef_t));
+       // we need to convert the statements to our memory format
+       prog->statements = (mstatement_t *)Mem_Alloc(prog->progs_mempool, prog->progs_numstatements * sizeof(mstatement_t));
+       // allocate space for profiling statement usage
+       prog->statement_profile = (double *)Mem_Alloc(prog->progs_mempool, prog->progs_numstatements * sizeof(*prog->statement_profile));
+       // functions need to be converted to the memory format
+       prog->functions = (mfunction_t *)Mem_Alloc(prog->progs_mempool, sizeof(mfunction_t) * prog->progs_numfunctions);
+
+       for (i = 0;i < prog->progs_numfunctions;i++)
+       {
+               prog->functions[i].first_statement = LittleLong(infunctions[i].first_statement);
+               prog->functions[i].parm_start = LittleLong(infunctions[i].parm_start);
+               prog->functions[i].s_name = LittleLong(infunctions[i].s_name);
+               prog->functions[i].s_file = LittleLong(infunctions[i].s_file);
+               prog->functions[i].numparms = LittleLong(infunctions[i].numparms);
+               prog->functions[i].locals = LittleLong(infunctions[i].locals);
+               memcpy(prog->functions[i].parm_size, infunctions[i].parm_size, sizeof(infunctions[i].parm_size));
+               if(prog->functions[i].first_statement >= prog->numstatements)
                        PRVM_ERROR("PRVM_LoadProgs: out of bounds function statement (function %d) in %s", i, PRVM_NAME);
                // TODO bounds check parm_start, s_name, s_file, numparms, locals, parm_size
        }
 
-       for (i=0 ; i<prog->progs->numglobaldefs ; i++)
+       // copy the globaldefs to the new globaldefs list
+       for (i=0 ; i<prog->numglobaldefs ; i++)
        {
-               prog->globaldefs[i].type = LittleShort (prog->globaldefs[i].type);
-               prog->globaldefs[i].ofs = LittleShort (prog->globaldefs[i].ofs);
-               prog->globaldefs[i].s_name = LittleLong (prog->globaldefs[i].s_name);
+               prog->globaldefs[i].type = LittleShort(inglobaldefs[i].type);
+               prog->globaldefs[i].ofs = LittleShort(inglobaldefs[i].ofs);
+               prog->globaldefs[i].s_name = LittleLong(inglobaldefs[i].s_name);
                // TODO bounds check ofs, s_name
        }
 
+       // append the required globals
+       for (i = 0;i < numrequiredglobals;i++)
+       {
+               prog->globaldefs[prog->numglobaldefs].type = required_global[i].type;
+               prog->globaldefs[prog->numglobaldefs].ofs = prog->numglobals;
+               prog->globaldefs[prog->numglobaldefs].s_name = PRVM_SetEngineString(required_global[i].name);
+               if (prog->globaldefs[prog->numglobaldefs].type == ev_vector)
+                       prog->numglobals += 3;
+               else
+                       prog->numglobals++;
+               prog->numglobaldefs++;
+       }
+
        // copy the progs fields to the new fields list
-       for (i = 0;i < prog->progs->numfielddefs;i++)
+       for (i = 0;i < prog->numfielddefs;i++)
        {
-               prog->fielddefs[i].type = LittleShort (infielddefs[i].type);
+               prog->fielddefs[i].type = LittleShort(infielddefs[i].type);
                if (prog->fielddefs[i].type & DEF_SAVEGLOBAL)
                        PRVM_ERROR ("PRVM_LoadProgs: prog->fielddefs[i].type & DEF_SAVEGLOBAL in %s", PRVM_NAME);
-               prog->fielddefs[i].ofs = LittleShort (infielddefs[i].ofs);
-               prog->fielddefs[i].s_name = LittleLong (infielddefs[i].s_name);
+               prog->fielddefs[i].ofs = LittleShort(infielddefs[i].ofs);
+               prog->fielddefs[i].s_name = LittleLong(infielddefs[i].s_name);
                // TODO bounds check ofs, s_name
        }
 
        // append the required fields
-       for (i = 0;i < (int) numrequiredfields;i++)
+       for (i = 0;i < numrequiredfields;i++)
        {
-               prog->fielddefs[prog->progs->numfielddefs].type = required_field[i].type;
-               prog->fielddefs[prog->progs->numfielddefs].ofs = prog->progs->entityfields;
-               prog->fielddefs[prog->progs->numfielddefs].s_name = PRVM_SetEngineString(required_field[i].name);
-               // TODO bounds check ofs, s_name
-               if (prog->fielddefs[prog->progs->numfielddefs].type == ev_vector)
-                       prog->progs->entityfields += 3;
+               prog->fielddefs[prog->numfielddefs].type = required_field[i].type;
+               prog->fielddefs[prog->numfielddefs].ofs = prog->entityfields;
+               prog->fielddefs[prog->numfielddefs].s_name = PRVM_SetEngineString(required_field[i].name);
+               if (prog->fielddefs[prog->numfielddefs].type == ev_vector)
+                       prog->entityfields += 3;
                else
-                       prog->progs->entityfields++;
-               prog->progs->numfielddefs++;
+                       prog->entityfields++;
+               prog->numfielddefs++;
        }
-       prog->entityfields = prog->progs->entityfields;
 
-       // check required functions
-       for(i=0 ; i < numrequiredfunc ; i++)
-               if(PRVM_ED_FindFunction(required_func[i]) == 0)
-                       PRVM_ERROR("%s: %s not found in %s",PRVM_NAME, required_func[i], filename);
-
-       // check required globals
-       for(i=0 ; i < numrequiredglobals ; i++)
-               if(PRVM_ED_FindGlobal(required_global[i]) == 0)
-                       PRVM_ERROR("%s: %s not found in %s",PRVM_NAME, required_global[i], filename);
+       // LordHavoc: TODO: reorder globals to match engine struct
+       // LordHavoc: TODO: reorder fields to match engine struct
+#define remapglobal(index) (index)
+#define remapfield(index) (index)
 
-       for (i=0 ; i<prog->progs->numglobals ; i++)
-               ((int *)prog->globals.generic)[i] = LittleLong (((int *)prog->globals.generic)[i]);
+       // copy globals
+       for (i = 0;i < prog->progs_numglobals;i++)
+               ((int *)prog->globals.generic)[remapglobal(i)] = LittleLong(((int *)inglobals)[i]);
 
-       // LordHavoc: bounds check anything static
-       for (i = 0,st = prog->statements;i < prog->progs->numstatements;i++,st++)
+       // LordHavoc: TODO: support 32bit progs statement formats
+       // copy, remap globals in statements, bounds check
+       for (i = 0;i < prog->progs_numstatements;i++)
        {
-               switch (st->op)
+               op = (opcode_t)LittleShort(instatements[i].op);
+               a = (unsigned short)LittleShort(instatements[i].a);
+               b = (unsigned short)LittleShort(instatements[i].b);
+               c = (unsigned short)LittleShort(instatements[i].c);
+               switch (op)
                {
                case OP_IF:
                case OP_IFNOT:
-                       if ((unsigned short) st->a >= prog->progs->numglobals || st->b + i < 0 || st->b + i >= prog->progs->numstatements)
+                       b = (short)b;
+                       if (a >= prog->progs_numglobals || b + i < 0 || b + i >= prog->progs_numstatements)
                                PRVM_ERROR("PRVM_LoadProgs: out of bounds IF/IFNOT (statement %d) in %s", i, PRVM_NAME);
+                       prog->statements[i].op = op;
+                       prog->statements[i].operand[0] = remapglobal(a);
+                       prog->statements[i].operand[1] = -1;
+                       prog->statements[i].operand[2] = -1;
+                       prog->statements[i].jumpabsolute = i + b;
                        break;
                case OP_GOTO:
-                       if (st->a + i < 0 || st->a + i >= prog->progs->numstatements)
+                       a = (short)a;
+                       if (a + i < 0 || a + i >= prog->progs_numstatements)
                                PRVM_ERROR("PRVM_LoadProgs: out of bounds GOTO (statement %d) in %s", i, PRVM_NAME);
+                       prog->statements[i].op = op;
+                       prog->statements[i].operand[0] = -1;
+                       prog->statements[i].operand[1] = -1;
+                       prog->statements[i].operand[2] = -1;
+                       prog->statements[i].jumpabsolute = i + a;
                        break;
+               default:
+                       Con_DPrintf("PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", (int)op, i, PRVM_NAME);
                // global global global
                case OP_ADD_F:
                case OP_ADD_V:
@@ -2264,8 +2308,13 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_LOAD_S:
                case OP_LOAD_FNC:
                case OP_LOAD_V:
-                       if ((unsigned short) st->a >= prog->progs->numglobals || (unsigned short) st->b >= prog->progs->numglobals || (unsigned short) st->c >= prog->progs->numglobals)
+                       if (a >= prog->progs_numglobals || b >= prog->progs_numglobals || c >= prog->progs_numglobals)
                                PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d)", i);
+                       prog->statements[i].op = op;
+                       prog->statements[i].operand[0] = remapglobal(a);
+                       prog->statements[i].operand[1] = remapglobal(b);
+                       prog->statements[i].operand[2] = remapglobal(c);
+                       prog->statements[i].jumpabsolute = -1;
                        break;
                // global none global
                case OP_NOT_F:
@@ -2273,8 +2322,13 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_NOT_S:
                case OP_NOT_FNC:
                case OP_NOT_ENT:
-                       if ((unsigned short) st->a >= prog->progs->numglobals || (unsigned short) st->c >= prog->progs->numglobals)
+                       if (a >= prog->progs_numglobals || c >= prog->progs_numglobals)
                                PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
+                       prog->statements[i].op = op;
+                       prog->statements[i].operand[0] = remapglobal(a);
+                       prog->statements[i].operand[1] = -1;
+                       prog->statements[i].operand[2] = remapglobal(c);
+                       prog->statements[i].jumpabsolute = -1;
                        break;
                // 2 globals
                case OP_STOREP_F:
@@ -2290,8 +2344,13 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_STATE:
                case OP_STOREP_V:
                case OP_STORE_V:
-                       if ((unsigned short) st->a >= prog->progs->numglobals || (unsigned short) st->b >= prog->progs->numglobals)
+                       if (a >= prog->progs_numglobals || b >= prog->progs_numglobals)
                                PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
+                       prog->statements[i].op = op;
+                       prog->statements[i].operand[0] = remapglobal(a);
+                       prog->statements[i].operand[1] = remapglobal(b);
+                       prog->statements[i].operand[2] = -1;
+                       prog->statements[i].jumpabsolute = -1;
                        break;
                // 1 global
                case OP_CALL0:
@@ -2305,19 +2364,21 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                case OP_CALL8:
                case OP_DONE:
                case OP_RETURN:
-                       if ((unsigned short) st->a >= prog->progs->numglobals)
+                       if ( a >= prog->progs_numglobals)
                                PRVM_ERROR("PRVM_LoadProgs: out of bounds global index (statement %d) in %s", i, PRVM_NAME);
-                       break;
-               default:
-                       Con_DPrintf("PRVM_LoadProgs: unknown opcode %d at statement %d in %s\n", st->op, i, PRVM_NAME);
+                       prog->statements[i].op = op;
+                       prog->statements[i].operand[0] = remapglobal(a);
+                       prog->statements[i].operand[1] = -1;
+                       prog->statements[i].operand[2] = -1;
+                       prog->statements[i].jumpabsolute = -1;
                        break;
                }
        }
-       if(prog->progs->numstatements < 1)
+       if(prog->numstatements < 1)
        {
                PRVM_ERROR("PRVM_LoadProgs: empty program in %s", PRVM_NAME);
        }
-       else switch(prog->statements[prog->progs->numstatements - 1].op)
+       else switch(prog->statements[prog->numstatements - 1].op)
        {
                case OP_RETURN:
                case OP_GOTO:
@@ -2328,6 +2389,15 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                        break;
        }
 
+       // we're done with the file now
+       Mem_Free(dprograms);
+       dprograms = NULL;
+
+       // check required functions
+       for(i=0 ; i < numrequiredfunc ; i++)
+               if(PRVM_ED_FindFunction(required_func[i]) == 0)
+                       PRVM_ERROR("%s: %s not found in %s",PRVM_NAME, required_func[i], filename);
+
        PRVM_LoadLNO(filename);
 
        PRVM_Init_Exec();
@@ -2340,7 +2410,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                const char *realfilename = (strcmp(PRVM_NAME, "client") ? filename : csqc_progname.string);
                if(deftrans) // once we have dotranslate_ strings, ALWAYS use the opt-in method!
                {
-                       for (i=0 ; i<prog->progs->numglobaldefs ; i++)
+                       for (i=0 ; i<prog->numglobaldefs ; i++)
                        {
                                const char *name;
                                name = PRVM_GetString(prog->globaldefs[i].s_name);
@@ -2358,14 +2428,14 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                        Con_Printf("Dumping to %s.pot\n", realfilename);
                        if(f)
                        {
-                               for (i=0 ; i<prog->progs->numglobaldefs ; i++)
+                               for (i=0 ; i<prog->numglobaldefs ; i++)
                                {
                                        const char *name;
                                        name = PRVM_GetString(prog->globaldefs[i].s_name);
                                        if(deftrans ? (!name || strncmp(name, "notranslate_", 12)) : (name && !strncmp(name, "dotranslate_", 12)))
                                        if((prog->globaldefs[i].type & ~DEF_SAVEGLOBAL) == ev_string)
                                        {
-                                               prvm_eval_t *val = (prvm_eval_t *)(prog->globals.generic + prog->globaldefs[i].ofs);
+                                               prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
                                                const char *value = PRVM_GetString(val->string);
                                                if(*value)
                                                {
@@ -2383,14 +2453,14 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                        po_t *po = PRVM_PO_Load(va("%s.%s.po", realfilename, prvm_language.string), prog->progs_mempool);
                        if(po)
                        {
-                               for (i=0 ; i<prog->progs->numglobaldefs ; i++)
+                               for (i=0 ; i<prog->numglobaldefs ; i++)
                                {
                                        const char *name;
                                        name = PRVM_GetString(prog->globaldefs[i].s_name);
                                        if(deftrans ? (!name || strncmp(name, "notranslate_", 12)) : (name && !strncmp(name, "dotranslate_", 12)))
                                        if((prog->globaldefs[i].type & ~DEF_SAVEGLOBAL) == ev_string)
                                        {
-                                               prvm_eval_t *val = (prvm_eval_t *)(prog->globals.generic + prog->globaldefs[i].ofs);
+                                               prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
                                                const char *value = PRVM_GetString(val->string);
                                                if(*value)
                                                {
@@ -2404,7 +2474,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                }
        }
 
-       for (i=0 ; i<prog->progs->numglobaldefs ; i++)
+       for (i=0 ; i<prog->numglobaldefs ; i++)
        {
                const char *name;
                name = PRVM_GetString(prog->globaldefs[i].s_name);
@@ -2414,7 +2484,7 @@ void PRVM_LoadProgs (const char * filename, int numrequiredfunc, const char **re
                        && !(strlen(name) > 1 && name[strlen(name)-2] == '_' && (name[strlen(name)-1] == 'x' || name[strlen(name)-1] == 'y' || name[strlen(name)-1] == 'z'))
                )
                {
-                       prvm_eval_t *val = (prvm_eval_t *)(prog->globals.generic + prog->globaldefs[i].ofs);
+                       prvm_eval_t *val = PRVM_GLOBALFIELDVALUE(prog->globaldefs[i].ofs);
                        cvar_t *cvar = Cvar_FindVar(name + 9);
                        //Con_Printf("PRVM_LoadProgs: autocvar global %s in %s, processing...\n", name, PRVM_NAME);
                        if(!cvar)
@@ -2540,13 +2610,13 @@ void PRVM_Fields_f (void)
        if(!PRVM_SetProgFromString(Cmd_Argv(1)))
                return;
 
-       counts = (int *)Mem_Alloc(tempmempool, prog->progs->numfielddefs * sizeof(int));
+       counts = (int *)Mem_Alloc(tempmempool, prog->numfielddefs * sizeof(int));
        for (ednum = 0;ednum < prog->max_edicts;ednum++)
        {
                ed = PRVM_EDICT_NUM(ednum);
                if (ed->priv.required->free)
                        continue;
-               for (i = 1;i < prog->progs->numfielddefs;i++)
+               for (i = 1;i < prog->numfielddefs;i++)
                {
                        d = &prog->fielddefs[i];
                        name = PRVM_GetString(d->s_name);
@@ -2567,7 +2637,7 @@ void PRVM_Fields_f (void)
        used = 0;
        usedamount = 0;
        tempstring[0] = 0;
-       for (i = 0;i < prog->progs->numfielddefs;i++)
+       for (i = 0;i < prog->numfielddefs;i++)
        {
                d = &prog->fielddefs[i];
                name = PRVM_GetString(d->s_name);
@@ -2629,7 +2699,7 @@ void PRVM_Fields_f (void)
                }
        }
        Mem_Free(counts);
-       Con_Printf("%s: %i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", PRVM_NAME, prog->progs->entityfields, used, prog->progs->entityfields * 4, usedamount * 4, prog->max_edicts, prog->progs->entityfields * 4 * prog->max_edicts, usedamount * 4 * prog->max_edicts);
+       Con_Printf("%s: %i entity fields (%i in use), totalling %i bytes per edict (%i in use), %i edicts allocated, %i bytes total spent on edict fields (%i needed)\n", PRVM_NAME, prog->entityfields, used, prog->entityfields * 4, usedamount * 4, prog->max_edicts, prog->entityfields * 4 * prog->max_edicts, usedamount * 4 * prog->max_edicts);
 
        PRVM_End;
 }
@@ -2663,7 +2733,7 @@ void PRVM_Globals_f (void)
 
        Con_Printf("%s :", PRVM_NAME);
 
-       for (i = 0;i < prog->progs->numglobaldefs;i++)
+       for (i = 0;i < prog->numglobaldefs;i++)
        {
                if(wildcard)
                        if( !matchpattern( PRVM_GetString(prog->globaldefs[i].s_name), wildcard, 1) )
@@ -2673,7 +2743,7 @@ void PRVM_Globals_f (void)
                        }
                Con_Printf("%s\n", PRVM_GetString(prog->globaldefs[i].s_name));
        }
-       Con_Printf("%i global variables, %i culled, totalling %i bytes\n", prog->progs->numglobals, numculled, prog->progs->numglobals * 4);
+       Con_Printf("%i global variables, %i culled, totalling %i bytes\n", prog->numglobals, numculled, prog->numglobals * 4);
 
        PRVM_End;
 }
@@ -2699,7 +2769,7 @@ void PRVM_Global_f(void)
        if( !global )
                Con_Printf( "No global '%s' in %s!\n", Cmd_Argv(2), Cmd_Argv(1) );
        else
-               Con_Printf( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( (etype_t)global->type, (prvm_eval_t *) &prog->globals.generic[ global->ofs ] ) );
+               Con_Printf( "%s: %s\n", Cmd_Argv(2), PRVM_ValueString( (etype_t)global->type, PRVM_GLOBALFIELDVALUE(global->ofs) ) );
        PRVM_End;
 }
 
@@ -2812,9 +2882,12 @@ void _PRVM_Free(void *buffer, const char *filename, int fileline)
 
 void _PRVM_FreeAll(const char *filename, int fileline)
 {
-       prog->progs = NULL;
-       prog->fielddefs = NULL;
        prog->functions = NULL;
+       prog->strings = NULL;
+       prog->fielddefs = NULL;
+       prog->globaldefs = NULL;
+       prog->statements = NULL;
+       // FIXME: what about knownstrings?
        _Mem_EmptyPool(prog->progs_mempool, filename, fileline);
 }
 
@@ -3061,12 +3134,12 @@ static qboolean PRVM_IsStringReferenced(string_t string)
 {
        int i, j;
 
-       for (i = 0;i < prog->progs->numglobaldefs;i++)
+       for (i = 0;i < prog->numglobaldefs;i++)
        {
                ddef_t *d = &prog->globaldefs[i];
                if((etype_t)((int) d->type & ~DEF_SAVEGLOBAL) != ev_string)
                        continue;
-               if(string == ((prvm_eval_t *) &prog->globals.generic[d->ofs])->string)
+               if(string == PRVM_GLOBALFIELDSTRING(d->ofs))
                        return true;
        }
 
@@ -3075,12 +3148,12 @@ static qboolean PRVM_IsStringReferenced(string_t string)
                prvm_edict_t *ed = PRVM_EDICT_NUM(j);
                if (ed->priv.required->free)
                        continue;
-               for (i=0; i<prog->progs->numfielddefs; ++i)
+               for (i=0; i<prog->numfielddefs; ++i)
                {
                        ddef_t *d = &prog->fielddefs[i];
                        if((etype_t)((int) d->type & ~DEF_SAVEGLOBAL) != ev_string)
                                continue;
-                       if(string == ((prvm_eval_t *) &ed->fields.vp[d->ofs])->string)
+                       if(string == PRVM_EDICTFIELDSTRING(ed, d->ofs))
                                return true;
                }
        }
@@ -3159,12 +3232,12 @@ static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict, int mark)
                if(!*targetname) // ""
                        targetname = NULL;
 
-       for (i = 0;i < prog->progs->numglobaldefs;i++)
+       for (i = 0;i < prog->numglobaldefs;i++)
        {
                ddef_t *d = &prog->globaldefs[i];
                if((etype_t)((int) d->type & ~DEF_SAVEGLOBAL) != ev_entity)
                        continue;
-               if(edictnum == ((prvm_eval_t *) &prog->globals.generic[d->ofs])->edict)
+               if(edictnum == PRVM_GLOBALFIELDEDICT(d->ofs))
                        return true;
        }
 
@@ -3182,12 +3255,12 @@ static qboolean PRVM_IsEdictReferenced(prvm_edict_t *edict, int mark)
                                if(!strcmp(target, targetname))
                                        return true;
                }
-               for (i=0; i<prog->progs->numfielddefs; ++i)
+               for (i=0; i<prog->numfielddefs; ++i)
                {
                        ddef_t *d = &prog->fielddefs[i];
                        if((etype_t)((int) d->type & ~DEF_SAVEGLOBAL) != ev_entity)
                                continue;
-                       if(edictnum == ((prvm_eval_t *) &ed->fields.vp[d->ofs])->edict)
+                       if(edictnum == PRVM_EDICTFIELDEDICT(ed, d->ofs))
                                return true;
                }
        }
index ca1c191..6deb4d9 100644 (file)
@@ -124,7 +124,7 @@ PRVM_PrintStatement
 */
 extern cvar_t prvm_statementprofiling;
 extern cvar_t prvm_timeprofiling;
-void PRVM_PrintStatement (dstatement_t *s)
+void PRVM_PrintStatement(mstatement_t *s)
 {
        size_t i;
        int opnum = (int)(s - prog->statements);
@@ -146,46 +146,10 @@ void PRVM_PrintStatement (dstatement_t *s)
                for ( ; i<10 ; i++)
                        Con_Print(" ");
        }
-       if (s->op == OP_IF || s->op == OP_IFNOT)
-               Con_Printf("%s, s%i",PRVM_GlobalString((unsigned short) s->a),(signed short)s->b + opnum);
-       else if (s->op == OP_GOTO)
-               Con_Printf("s%i",(signed short)s->a + opnum);
-       else if ( (unsigned)(s->op - OP_STORE_F) < 6)
-       {
-               Con_Print(PRVM_GlobalString((unsigned short) s->a));
-               Con_Print(", ");
-               Con_Print(PRVM_GlobalStringNoContents((unsigned short) s->b));
-       }
-       else if (s->op == OP_ADDRESS || (unsigned)(s->op - OP_LOAD_F) < 6)
-       {
-               if (s->a)
-                       Con_Print(PRVM_GlobalString((unsigned short) s->a));
-               if (s->b)
-               {
-                       Con_Print(", ");
-                       Con_Print(PRVM_GlobalStringNoContents((unsigned short) s->b));
-               }
-               if (s->c)
-               {
-                       Con_Print(", ");
-                       Con_Print(PRVM_GlobalStringNoContents((unsigned short) s->c));
-               }
-       }
-       else
-       {
-               if (s->a)
-                       Con_Print(PRVM_GlobalString((unsigned short) s->a));
-               if (s->b)
-               {
-                       Con_Print(", ");
-                       Con_Print(PRVM_GlobalString((unsigned short) s->b));
-               }
-               if (s->c)
-               {
-                       Con_Print(", ");
-                       Con_Print(PRVM_GlobalStringNoContents((unsigned short) s->c));
-               }
-       }
+       if (s->operand[0] >= 0) Con_Printf(  "%s", PRVM_GlobalString(s->operand[0]));
+       if (s->operand[1] >= 0) Con_Printf(", %s", PRVM_GlobalString(s->operand[1]));
+       if (s->operand[2] >= 0) Con_Printf(", %s", PRVM_GlobalString(s->operand[2]));
+       if (s->jumpabsolute >= 0) Con_Printf(", statement %i", s->jumpabsolute);
        Con_Print("\n");
 }
 
@@ -207,8 +171,8 @@ void PRVM_PrintFunctionStatements (const char *name)
        }
 
        // find the end statement
-       endstatement = prog->progs->numstatements;
-       for (i = 0;i < prog->progs->numfunctions;i++)
+       endstatement = prog->numstatements;
+       for (i = 0;i < prog->numfunctions;i++)
                if (endstatement > prog->functions[i].first_statement && firststatement < prog->functions[i].first_statement)
                        endstatement = prog->functions[i].first_statement;
 
@@ -313,7 +277,7 @@ void PRVM_CallProfile (void)
        {
                max = 0;
                best = NULL;
-               for (i=0 ; i<prog->progs->numfunctions ; i++)
+               for (i=0 ; i<prog->numfunctions ; i++)
                {
                        f = &prog->functions[i];
                        if (max < f->totaltime)
@@ -357,7 +321,7 @@ void PRVM_Profile (int maxfunctions, double mintime, int sortby)
        {
                max = 0;
                best = NULL;
-               for (i=0 ; i<prog->progs->numfunctions ; i++)
+               for (i=0 ; i<prog->numfunctions ; i++)
                {
                        f = &prog->functions[i];
                        if(prvm_timeprofiling.integer)
@@ -701,9 +665,9 @@ void PRVM_Init_Exec(void)
        // nothing here yet
 }
 
-#define OPA ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->a])
-#define OPB ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->b])
-#define OPC ((prvm_eval_t *)&prog->globals.generic[(unsigned short) st->c])
+#define OPA ((prvm_eval_t *)&prog->globals.generic[st->operand[0]])
+#define OPB ((prvm_eval_t *)&prog->globals.generic[st->operand[1]])
+#define OPC ((prvm_eval_t *)&prog->globals.generic[st->operand[2]])
 extern cvar_t prvm_traceqc;
 extern cvar_t prvm_statementprofiling;
 extern sizebuf_t vm_tempstringsbuf;
@@ -717,7 +681,7 @@ MVM_ExecuteProgram
 */
 void MVM_ExecuteProgram (func_t fnum, const char *errormessage)
 {
-       dstatement_t    *st, *startst;
+       mstatement_t    *st, *startst;
        mfunction_t     *f, *newf;
        prvm_edict_t    *ed;
        prvm_eval_t     *ptr;
@@ -728,7 +692,7 @@ void MVM_ExecuteProgram (func_t fnum, const char *errormessage)
 
        calltime = Sys_DoubleTime();
 
-       if (!fnum || fnum >= (unsigned int)prog->progs->numfunctions)
+       if (!fnum || fnum >= (unsigned int)prog->numfunctions)
        {
                if (prog->globaloffsets.self >= 0 && PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict)
                        PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict), NULL);
@@ -806,7 +770,7 @@ CLVM_ExecuteProgram
 */
 void CLVM_ExecuteProgram (func_t fnum, const char *errormessage)
 {
-       dstatement_t    *st, *startst;
+       mstatement_t    *st, *startst;
        mfunction_t     *f, *newf;
        prvm_edict_t    *ed;
        prvm_eval_t     *ptr;
@@ -817,7 +781,7 @@ void CLVM_ExecuteProgram (func_t fnum, const char *errormessage)
 
        calltime = Sys_DoubleTime();
 
-       if (!fnum || fnum >= (unsigned int)prog->progs->numfunctions)
+       if (!fnum || fnum >= (unsigned int)prog->numfunctions)
        {
                if (prog->globaloffsets.self >= 0 && PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict)
                        PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict), NULL);
@@ -896,7 +860,7 @@ SVVM_ExecuteProgram
 */
 void SVVM_ExecuteProgram (func_t fnum, const char *errormessage)
 {
-       dstatement_t    *st, *startst;
+       mstatement_t    *st, *startst;
        mfunction_t     *f, *newf;
        prvm_edict_t    *ed;
        prvm_eval_t     *ptr;
@@ -907,7 +871,7 @@ void SVVM_ExecuteProgram (func_t fnum, const char *errormessage)
 
        calltime = Sys_DoubleTime();
 
-       if (!fnum || fnum >= (unsigned int)prog->progs->numfunctions)
+       if (!fnum || fnum >= (unsigned int)prog->numfunctions)
        {
                if (prog->globaloffsets.self >= 0 && PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict)
                        PRVM_ED_Print(PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict), NULL);
index 719224d..447ee78 100644 (file)
                                        PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int);
                                        goto cleanup;
                                }
-                               if (OPB->_int < prog->progs->entityfields && !prog->allowworldwrites)
+                               if (OPB->_int < prog->entityfields && !prog->allowworldwrites)
                                {
                                        prog->xstatement = st - prog->statements;
                                        VM_Warning("assignment to world.%s (field %i) in %s\n", PRVM_GetString(PRVM_ED_FieldAtOfs(OPB->_int)->s_name), OPB->_int, PRVM_NAME);
                                        PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int);
                                        goto cleanup;
                                }
-                               if (OPB->_int < prog->progs->entityfields && !prog->allowworldwrites)
+                               if (OPB->_int < prog->entityfields && !prog->allowworldwrites)
                                {
                                        prog->xstatement = st - prog->statements;
                                        VM_Warning("assignment to world.%s (field %i) in %s\n", PRVM_GetString(PRVM_ED_FieldAtOfs(OPB->_int)->s_name), OPB->_int, PRVM_NAME);
                                        PRVM_ERROR ("%s Progs attempted to address an out of bounds edict number", PRVM_NAME);
                                        goto cleanup;
                                }
-                               if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields))
+                               if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->entityfields))
                                {
                                        PreError();
                                        PRVM_ERROR("%s attempted to address an invalid field (%i) in an edict", PRVM_NAME, OPB->_int);
                                        PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME);
                                        goto cleanup;
                                }
-                               if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields))
+                               if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->entityfields))
                                {
                                        PreError();
                                        PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int);
                                        PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME);
                                        goto cleanup;
                                }
-                               if (OPB->_int < 0 || OPB->_int + 2 >= prog->progs->entityfields)
+                               if (OPB->_int < 0 || OPB->_int + 2 >= prog->entityfields)
                                {
                                        PreError();
                                        PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int);
                                // and entity, string, field values can never have that value
                                {
                                        prog->xfunction->profile += (st - startst);
-                                       st += st->b - 1;        // offset the s++
+                                       st = prog->statements + st->jumpabsolute - 1;   // offset the st++
                                        startst = st;
                                        // no bounds check needed, it is done when loading progs
                                        if (++jumpcount == 10000000 && prvm_runawaycheck)
                                // and entity, string, field values can never have that value
                                {
                                        prog->xfunction->profile += (st - startst);
-                                       st += st->b - 1;        // offset the s++
+                                       st = prog->statements + st->jumpabsolute - 1;   // offset the st++
                                        startst = st;
                                        // no bounds check needed, it is done when loading progs
                                        if (++jumpcount == 10000000 && prvm_runawaycheck)
 
                        case OP_GOTO:
                                prog->xfunction->profile += (st - startst);
-                               st += st->a - 1;        // offset the s++
+                               st = prog->statements + st->jumpabsolute - 1;   // offset the st++
                                startst = st;
                                // no bounds check needed, it is done when loading progs
                                if (++jumpcount == 10000000 && prvm_runawaycheck)
                                if (!OPA->function)
                                        PRVM_ERROR("NULL function in %s", PRVM_NAME);
 
-                               if(!OPA->function || OPA->function >= (unsigned int)prog->progs->numfunctions)
+                               if(!OPA->function || OPA->function >= (unsigned int)prog->numfunctions)
                                {
                                        PreError();
                                        PRVM_ERROR("%s CALL outside the program", PRVM_NAME);
                                prog->xfunction->profile += (st - startst);
                                prog->xstatement = st - prog->statements;
 
-                               prog->globals.generic[OFS_RETURN] = prog->globals.generic[(unsigned short) st->a];
-                               prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[(unsigned short) st->a+1];
-                               prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[(unsigned short) st->a+2];
+                               prog->globals.generic[OFS_RETURN] = prog->globals.generic[st->operand[0]];
+                               prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[st->operand[0]+1];
+                               prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[st->operand[0]+2];
 
                                st = prog->statements + PRVM_LeaveFunction();
                                startst = st;
                        case OP_STATE:
                                if(prog->flag & PRVM_OP_STATE)
                                {
-                                       ed = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDVALUE(prog->globaloffsets.self)->edict);
-                                       PRVM_EDICTFIELDVALUE(ed,prog->fieldoffsets.nextthink)->_float = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.time)->_float + 0.1;
-                                       PRVM_EDICTFIELDVALUE(ed,prog->fieldoffsets.frame)->_float = OPA->_float;
-                                       PRVM_EDICTFIELDVALUE(ed,prog->fieldoffsets.think)->function = OPB->function;
+                                       ed = PRVM_PROG_TO_EDICT(PRVM_GLOBALFIELDEDICT(prog->globaloffsets.self));
+                                       PRVM_EDICTFIELDFLOAT(ed,prog->fieldoffsets.nextthink) = PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.time) + 0.1;
+                                       PRVM_EDICTFIELDFLOAT(ed,prog->fieldoffsets.frame) = OPA->_float;
+                                       PRVM_EDICTFIELDFUNCTION(ed,prog->fieldoffsets.think) = OPB->function;
                                }
                                else
                                {
index acea7b0..8f29939 100644 (file)
--- a/sv_demo.c
+++ b/sv_demo.c
@@ -6,7 +6,6 @@ extern cvar_t sv_autodemo_perclient_discardable;
 void SV_StartDemoRecording(client_t *client, const char *filename, int forcetrack)
 {
        char name[MAX_QPATH];
-       prvm_eval_t *val;
 
        if(client->sv_demo_file != NULL)
                return; // we already have a demo
@@ -17,8 +16,7 @@ void SV_StartDemoRecording(client_t *client, const char *filename, int forcetrac
        Con_Printf("Recording demo for # %d (%s) to %s\n", PRVM_NUM_FOR_EDICT(client->edict), client->netaddress, name);
 
        // Reset discardable flag for every new demo.
-       if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.discardabledemo)))
-               val->_float = 0;
+       PRVM_EDICTFIELDFLOAT(client->edict, prog->fieldoffsets.discardabledemo) = 0;
 
        client->sv_demo_file = FS_OpenRealFile(name, "wb", false);
        if(!client->sv_demo_file)
@@ -56,7 +54,6 @@ void SV_StopDemoRecording(client_t *client)
 {
        sizebuf_t buf;
        unsigned char bufdata[64];
-       prvm_eval_t *val;
 
        if(client->sv_demo_file == NULL)
                return;
@@ -67,7 +64,7 @@ void SV_StopDemoRecording(client_t *client)
        MSG_WriteByte(&buf, svc_disconnect);
        SV_WriteDemoMessage(client, &buf, false);
 
-       if (sv_autodemo_perclient_discardable.integer && (val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.discardabledemo)) && val->_float)
+       if (sv_autodemo_perclient_discardable.integer && PRVM_EDICTFIELDFLOAT(client->edict, prog->fieldoffsets.discardabledemo))
        {
                FS_RemoveOnClose(client->sv_demo_file);
                Con_Printf("Stopped recording discardable demo for # %d (%s)\n", PRVM_NUM_FOR_EDICT(client->edict), client->netaddress);
index 7751d81..4696c3d 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -238,13 +238,24 @@ static const char *standardeffectnames[EFFECT_TOTAL] =
        "SVC_PARTICLE"
 };
 
-#define REQFIELDS (sizeof(reqfields) / sizeof(prvm_required_field_t))
+#define SV_REQFUNCS (sizeof(sv_reqfuncs) / sizeof(const char *))
 
-prvm_required_field_t reqfields[] =
+#define sv_reqfuncs NULL
+//static const char *sv_reqfuncs[] = {
+//};
+
+#define SV_REQFIELDS (sizeof(sv_reqfields) / sizeof(prvm_required_field_t))
+
+prvm_required_field_t sv_reqfields[] =
 {
+       {ev_entity, "aiment"},
+       {ev_entity, "chain"},
+       {ev_entity, "clientcamera"},
        {ev_entity, "cursor_trace_ent"},
        {ev_entity, "drawonlytoclient"},
+       {ev_entity, "enemy"},
        {ev_entity, "exteriormodeltoclient"},
+       {ev_entity, "groundentity"},
        {ev_entity, "nodrawtoclient"},
        {ev_entity, "tag_entity"},
        {ev_entity, "viewmodelforclient"},
@@ -258,6 +269,8 @@ prvm_required_field_t reqfields[] =
        {ev_float, "ammo_plasma"},
        {ev_float, "ammo_rockets1"},
        {ev_float, "ammo_shells1"},
+       {ev_float, "bouncefactor"},
+       {ev_float, "bouncestop"},
        {ev_float, "button3"},
        {ev_float, "button4"},
        {ev_float, "button5"},
@@ -275,69 +288,155 @@ prvm_required_field_t reqfields[] =
        {ev_float, "buttonchat"},
        {ev_float, "buttonuse"},
        {ev_float, "clientcolors"},
+       {ev_float, "color"},
+       {ev_float, "colormod"},
        {ev_float, "cursor_active"},
+       {ev_float, "cursor_screen"},
+       {ev_float, "cursor_trace_endpos"},
+       {ev_float, "cursor_trace_start"},
+       {ev_float, "dimension_hit"},
+       {ev_float, "dimension_solid"},
        {ev_float, "disableclientprediction"},
+       {ev_float, "discardabledemo"},
+       {ev_float, "dphitcontentsmask"},
+       {ev_float, "fatness"},
+       {ev_float, "forceshader"},
+       {ev_float, "frame"},
+       {ev_float, "frame1time"},
+       {ev_float, "frame2"},
+       {ev_float, "frame2time"},
+       {ev_float, "frame3"},
+       {ev_float, "frame3time"},
+       {ev_float, "frame4"},
+       {ev_float, "frame4time"},
        {ev_float, "fullbright"},
        {ev_float, "glow_color"},
        {ev_float, "glow_size"},
        {ev_float, "glow_trail"},
        {ev_float, "gravity"},
+       {ev_float, "hull"},
+       {ev_float, "ideal_yaw"},
        {ev_float, "idealpitch"},
        {ev_float, "items2"},
+       {ev_float, "jointtype"},
+       {ev_float, "lerpfrac"},
+       {ev_float, "lerpfrac3"},
+       {ev_float, "lerpfrac4"},
        {ev_float, "light_lev"},
+       {ev_float, "mass"},
        {ev_float, "modelflags"},
+       {ev_float, "modelindex"},
+       {ev_float, "movetype"},
+       {ev_float, "nextthink"},
+       {ev_float, "packetloss"},
        {ev_float, "pflags"},
        {ev_float, "ping"},
+       {ev_float, "ping_packetloss"},
+       {ev_float, "ping_movementloss"},
        {ev_float, "pitch_speed"},
        {ev_float, "pmodel"},
-       {ev_float, "renderamt"}, // HalfLife support
-       {ev_float, "rendermode"}, // HalfLife support
+       {ev_float, "renderamt"},
+       {ev_float, "renderflags"},
+       {ev_float, "rendermode"},
        {ev_float, "scale"},
+       {ev_float, "sendcomplexanimation"},
+       {ev_float, "shadertime"},
+       {ev_float, "skeletonindex"},
+       {ev_float, "solid"},
        {ev_float, "style"},
        {ev_float, "tag_index"},
+       {ev_float, "think"},
+       {ev_float, "userwavefunc_param0"},
+       {ev_float, "userwavefunc_param1"},
+       {ev_float, "userwavefunc_param2"},
+       {ev_float, "userwavefunc_param3"},
        {ev_float, "viewzoom"},
+       {ev_float, "yaw_speed"},
        {ev_function, "SendEntity"},
-       {ev_function, "contentstransition"}, // DRESK - Support for Entity Contents Transition Event
+       {ev_function, "camera_transform"},
+       {ev_function, "contentstransition"},
        {ev_function, "customizeentityforclient"},
-       {ev_function, "movetypesteplandevent"}, // DRESK - Support for MOVETYPE_STEP Entity Land Event
+       {ev_function, "movetypesteplandevent"},
+       {ev_string, "classname"},
+       {ev_string, "clientstatus"},
+       {ev_string, "crypto_encryptmethod"},
+       {ev_string, "crypto_idfp"},
+       {ev_string, "crypto_keyfp"},
+       {ev_string, "crypto_mykeyfp"},
+       {ev_string, "crypto_signmethod"},
+       {ev_string, "message"},
        {ev_string, "netaddress"},
        {ev_string, "playermodel"},
        {ev_string, "playerskin"},
-       {ev_vector, "color"},
-       {ev_vector, "colormod"},
-       {ev_vector, "cursor_screen"},
-       {ev_vector, "cursor_trace_endpos"},
-       {ev_vector, "cursor_trace_start"},
+       {ev_vector, "angles"},
+       {ev_vector, "angles"},
+       {ev_vector, "avelocity"},
+//     {ev_vector, "axis_forward"},
+//     {ev_vector, "axis_left"},
+//     {ev_vector, "axis_up"},
        {ev_vector, "glowmod"},
+       {ev_vector, "maxs"},
+       {ev_vector, "mins"},
+       {ev_vector, "movedir"},
        {ev_vector, "movement"},
+       {ev_vector, "origin"},
        {ev_vector, "punchvector"},
-       {ev_float, "frame"},
-       {ev_float, "frame1time"},
-       {ev_float, "frame2"},
-       {ev_float, "frame2time"},
-       {ev_float, "frame3"},
-       {ev_float, "frame3time"},
-       {ev_float, "frame4"},
-       {ev_float, "frame4time"},
-       {ev_float, "lerpfrac"},
-       {ev_float, "lerpfrac3"},
-       {ev_float, "lerpfrac4"},
-       {ev_float, "sendcomplexanimation"},
+//     {ev_vector, "spinvelocity"},
+       {ev_vector, "velocity"},
+};
 
-       // physics
-       //{ev_float, "solid"},
-       //{ev_float, "movetype"},
-       //{ev_float, "modelindex"},
-       {ev_vector, "mass"},
-       //{ev_vector, "origin"},
-       //{ev_vector, "velocity"},
-       //{ev_vector, "axis_forward"},
-       //{ev_vector, "axis_left"},
-       //{ev_vector, "axis_up"},
-       //{ev_vector, "spinvelocity"},
-       //{ev_vector, "angles"},
-       //{ev_vector, "avelocity"},
+#define SV_REQGLOBALS (sizeof(sv_reqglobals) / sizeof(prvm_required_field_t))
 
+prvm_required_field_t sv_reqglobals[] =
+{
+       {ev_entity, "self"},
+       {ev_entity, "trace_ent"},
+       {ev_entity, "trace_networkentity"},
+       {ev_float, "coop"},
+       {ev_float, "deathmatch"},
+       {ev_float, "dmg_save"},
+       {ev_float, "dmg_take"},
+       {ev_float, "drawfont"},
+       {ev_float, "drawfontscale"},
+       {ev_float, "gettaginfo_parent"},
+       {ev_float, "intermission"},
+       {ev_float, "particles_alphamax"},
+       {ev_float, "particles_alphamin"},
+       {ev_float, "require_spawnfunc_prefix"},
+       {ev_float, "sb_showscores"},
+       {ev_float, "serverdeltatime"},
+       {ev_float, "serverprevtime"},
+       {ev_float, "servertime"},
+       {ev_float, "time"},
+       {ev_float, "trace_allsolid"},
+       {ev_float, "trace_dphitcontents"},
+       {ev_float, "trace_dphitq3surfaceflags"},
+       {ev_float, "trace_dpstartcontents"},
+       {ev_float, "trace_fraction"},
+       {ev_float, "trace_inopen"},
+       {ev_float, "trace_inwater"},
+       {ev_float, "trace_plane_dist"},
+       {ev_float, "trace_startsolid"},
+       {ev_float, "transparent_offset"},
+       {ev_string, "SV_InitCmd"},
+       {ev_string, "gettaginfo_name"},
+       {ev_string, "trace_dphittexturename"},
+       {ev_string, "worldstatus"},
+       {ev_vector, "dmg_origin"},
+       {ev_vector, "gettaginfo_forward"},
+       {ev_vector, "gettaginfo_offset"},
+       {ev_vector, "gettaginfo_right"},
+       {ev_vector, "gettaginfo_up"},
+       {ev_vector, "particles_colormax"},
+       {ev_vector, "particles_colormin"},
+       {ev_vector, "trace_endpos"},
+       {ev_vector, "trace_plane_normal"},
+       {ev_vector, "v_forward"},
+       {ev_vector, "v_right"},
+       {ev_vector, "v_up"},
+       {ev_vector, "view_angles"},
+       {ev_vector, "view_punchangle"},
+       {ev_vector, "view_punchvector"},
 };
 
 
@@ -850,7 +949,6 @@ void SV_SendServerinfo (client_t *client)
        //[515]: init csprogs according to version of svprogs, check the crc, etc.
        if (sv.csqc_progname[0])
        {
-               prvm_eval_t *val;
                Con_DPrintf("sending csqc info to client (\"%s\" with size %i and crc %i)\n", sv.csqc_progname, sv.csqc_progsize, sv.csqc_progcrc);
                MSG_WriteByte (&client->netconnection->message, svc_stufftext);
                MSG_WriteString (&client->netconnection->message, va("csqc_progname %s\n", sv.csqc_progname));
@@ -873,11 +971,10 @@ void SV_SendServerinfo (client_t *client)
                }
 
                //[515]: init stufftext string (it is sent before svc_serverinfo)
-               val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.SV_InitCmd);
-               if (val)
+               if (PRVM_GetString(PRVM_GLOBALFIELDSTRING(prog->globaloffsets.SV_InitCmd)))
                {
                        MSG_WriteByte (&client->netconnection->message, svc_stufftext);
-                       MSG_WriteString (&client->netconnection->message, va("%s\n", PRVM_GetString(val->string)));
+                       MSG_WriteString (&client->netconnection->message, va("%s\n", PRVM_GetString(PRVM_GLOBALFIELDSTRING(prog->globaloffsets.SV_InitCmd))));
                }
        }
 
@@ -1058,13 +1155,13 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        unsigned int customizeentityforclient;
        unsigned int sendentity;
        float f;
+       float *v;
        vec3_t cullmins, cullmaxs;
        dp_model_t *model;
-       prvm_eval_t *val, *val2;
 
        // fast path for games that do not use legacy entity networking
        // note: still networks clients even if they are legacy
-       sendentity = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.SendEntity)->function;
+       sendentity = PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.SendEntity);
        if (sv_onlycsqcnetworking.integer && !sendentity && enumber > svs.maxclients)
                return false;
 
@@ -1084,23 +1181,24 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        modelindex = (i >= 1 && i < MAX_MODELS && ent->fields.server->model && *PRVM_GetString(ent->fields.server->model) && sv.models[i]) ? i : 0;
 
        flags = 0;
-       i = (int)(PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.glow_size)->_float * 0.25f);
+       i = (int)(PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.glow_size) * 0.25f);
        glowsize = (unsigned char)bound(0, i, 255);
-       if (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.glow_trail)->_float)
+       if (PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.glow_trail))
                flags |= RENDER_GLOWTRAIL;
-       if (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)->edict)
+       if (PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.viewmodelforclient))
                flags |= RENDER_VIEWMODEL;
 
-       f = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.color)->vector[0]*256;
+       v = PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.color);
+       f = v[0]*256;
        light[0] = (unsigned short)bound(0, f, 65535);
-       f = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.color)->vector[1]*256;
+       f = v[1]*256;
        light[1] = (unsigned short)bound(0, f, 65535);
-       f = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.color)->vector[2]*256;
+       f = v[2]*256;
        light[2] = (unsigned short)bound(0, f, 65535);
-       f = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.light_lev)->_float;
+       f = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.light_lev);
        light[3] = (unsigned short)bound(0, f, 65535);
-       lightstyle = (unsigned char)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.style)->_float;
-       lightpflags = (unsigned char)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.pflags)->_float;
+       lightstyle = (unsigned char)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.style);
+       lightpflags = (unsigned char)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.pflags);
 
        if (gamemode == GAME_TENEBRAE)
        {
@@ -1151,7 +1249,7 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
 
        // early culling checks
        // (final culling is done by SV_MarkWriteEntityStateToClient)
-       customizeentityforclient = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.customizeentityforclient)->function;
+       customizeentityforclient = PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.customizeentityforclient);
        if (!customizeentityforclient && enumber > svs.maxclients && (!modelindex && !specialvisibilityradius))
                return false;
 
@@ -1166,46 +1264,46 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        cs->modelindex = modelindex;
        cs->skin = (unsigned)ent->fields.server->skin;
        cs->frame = (unsigned)ent->fields.server->frame;
-       cs->viewmodelforclient = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)->edict;
-       cs->exteriormodelforclient = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.exteriormodeltoclient)->edict;
-       cs->nodrawtoclient = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.nodrawtoclient)->edict;
-       cs->drawonlytoclient = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.drawonlytoclient)->edict;
+       cs->viewmodelforclient = PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.viewmodelforclient);
+       cs->exteriormodelforclient = PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.exteriormodeltoclient);
+       cs->nodrawtoclient = PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.nodrawtoclient);
+       cs->drawonlytoclient = PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.drawonlytoclient);
        cs->customizeentityforclient = customizeentityforclient;
-       cs->tagentity = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)->edict;
-       cs->tagindex = (unsigned char)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
+       cs->tagentity = PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.tag_entity);
+       cs->tagindex = (unsigned char)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.tag_index);
        cs->glowsize = glowsize;
 
        // don't need to init cs->colormod because the defaultstate did that for us
        //cs->colormod[0] = cs->colormod[1] = cs->colormod[2] = 32;
-       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.colormod);
-       if (val->vector[0] || val->vector[1] || val->vector[2])
+       v = PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.colormod);
+       if (VectorLength2(v))
        {
-               i = (int)(val->vector[0] * 32.0f);cs->colormod[0] = bound(0, i, 255);
-               i = (int)(val->vector[1] * 32.0f);cs->colormod[1] = bound(0, i, 255);
-               i = (int)(val->vector[2] * 32.0f);cs->colormod[2] = bound(0, i, 255);
+               i = (int)(v[0] * 32.0f);cs->colormod[0] = bound(0, i, 255);
+               i = (int)(v[1] * 32.0f);cs->colormod[1] = bound(0, i, 255);
+               i = (int)(v[2] * 32.0f);cs->colormod[2] = bound(0, i, 255);
        }
 
        // don't need to init cs->glowmod because the defaultstate did that for us
        //cs->glowmod[0] = cs->glowmod[1] = cs->glowmod[2] = 32;
-       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.glowmod);
-       if (val->vector[0] || val->vector[1] || val->vector[2])
+       v = PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.glowmod);
+       if (VectorLength2(v))
        {
-               i = (int)(val->vector[0] * 32.0f);cs->glowmod[0] = bound(0, i, 255);
-               i = (int)(val->vector[1] * 32.0f);cs->glowmod[1] = bound(0, i, 255);
-               i = (int)(val->vector[2] * 32.0f);cs->glowmod[2] = bound(0, i, 255);
+               i = (int)(v[0] * 32.0f);cs->glowmod[0] = bound(0, i, 255);
+               i = (int)(v[1] * 32.0f);cs->glowmod[1] = bound(0, i, 255);
+               i = (int)(v[2] * 32.0f);cs->glowmod[2] = bound(0, i, 255);
        }
 
        cs->modelindex = modelindex;
 
        cs->alpha = 255;
-       f = (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.alpha)->_float * 255.0f);
+       f = (PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.alpha) * 255.0f);
        if (f)
        {
                i = (int)f;
                cs->alpha = (unsigned char)bound(0, i, 255);
        }
        // halflife
-       f = (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderamt)->_float);
+       f = (PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.renderamt));
        if (f)
        {
                i = (int)f;
@@ -1213,7 +1311,7 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        }
 
        cs->scale = 16;
-       f = (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale)->_float * 16.0f);
+       f = (PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.scale) * 16.0f);
        if (f)
        {
                i = (int)f;
@@ -1221,16 +1319,16 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        }
 
        cs->glowcolor = 254;
-       f = (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.glow_color)->_float);
+       f = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.glow_color);
        if (f)
                cs->glowcolor = (int)f;
 
-       if (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.fullbright)->_float)
+       if (PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.fullbright))
                cs->effects |= EF_FULLBRIGHT;
 
-       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.modelflags);
-       if (val && val->_float)
-               cs->effects |= ((unsigned int)val->_float & 0xff) << 24;
+       f = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.modelflags);
+       if (f)
+               cs->effects |= ((unsigned int)f & 0xff) << 24;
 
        if (ent->fields.server->movetype == MOVETYPE_STEP)
                cs->flags |= RENDER_STEP;
@@ -1241,22 +1339,22 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        if (cs->viewmodelforclient)
                cs->flags |= RENDER_VIEWMODEL; // show relative to the view
 
-       if (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.sendcomplexanimation)->_float)
+       if (PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.sendcomplexanimation))
        {
                cs->flags |= RENDER_COMPLEXANIMATION;
-               if (PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.skeletonindex)->_float >= 1)
+               if (PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.skeletonindex) >= 1)
                        cs->skeletonobject = ent->priv.server->skeleton;
-               cs->framegroupblend[0].frame = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.frame)->_float;
-               cs->framegroupblend[1].frame = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.frame2)->_float;
-               cs->framegroupblend[2].frame = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.frame3)->_float;
-               cs->framegroupblend[3].frame = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.frame4)->_float;
-               cs->framegroupblend[0].start = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.frame1time)->_float;
-               cs->framegroupblend[1].start = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.frame2time)->_float;
-               cs->framegroupblend[2].start = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.frame3time)->_float;
-               cs->framegroupblend[3].start = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.frame4time)->_float;
-               cs->framegroupblend[1].lerp = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.lerpfrac)->_float;
-               cs->framegroupblend[2].lerp = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.lerpfrac3)->_float;
-               cs->framegroupblend[3].lerp = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.lerpfrac4)->_float;
+               cs->framegroupblend[0].frame = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.frame);
+               cs->framegroupblend[1].frame = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.frame2);
+               cs->framegroupblend[2].frame = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.frame3);
+               cs->framegroupblend[3].frame = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.frame4);
+               cs->framegroupblend[0].start = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.frame1time);
+               cs->framegroupblend[1].start = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.frame2time);
+               cs->framegroupblend[2].start = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.frame3time);
+               cs->framegroupblend[3].start = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.frame4time);
+               cs->framegroupblend[1].lerp = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.lerpfrac);
+               cs->framegroupblend[2].lerp = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.lerpfrac3);
+               cs->framegroupblend[3].lerp = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.lerpfrac4);
                cs->framegroupblend[0].lerp = 1.0f - cs->framegroupblend[1].lerp - cs->framegroupblend[2].lerp - cs->framegroupblend[3].lerp;
        }
 
@@ -1333,14 +1431,11 @@ static qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *c
        // (to let the QC know that they've been read)
        if (sendentity)
        {
-               val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.SendFlags);
-               sendflags = (unsigned int)val->_float;
-               val->_float = 0;
+               sendflags = (unsigned int)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.SendFlags);
+               PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.SendFlags) = 0;
                // legacy self.Version system
-               val2 = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.Version);
-               if (val2->_float)
+               if ((version = (unsigned int)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.Version)))
                {
-                       version = (unsigned int)val2->_float;
                        if (sv.csqcentityversion[enumber] != version)
                                sendflags = 0xFFFFFF;
                        sv.csqcentityversion[enumber] = version;
@@ -1442,7 +1537,7 @@ qboolean SV_CanSeeBox(int numtraces, vec_t enlarge, vec3_t eye, vec3_t entboxmin
                if (!model || !model->brush.TraceLineOfSight)
                        continue;
                // skip obviously transparent entities
-               alpha = PRVM_EDICTFIELDVALUE(touch, prog->fieldoffsets.alpha)->_float;
+               alpha = PRVM_EDICTFIELDFLOAT(touch, prog->fieldoffsets.alpha);
                if (alpha && alpha < 1)
                        continue;
                if ((int)touch->fields.server->effects & EF_ADDITIVE)
@@ -1628,13 +1723,9 @@ void SV_AddCameraEyes(void)
        static int eye_levels[MAX_CLIENTNETWORKEYES];
        int n_cameras = 0;
        vec3_t mi, ma;
-       prvm_eval_t *valendpos, *val;
 
        if(!prog->fieldoffsets.camera_transform)
                return;
-       valendpos = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_endpos);
-       if(!valendpos)
-               return;
 
        for(i = 0; i < sv.writeentitiestoclient_numeyes; ++i)
                eye_levels[i] = 0;
@@ -1644,17 +1735,17 @@ void SV_AddCameraEyes(void)
        {
                if (!ed->priv.server->free)
                {
-                       if((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.camera_transform)) && val->function)
+                       if(PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.camera_transform))
                        {
                                prog->globals.server->self = e;
                                prog->globals.server->other = sv.writeentitiestoclient_cliententitynumber;
-                               VectorCopy(sv.writeentitiestoclient_eyes[0], valendpos->vector);
+                               VectorCopy(sv.writeentitiestoclient_eyes[0], PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_endpos));
                                VectorCopy(sv.writeentitiestoclient_eyes[0], PRVM_G_VECTOR(OFS_PARM0));
                                VectorClear(PRVM_G_VECTOR(OFS_PARM1));
-                               PRVM_ExecuteProgram(val->function, "QC function e.camera_transform is missing");
-                               if(!VectorCompare(valendpos->vector, sv.writeentitiestoclient_eyes[0]))
+                               PRVM_ExecuteProgram(PRVM_EDICTFIELDFUNCTION(ed, prog->fieldoffsets.camera_transform), "QC function e.camera_transform is missing");
+                               if(!VectorCompare(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_endpos), sv.writeentitiestoclient_eyes[0]))
                                {
-                                       VectorCopy(valendpos->vector, camera_origins[n_cameras]);
+                                       VectorCopy(PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.trace_endpos), camera_origins[n_cameras]);
                                        cameras[n_cameras] = e;
                                        ++n_cameras;
                                        if(n_cameras >= MAX_LEVELNETWORKEYES)
@@ -1848,11 +1939,11 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
        int             i;
        prvm_edict_t    *other;
        int             items;
-       prvm_eval_t     *val;
        vec3_t  punchvector;
        int             viewzoom;
        const char *s;
        float   *statsf = (float *)stats;
+       float gravity;
 
 //
 // send a damage message
@@ -1897,15 +1988,12 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
 
        // stuff the sigil bits into the high bits of items for sbar, or else
        // mix in items2
-       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.items2);
        if (gamemode == GAME_HIPNOTIC || gamemode == GAME_ROGUE)
-               items = (int)ent->fields.server->items | ((int)val->_float << 23);
+               items = (int)ent->fields.server->items | ((int)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.items2) << 23);
        else
                items = (int)ent->fields.server->items | ((int)prog->globals.server->serverflags << 28);
 
-       VectorClear(punchvector);
-       if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.punchvector)))
-               VectorCopy(val->vector, punchvector);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ent, prog->fieldoffsets.punchvector), punchvector);
 
        // cache weapon model name and index in client struct to save time
        // (this search can be almost 1% of cpu time!)
@@ -1916,9 +2004,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
                client->weaponmodelindex = SV_ModelIndex(s, 1);
        }
 
-       viewzoom = 255;
-       if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewzoom)))
-               viewzoom = (int)(val->_float * 255.0f);
+       viewzoom = (int)(PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.viewzoom) * 255.0f);
        if (viewzoom == 0)
                viewzoom = 255;
 
@@ -1942,6 +2028,8 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
                        bits |= (SU_VELOCITY1<<i);
        }
 
+       gravity = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.gravity);if (!gravity) gravity = 1.0f;
+
        memset(stats, 0, sizeof(int[MAX_CL_STATS]));
        stats[STAT_VIEWHEIGHT] = (int)ent->fields.server->view_ofs[2];
        stats[STAT_ITEMS] = items;
@@ -1979,8 +2067,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
        statsf[STAT_MOVEVARS_ACCELERATE] = sv_accelerate.value;
        statsf[STAT_MOVEVARS_AIRACCELERATE] = sv_airaccelerate.value >= 0 ? sv_airaccelerate.value : sv_accelerate.value;
        statsf[STAT_MOVEVARS_WATERACCELERATE] = sv_wateraccelerate.value >= 0 ? sv_wateraccelerate.value : sv_accelerate.value;
-       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.gravity);
-       statsf[STAT_MOVEVARS_ENTGRAVITY] = (val && val->_float != 0) ? val->_float : 1.0f;
+       statsf[STAT_MOVEVARS_ENTGRAVITY] = gravity;
        statsf[STAT_MOVEVARS_JUMPVELOCITY] = sv_jumpvelocity.value;
        statsf[STAT_MOVEVARS_EDGEFRICTION] = sv_edgefriction.value;
        statsf[STAT_MOVEVARS_MAXAIRSPEED] = sv_maxairspeed.value;
@@ -2331,10 +2418,10 @@ static void SV_UpdateToReliableMessages (void)
 {
        int i, j;
        client_t *client;
-       prvm_eval_t *val;
        const char *name;
        const char *model;
        const char *skin;
+       int clientcamera;
 
 // check for changes to be sent over the reliable streams
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
@@ -2362,9 +2449,7 @@ static void SV_UpdateToReliableMessages (void)
                }
 
                // DP_SV_CLIENTCOLORS
-               // this is always found (since it's added by the progs loader)
-               if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.clientcolors)))
-                       host_client->colors = (int)val->_float;
+               host_client->colors = (int)PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.clientcolors);
                if (host_client->old_colors != host_client->colors)
                {
                        host_client->old_colors = host_client->colors;
@@ -2376,36 +2461,37 @@ static void SV_UpdateToReliableMessages (void)
 
                // NEXUIZ_PLAYERMODEL
                if( prog->fieldoffsets.playermodel >= 0 ) {
-                       model = PRVM_GetString(PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playermodel)->string);
+                       model = PRVM_GetString(PRVM_EDICTFIELDSTRING(host_client->edict, prog->fieldoffsets.playermodel));
                        if (model == NULL)
                                model = "";
                        // always point the string back at host_client->name to keep it safe
                        strlcpy (host_client->playermodel, model, sizeof (host_client->playermodel));
-                       PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playermodel)->string = PRVM_SetEngineString(host_client->playermodel);
+                       PRVM_EDICTFIELDSTRING(host_client->edict, prog->fieldoffsets.playermodel) = PRVM_SetEngineString(host_client->playermodel);
                }
 
                // NEXUIZ_PLAYERSKIN
                if( prog->fieldoffsets.playerskin >= 0 ) {
-                       skin = PRVM_GetString(PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playerskin)->string);
+                       skin = PRVM_GetString(PRVM_EDICTFIELDSTRING(host_client->edict, prog->fieldoffsets.playerskin));
                        if (skin == NULL)
                                skin = "";
                        // always point the string back at host_client->name to keep it safe
                        strlcpy (host_client->playerskin, skin, sizeof (host_client->playerskin));
-                       PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.playerskin)->string = PRVM_SetEngineString(host_client->playerskin);
+                       PRVM_EDICTFIELDSTRING(host_client->edict, prog->fieldoffsets.playerskin) = PRVM_SetEngineString(host_client->playerskin);
                }
 
                // TODO: add an extension name for this [1/17/2008 Black]
-               if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.clientcamera)) && val->edict > 0 ) {
+               clientcamera = PRVM_EDICTFIELDEDICT(host_client->edict, prog->fieldoffsets.clientcamera);
+               if (clientcamera > 0)
+               {
                        int oldclientcamera = host_client->clientcamera;
-                       if( val->edict >= prog->max_edicts || PRVM_EDICT_NUM( val->edict )->priv.required->free ) {
-                               val->edict = host_client->clientcamera = PRVM_NUM_FOR_EDICT( host_client->edict );
-                       } else {
-                               host_client->clientcamera = val->edict;
-                       }
+                       if (clientcamera >= prog->max_edicts || PRVM_EDICT_NUM(clientcamera)->priv.required->free)
+                               clientcamera = PRVM_NUM_FOR_EDICT(host_client->edict);
+                       host_client->clientcamera = clientcamera;
 
-                       if( oldclientcamera != host_client->clientcamera ) {
-                               MSG_WriteByte (&host_client->netconnection->message, svc_setview );
-                               MSG_WriteShort (&host_client->netconnection->message, host_client->clientcamera);
+                       if (oldclientcamera != host_client->clientcamera)
+                       {
+                               MSG_WriteByte(&host_client->netconnection->message, svc_setview);
+                               MSG_WriteShort(&host_client->netconnection->message, host_client->clientcamera);
                        }
                }
 
@@ -3277,7 +3363,7 @@ void SV_SpawnServer (const char *server)
 //
        // AK possible hack since num_edicts is still 0
        ent = PRVM_EDICT_NUM(0);
-       memset (ent->fields.server, 0, prog->progs->entityfields * 4);
+       memset (ent->fields.server, 0, prog->entityfields * 4);
        ent->priv.server->free = false;
        ent->fields.server->model = PRVM_SetEngineString(sv.worldname);
        ent->fields.server->modelindex = 1;             // world model
@@ -3414,7 +3500,6 @@ static void SV_VM_CB_InitEdict(prvm_edict_t *e)
 
        if (num >= 0 && num < svs.maxclients)
        {
-               prvm_eval_t *val;
                // set colormap and team on newly created player entity
                e->fields.server->colormap = num + 1;
                e->fields.server->team = (svs.clients[num].colors & 15) + 1;
@@ -3422,13 +3507,12 @@ static void SV_VM_CB_InitEdict(prvm_edict_t *e)
                // DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS will not immediately
                // reset them
                e->fields.server->netname = PRVM_SetEngineString(svs.clients[num].name);
-               if ((val = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.clientcolors)))
-                       val->_float = svs.clients[num].colors;
+               PRVM_EDICTFIELDFLOAT(e, prog->fieldoffsets.clientcolors) = svs.clients[num].colors;
                // NEXUIZ_PLAYERMODEL and NEXUIZ_PLAYERSKIN
                if( prog->fieldoffsets.playermodel >= 0 )
-                       PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.playermodel)->string = PRVM_SetEngineString(svs.clients[num].playermodel);
+                       PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.playermodel) = PRVM_SetEngineString(svs.clients[num].playermodel);
                if( prog->fieldoffsets.playerskin >= 0 )
-                       PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.playerskin)->string = PRVM_SetEngineString(svs.clients[num].playerskin);
+                       PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.playerskin) = PRVM_SetEngineString(svs.clients[num].playerskin);
                // Assign netaddress (IP Address, etc)
                if(prog->fieldoffsets.netaddress >= 0)
                { // Valid Field; Process
@@ -3436,46 +3520,46 @@ static void SV_VM_CB_InitEdict(prvm_edict_t *e)
                        {// Valid Address; Assign
                                // Acquire Readable Address
                                LHNETADDRESS_ToString(&svs.clients[num].netconnection->peeraddress, svs.clients[num].netaddress, sizeof(svs.clients[num].netaddress), false);
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.netaddress)->string = PRVM_SetEngineString(svs.clients[num].netaddress);
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.netaddress) = PRVM_SetEngineString(svs.clients[num].netaddress);
                        }
                        else
                                // Invalid / Bot
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.netaddress)->string = PRVM_SetEngineString("null/botclient");
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.netaddress) = PRVM_SetEngineString("null/botclient");
                }
                if(prog->fieldoffsets.crypto_idfp >= 0)
                { // Valid Field; Process
                        if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated && svs.clients[num].netconnection->crypto.client_idfp[0])
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_idfp)->string = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.client_idfp);
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_idfp) = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.client_idfp);
                        else
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_idfp)->string = 0;
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_idfp) = 0;
                }
                if(prog->fieldoffsets.crypto_keyfp >= 0)
                { // Valid Field; Process
                        if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated && svs.clients[num].netconnection->crypto.client_keyfp[0])
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_keyfp)->string = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.client_keyfp);
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_keyfp) = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.client_keyfp);
                        else
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_keyfp)->string = 0;
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_keyfp) = 0;
                }
                if(prog->fieldoffsets.crypto_mykeyfp >= 0)
                { // Valid Field; Process
                        if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated && svs.clients[num].netconnection->crypto.server_keyfp[0])
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_mykeyfp)->string = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.server_keyfp);
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_mykeyfp) = PRVM_SetEngineString(svs.clients[num].netconnection->crypto.server_keyfp);
                        else
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_mykeyfp)->string = 0;
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_mykeyfp) = 0;
                }
                if(prog->fieldoffsets.crypto_encryptmethod >= 0)
                { // Valid Field; Process
                        if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated && svs.clients[num].netconnection->crypto.use_aes)
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_encryptmethod)->string = PRVM_SetEngineString("AES128");
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_encryptmethod) = PRVM_SetEngineString("AES128");
                        else
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_encryptmethod)->string = 0;
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_encryptmethod) = 0;
                }
                if(prog->fieldoffsets.crypto_signmethod >= 0)
                { // Valid Field; Process
                        if(svs.clients[num].netconnection != NULL && svs.clients[num].netconnection->crypto.authenticated)
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_signmethod)->string = PRVM_SetEngineString("HMAC-SHA256");
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_signmethod) = PRVM_SetEngineString("HMAC-SHA256");
                        else
-                               PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.crypto_signmethod)->string = 0;
+                               PRVM_EDICTFIELDSTRING(e, prog->fieldoffsets.crypto_signmethod) = 0;
                }
        }
 }
@@ -3603,8 +3687,7 @@ static void SV_VM_Setup(void)
        prog->error_cmd = Host_Error;
        prog->ExecuteProgram = SVVM_ExecuteProgram;
 
-       // TODO: add a requiredfuncs list (ask LH if this is necessary at all)
-       PRVM_LoadProgs( sv_progs.string, 0, NULL, REQFIELDS, reqfields, 0, NULL );
+       PRVM_LoadProgs( sv_progs.string, SV_REQFUNCS, sv_reqfuncs, SV_REQFIELDS, sv_reqfields, SV_REQGLOBALS, sv_reqglobals);
 
        // some mods compiled with scrambling compilers lack certain critical
        // global names and field names such as "self" and "time" and "nextthink"
index 7558be8..541a105 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -52,7 +52,7 @@ int SV_GetPitchSign(prvm_edict_t *ent)
                        model->type == mod_alias
                        :
                        (
-                        (((unsigned char)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.pflags)->_float) & PFLAGS_FULLDYNAMIC)
+                        (((unsigned char)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.pflags)) & PFLAGS_FULLDYNAMIC)
                         ||
                         ((gamemode == GAME_TENEBRAE) && ((unsigned int)ent->fields.server->effects & (16 | 32)))
                        )
@@ -71,12 +71,11 @@ LINE TESTING IN HULLS
 
 int SV_GenericHitSuperContentsMask(const prvm_edict_t *passedict)
 {
-       prvm_eval_t *val;
        if (passedict)
        {
-               val = PRVM_EDICTFIELDVALUE(passedict, prog->fieldoffsets.dphitcontentsmask);
-               if (val && val->_float)
-                       return (int)val->_float;
+               int dphitcontentsmask = (int)PRVM_EDICTFIELDFLOAT(passedict, prog->fieldoffsets.dphitcontentsmask);
+               if (dphitcontentsmask)
+                       return dphitcontentsmask;
                else if (passedict->fields.server->solid == SOLID_SLIDEBOX)
                {
                        if ((int)passedict->fields.server->flags & FL_MONSTER)
@@ -702,7 +701,6 @@ Linking entities into the world culling system
 
 void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
 {
-       prvm_eval_t *val;
        prog->globals.server->self = PRVM_EDICT_TO_PROG(touch);
        prog->globals.server->other = PRVM_EDICT_TO_PROG(ent);
        prog->globals.server->time = sv.time;
@@ -715,14 +713,10 @@ void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
        VectorSet (prog->globals.server->trace_plane_normal, 0, 0, 1);
        prog->globals.server->trace_plane_dist = 0;
        prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(ent);
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
-               val->_float = 0;
-       if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
-               val->string = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dpstartcontents) = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitcontents) = 0;
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitq3surfaceflags) = 0;
+       PRVM_GLOBALFIELDSTRING(prog->globaloffsets.trace_dphittexturename) = 0;
        PRVM_ExecuteProgram (touch->fields.server->touch, "QC function self.touch is missing");
 }
 
@@ -1012,7 +1006,6 @@ returns true if entity had a valid contentstransition function call
 int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
 {
        int bValidFunctionCall;
-       prvm_eval_t *contentstransition;
 
        // Default Valid Function Call to False
        bValidFunctionCall = false;
@@ -1020,9 +1013,7 @@ int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
        if(ent->fields.server->watertype != nContents)
        { // Changed Contents
                // Acquire Contents Transition Function from QC
-               contentstransition = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.contentstransition);
-
-               if(contentstransition->function)
+               if(PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.contentstransition))
                { // Valid Function; Execute
                        // Assign Valid Function
                        bValidFunctionCall = true;
@@ -1034,7 +1025,7 @@ int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
                                // Assign Self
                                prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
                        // Execute VM Function
-                       PRVM_ExecuteProgram(contentstransition->function, "contentstransition: NULL function");
+                       PRVM_ExecuteProgram(PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.contentstransition), "contentstransition: NULL function");
                }
        }
 
@@ -1137,7 +1128,6 @@ void SV_Impact (prvm_edict_t *e1, trace_t *trace)
        int restorevm_tempstringsbuf_cursize;
        int old_self, old_other;
        prvm_edict_t *e2 = (prvm_edict_t *)trace->ent;
-       prvm_eval_t *val;
 
        old_self = prog->globals.server->self;
        old_other = prog->globals.server->other;
@@ -1161,14 +1151,10 @@ void SV_Impact (prvm_edict_t *e1, trace_t *trace)
                VectorNegate(trace->plane.normal, prog->globals.server->trace_plane_normal);
                prog->globals.server->trace_plane_dist = -trace->plane.dist;
                prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(e1);
-               if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dpstartcontents)))
-                       val->_float = 0;
-               if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitcontents)))
-                       val->_float = 0;
-               if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphitq3surfaceflags)))
-                       val->_float = 0;
-               if ((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.trace_dphittexturename)))
-                       val->string = 0;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dpstartcontents) = 0;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitcontents) = 0;
+               PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.trace_dphitq3surfaceflags) = 0;
+               PRVM_GLOBALFIELDSTRING(prog->globaloffsets.trace_dphittexturename) = 0;
                PRVM_ExecuteProgram (e2->fields.server->touch, "QC function self.touch is missing");
        }
 
@@ -1447,13 +1433,10 @@ SV_Gravity
 static float SV_Gravity (prvm_edict_t *ent)
 {
        float ent_gravity;
-       prvm_eval_t *val;
 
-       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.gravity);
-       if (val!=0 && val->_float)
-               ent_gravity = val->_float;
-       else
-               ent_gravity = 1.0;
+       ent_gravity = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.gravity);
+       if (!ent_gravity)
+               ent_gravity = 1.0f;
        return ent_gravity * sv_gravity.value * sv.frametime;
 }
 
@@ -2521,11 +2504,10 @@ void SV_Physics_Toss (prvm_edict_t *ent)
                movetime *= 1 - min(1, trace.fraction);
                if (ent->fields.server->movetype == MOVETYPE_BOUNCEMISSILE)
                {
-                       prvm_eval_t *val;
-                       float bouncefactor = 1.0f;
-                       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.bouncefactor);
-                       if (val!=0 && val->_float)
-                               bouncefactor = val->_float;
+                       float bouncefactor;
+                       bouncefactor = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.bouncefactor);
+                       if (!bouncefactor)
+                               bouncefactor = 1.0f;
 
                        ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1 + bouncefactor);
                        ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
@@ -2533,25 +2515,22 @@ void SV_Physics_Toss (prvm_edict_t *ent)
                else if (ent->fields.server->movetype == MOVETYPE_BOUNCE)
                {
                        float d, ent_gravity;
-                       prvm_eval_t *val;
-                       float bouncefactor = 0.5f;
-                       float bouncestop = 60.0f / 800.0f;
+                       float bouncefactor;
+                       float bouncestop;
 
-                       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.bouncefactor);
-                       if (val!=0 && val->_float)
-                               bouncefactor = val->_float;
+                       bouncefactor = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.bouncefactor);
+                       if (!bouncefactor)
+                               bouncefactor = 0.5f;
 
-                       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.bouncestop);
-                       if (val!=0 && val->_float)
-                               bouncestop = val->_float;
+                       bouncestop = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.bouncestop);
+                       if (!bouncestop)
+                               bouncestop = 60.0f / 800.0f;
 
                        ClipVelocity (ent->fields.server->velocity, trace.plane.normal, ent->fields.server->velocity, 1 + bouncefactor);
+                       ent_gravity = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.gravity);
+                       if (!ent_gravity)
+                               ent_gravity = 1.0f;
                        // LordHavoc: fixed grenades not bouncing when fired down a slope
-                       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.gravity);
-                       if (val!=0 && val->_float)
-                               ent_gravity = val->_float;
-                       else
-                               ent_gravity = 1.0;
                        if (sv_gameplayfix_grenadebouncedownslopes.integer)
                        {
                                d = DotProduct(trace.plane.normal, ent->fields.server->velocity);
@@ -2627,7 +2606,6 @@ void SV_Physics_Step (prvm_edict_t *ent)
        // DRESK
        // Backup Velocity in the event that movetypesteplandevent is called,
        // to provide a parameter with the entity's velocity at impact.
-       prvm_eval_t *movetypesteplandevent;
        vec3_t backupVelocity;
        VectorCopy(ent->fields.server->velocity, backupVelocity);
        // don't fall at all if fly/swim
@@ -2661,9 +2639,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
                        if (hitsound && (int)ent->fields.server->flags & FL_ONGROUND)
                        {
                                // DRESK - Check for Entity Land Event Function
-                               movetypesteplandevent = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.movetypesteplandevent);
-
-                               if(movetypesteplandevent->function)
+                               if(PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.movetypesteplandevent))
                                { // Valid Function; Execute
                                        // Prepare Parameters
                                                // Assign Velocity at Impact
@@ -2673,7 +2649,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
                                                // Assign Self
                                                prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
                                        // Execute VM Function
-                                       PRVM_ExecuteProgram(movetypesteplandevent->function, "movetypesteplandevent: NULL function");
+                                       PRVM_ExecuteProgram(PRVM_EDICTFIELDFUNCTION(ent, prog->fieldoffsets.movetypesteplandevent), "movetypesteplandevent: NULL function");
                                }
                                else
                                // Check for Engine Landing Sound
index 1158d2e..f8b666a 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -190,7 +190,7 @@ void SV_AirAccelerate (vec3_t wishveloc)
 void DropPunchAngle (void)
 {
        float len;
-       prvm_eval_t *val;
+       vec3_t v;
 
        len = VectorNormalizeLength (host_client->edict->fields.server->punchangle);
 
@@ -199,15 +199,16 @@ void DropPunchAngle (void)
                len = 0;
        VectorScale (host_client->edict->fields.server->punchangle, len, host_client->edict->fields.server->punchangle);
 
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.punchvector)))
+       VectorCopy(PRVM_EDICTFIELDVECTOR(host_client->edict, prog->fieldoffsets.punchvector), v);
+       len = VectorNormalizeLength(v);
+       if (len > 0)
        {
-               len = VectorNormalizeLength (val->vector);
-
                len -= 20*sv.frametime;
                if (len < 0)
                        len = 0;
-               VectorScale (val->vector, len, val->vector);
+               VectorScale(v, len, v);
        }
+       VectorCopy(v, PRVM_EDICTFIELDVECTOR(host_client->edict, prog->fieldoffsets.punchvector));
 }
 
 /*
@@ -584,7 +585,6 @@ void SV_ExecuteClientMoves(void)
 #ifdef NUM_PING_TIMES
        double total;
 #endif
-       prvm_eval_t *val;
        if (sv_numreadmoves < 1)
                return;
        // only start accepting input once the player is spawned
@@ -597,7 +597,7 @@ void SV_ExecuteClientMoves(void)
        if (ceil(max(sv_readmoves[sv_numreadmoves-1].receivetime - sv_readmoves[sv_numreadmoves-1].time, 0) * 1000.0) < sv_clmovement_minping.integer)
                host_client->clmovement_disabletimeout = realtime + sv_clmovement_minping_disabletime.value / 1000.0;
        // several conditions govern whether clientside movement prediction is allowed
-       if (sv_readmoves[sv_numreadmoves-1].sequence && sv_clmovement_enable.integer && sv_clmovement_inputtimeout.value > 0 && host_client->clmovement_disabletimeout <= realtime && host_client->edict->fields.server->movetype == MOVETYPE_WALK && (!(val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.disableclientprediction)) || !val->_float))
+       if (sv_readmoves[sv_numreadmoves-1].sequence && sv_clmovement_enable.integer && sv_clmovement_inputtimeout.value > 0 && host_client->clmovement_disabletimeout <= realtime && host_client->edict->fields.server->movetype == MOVETYPE_WALK && (!PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.disableclientprediction)))
        {
                // process the moves in order and ignore old ones
                // but always trust the latest move
@@ -705,7 +705,6 @@ void SV_ExecuteClientMoves(void)
 
 void SV_ApplyClientMove (void)
 {
-       prvm_eval_t *val;
        usercmd_t *move = &host_client->cmd;
        int j, movementloss, packetloss;
 
@@ -739,31 +738,31 @@ void SV_ApplyClientMove (void)
        }
 
        VectorCopy(move->viewangles, host_client->edict->fields.server->v_angle);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button3))) val->_float = ((move->buttons >> 2) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button4))) val->_float = ((move->buttons >> 3) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button5))) val->_float = ((move->buttons >> 4) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button6))) val->_float = ((move->buttons >> 5) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button7))) val->_float = ((move->buttons >> 6) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button8))) val->_float = ((move->buttons >> 7) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button9))) val->_float = ((move->buttons >> 11) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button10))) val->_float = ((move->buttons >> 12) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button11))) val->_float = ((move->buttons >> 13) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button12))) val->_float = ((move->buttons >> 14) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button13))) val->_float = ((move->buttons >> 15) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button14))) val->_float = ((move->buttons >> 16) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button15))) val->_float = ((move->buttons >> 17) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.button16))) val->_float = ((move->buttons >> 18) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.buttonuse))) val->_float = ((move->buttons >> 8) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.buttonchat))) val->_float = ((move->buttons >> 9) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.cursor_active))) val->_float = ((move->buttons >> 10) & 1);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.movement))) VectorSet(val->vector, move->forwardmove, move->sidemove, move->upmove);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.cursor_screen))) VectorCopy(move->cursor_screen, val->vector);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.cursor_trace_start))) VectorCopy(move->cursor_start, val->vector);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.cursor_trace_endpos))) VectorCopy(move->cursor_impact, val->vector);
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.cursor_trace_ent))) val->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM(move->cursor_entitynumber));
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ping))) val->_float = host_client->ping * 1000.0;
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ping_packetloss))) val->_float = packetloss / (float) NETGRAPH_PACKETS;
-       if ((val = PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.ping_movementloss))) val->_float = movementloss / (float) NETGRAPH_PACKETS;
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button3) = ((move->buttons >> 2) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button4) = ((move->buttons >> 3) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button5) = ((move->buttons >> 4) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button6) = ((move->buttons >> 5) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button7) = ((move->buttons >> 6) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button8) = ((move->buttons >> 7) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button9) = ((move->buttons >> 11) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button10) = ((move->buttons >> 12) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button11) = ((move->buttons >> 13) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button12) = ((move->buttons >> 14) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button13) = ((move->buttons >> 15) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button14) = ((move->buttons >> 16) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button15) = ((move->buttons >> 17) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.button16) = ((move->buttons >> 18) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.buttonuse) = ((move->buttons >> 8) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.buttonchat) = ((move->buttons >> 9) & 1);
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.cursor_active) = ((move->buttons >> 10) & 1);
+       VectorSet(PRVM_EDICTFIELDVECTOR(host_client->edict, prog->fieldoffsets.movement), move->forwardmove, move->sidemove, move->upmove);
+       VectorCopy(move->cursor_screen, PRVM_EDICTFIELDVECTOR(host_client->edict, prog->fieldoffsets.cursor_screen));
+       VectorCopy(move->cursor_start, PRVM_EDICTFIELDVECTOR(host_client->edict, prog->fieldoffsets.cursor_trace_start));
+       VectorCopy(move->cursor_impact, PRVM_EDICTFIELDVECTOR(host_client->edict, prog->fieldoffsets.cursor_trace_endpos));
+       PRVM_EDICTFIELDVALUE(host_client->edict, prog->fieldoffsets.cursor_trace_ent)->edict = PRVM_EDICT_TO_PROG(PRVM_EDICT_NUM(move->cursor_entitynumber));
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ping) = host_client->ping * 1000.0;
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ping_packetloss) = packetloss / (float) NETGRAPH_PACKETS;
+       PRVM_EDICTFIELDFLOAT(host_client->edict, prog->fieldoffsets.ping_movementloss) = movementloss / (float) NETGRAPH_PACKETS;
 }
 
 void SV_FrameLost(int framenum)
index 0efb61b..b5a8399 100644 (file)
@@ -667,7 +667,6 @@ static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
        vec3_t original_velocity;
        vec3_t original_angles;
        vec3_t original_avelocity;
-       prvm_eval_t *val;
        trace_t trace;
 
        VectorCopy(tossent->fields.server->origin   , original_origin   );
@@ -675,11 +674,9 @@ static trace_t SV_Trace_Toss (prvm_edict_t *tossent, prvm_edict_t *ignore)
        VectorCopy(tossent->fields.server->angles   , original_angles   );
        VectorCopy(tossent->fields.server->avelocity, original_avelocity);
 
-       val = PRVM_EDICTFIELDVALUE(tossent, prog->fieldoffsets.gravity);
-       if (val != NULL && val->_float != 0)
-               gravity = val->_float;
-       else
-               gravity = 1.0;
+       gravity = PRVM_EDICTFIELDFLOAT(tossent, prog->fieldoffsets.gravity);
+       if (!gravity)
+               gravity = 1.0f;
        gravity *= sv_gravity.value * 0.025;
 
        for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
@@ -995,7 +992,7 @@ static void VM_SV_findradius (void)
                        VectorMAMAM(1, eorg, -0.5f, ent->fields.server->mins, -0.5f, ent->fields.server->maxs, eorg);
                if (DotProduct(eorg, eorg) < radius2)
                {
-                       PRVM_EDICTFIELDVALUE(ent,chainfield)->edict = PRVM_EDICT_TO_PROG(chain);
+                       PRVM_EDICTFIELDEDICT(ent,chainfield) = PRVM_EDICT_TO_PROG(chain);
                        chain = ent;
                }
        }
@@ -1713,7 +1710,7 @@ static void VM_SV_copyentity (void)
                VM_Warning("copyentity: can not modify free entity\n");
                return;
        }
-       memcpy(out->fields.vp, in->fields.vp, prog->progs->entityfields * 4);
+       memcpy(out->fields.vp, in->fields.vp, prog->entityfields * 4);
        SV_LinkEdict(out);
 }
 
@@ -1731,7 +1728,6 @@ static void VM_SV_setcolor (void)
 {
        client_t *client;
        int entnum, i;
-       prvm_eval_t *val;
 
        VM_SAFEPARMCOUNT(2, VM_SV_setcolor);
        entnum = PRVM_G_EDICTNUM(OFS_PARM0);
@@ -1746,8 +1742,7 @@ static void VM_SV_setcolor (void)
        client = svs.clients + entnum-1;
        if (client->edict)
        {
-               if ((val = PRVM_EDICTFIELDVALUE(client->edict, prog->fieldoffsets.clientcolors)))
-                       val->_float = i;
+               PRVM_EDICTFIELDFLOAT(client->edict, prog->fieldoffsets.clientcolors) = i;
                client->edict->fields.server->team = (i & 15) + 1;
        }
        client->colors = i;
@@ -2296,8 +2291,8 @@ static void VM_SV_setattachment (void)
        prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
        prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
        const char *tagname = PRVM_G_STRING(OFS_PARM2);
-       prvm_eval_t *v;
        dp_model_t *model;
+       int tagindex;
        VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
 
        if (e == prog->edicts)
@@ -2314,25 +2309,23 @@ static void VM_SV_setattachment (void)
        if (tagentity == NULL)
                tagentity = prog->edicts;
 
-       v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_entity);
-       if (v)
-               v->edict = PRVM_EDICT_TO_PROG(tagentity);
+       tagindex = 0;
 
-       v = PRVM_EDICTFIELDVALUE(e, prog->fieldoffsets.tag_index);
-       if (v)
-               v->_float = 0;
        if (tagentity != NULL && tagentity != prog->edicts && tagname && tagname[0])
        {
                model = SV_GetModelFromEdict(tagentity);
                if (model)
                {
-                       v->_float = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
-                       if (v->_float == 0)
+                       tagindex = Mod_Alias_GetTagIndexForName(model, (int)tagentity->fields.server->skin, tagname);
+                       if (tagindex == 0)
                                Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i (model \"%s\") but could not find it\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity), model->name);
                }
                else
                        Con_DPrintf("setattachment(edict %i, edict %i, string \"%s\"): tried to find tag named \"%s\" on entity %i but it has no model\n", PRVM_NUM_FOR_EDICT(e), PRVM_NUM_FOR_EDICT(tagentity), tagname, tagname, PRVM_NUM_FOR_EDICT(tagentity));
        }
+
+       PRVM_EDICTFIELDEDICT(e, prog->fieldoffsets.tag_entity) = PRVM_EDICT_TO_PROG(tagentity);
+       PRVM_EDICTFIELDFLOAT(e, prog->fieldoffsets.tag_index) = tagindex;
 }
 
 /////////////////////////////////////////
@@ -2373,14 +2366,12 @@ int SV_GetExtendedTagInfo (prvm_edict_t *e, int tagindex, int *parentindex, cons
 
 void SV_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
 {
-       prvm_eval_t *val;
        float scale;
        float pitchsign = 1;
 
-       scale = 1;
-       val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
-       if (val && val->_float != 0)
-               scale = val->_float;
+       scale = PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.scale);
+       if (!scale)
+               scale = 1.0f;
        
        if (viewmatrix)
                Matrix4x4_CreateFromQuakeEntity(out, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + ent->fields.server->view_ofs[2], ent->fields.server->v_angle[0], ent->fields.server->v_angle[1], ent->fields.server->v_angle[2], scale * cl_viewmodel_scale.value);
@@ -2418,7 +2409,6 @@ extern cvar_t cl_bobup;
 int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 {
        int ret;
-       prvm_eval_t *val;
        int modelindex, attachloop;
        matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
        dp_model_t *model;
@@ -2456,10 +2446,10 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
                Matrix4x4_Concat(&tagmatrix, &attachmatrix, out);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
                // next iteration we process the parent entity
-               if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_entity)) && val->edict)
+               if (PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.tag_entity))
                {
-                       tagindex = (int)PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.tag_index)->_float;
-                       ent = PRVM_EDICT_NUM(val->edict);
+                       tagindex = (int)PRVM_EDICTFIELDFLOAT(ent, prog->fieldoffsets.tag_index);
+                       ent = PRVM_EDICT_NUM(PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.tag_entity));
                }
                else
                        break;
@@ -2467,10 +2457,10 @@ int SV_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
        }
 
        // RENDER_VIEWMODEL magic
-       if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.viewmodelforclient)) && val->edict)
+       if (PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.viewmodelforclient))
        {
                Matrix4x4_Copy(&tagmatrix, out);
-               ent = PRVM_EDICT_NUM(val->edict);
+               ent = PRVM_EDICT_NUM(PRVM_EDICTFIELDEDICT(ent, prog->fieldoffsets.viewmodelforclient));
 
                SV_GetEntityMatrix(ent, &entitymatrix, true);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
@@ -2548,7 +2538,6 @@ static void VM_SV_gettaginfo (void)
        int parentindex;
        const char *tagname;
        int returncode;
-       prvm_eval_t *val;
        vec3_t fo, le, up, trans;
        const dp_model_t *model;
 
@@ -2567,18 +2556,12 @@ static void VM_SV_gettaginfo (void)
        SV_GetExtendedTagInfo(e, tagindex, &parentindex, &tagname, &tag_localmatrix);
        Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
 
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_parent)))
-               val->_float = parentindex;
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_name)))
-               val->string = tagname ? PRVM_SetTempString(tagname) : 0;
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_offset)))
-               VectorCopy(trans, val->vector);
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_forward)))
-               VectorCopy(fo, val->vector);
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_right)))
-               VectorScale(le, -1, val->vector);
-       if((val = PRVM_GLOBALFIELDVALUE(prog->globaloffsets.gettaginfo_up)))
-               VectorCopy(up, val->vector);
+       PRVM_GLOBALFIELDFLOAT(prog->globaloffsets.gettaginfo_parent) = parentindex;
+       PRVM_GLOBALFIELDSTRING(prog->globaloffsets.gettaginfo_name) = tagname ? PRVM_SetTempString(tagname) : 0;
+       VectorCopy(trans, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.gettaginfo_offset));
+       VectorCopy(fo, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.gettaginfo_forward));
+       VectorScale(le, -1, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.gettaginfo_right));
+       VectorCopy(up, PRVM_GLOBALFIELDVECTOR(prog->globaloffsets.gettaginfo_up));
 
        switch(returncode)
        {
diff --git a/todo b/todo
index 764cf7d..6c60804 100644 (file)
--- a/todo
+++ b/todo
@@ -1,6 +1,8 @@
 - todo: difficulty ratings are: 0 = trivial, 1 = easy, 2 = easy-moderate, 3 = moderate, 4 = moderate-hard, 5 = hard, 6 = hard++, 7 = nightmare, d = done, -d = done but have not notified the people who asked for it, f = failed, -f = failed but have not notified the people who asked for it
 -d bug darkplaces d3d9: drawsetcliparea not working right - seems to be Y-flipped, this also affects menus in Steelstorm (VorteX)
 -d bug darkplaces d3d9: overbright particles get weird colors (VorteX)
+0 optimize darkplaces renderer: get rid of attenuation texture on lights because math is faster, add fastpath for no normalmap (Lava_Croft)
+0 bug darkplaces filesystem: -game nehahra does not load properly; menu does not work properly - probably not activating gamemode
 0 bug darkplaces client csqc: CSQC_InputEvent is supposed to handle mouse movement, compare to FTEQW code (avirox)
 0 bug darkplaces client csqc: engine prediction function is not implemented - could just return the engine's current cl.movement_origin (Spike)
 0 bug darkplaces client csqc: entities not being drawn with VF_PERSPECTIVE 0? (daemon)
diff --git a/world.c b/world.c
index b5b1def..e914f38 100644 (file)
--- a/world.c
+++ b/world.c
@@ -1746,7 +1746,6 @@ static void World_Physics_Frame_BodyToEntity(world_t *world, prvm_edict_t *ed)
        int movetype;
        matrix4x4_t bodymatrix;
        matrix4x4_t entitymatrix;
-       prvm_eval_t *val;
        vec3_t angles;
        vec3_t avelocity;
        vec3_t forward, left, up;
@@ -1756,11 +1755,10 @@ static void World_Physics_Frame_BodyToEntity(world_t *world, prvm_edict_t *ed)
        int jointtype;
        if (!body)
                return;
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.movetype);
-       movetype = (int)val->_float;
+       movetype = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.movetype);
        if (movetype != MOVETYPE_PHYSICS)
        {
-               jointtype = 0;val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.jointtype);if (val) jointtype = (int)val->_float;
+               jointtype = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.jointtype);
                switch(jointtype)
                {
                        // TODO feed back data from physics
@@ -1817,14 +1815,14 @@ static void World_Physics_Frame_BodyToEntity(world_t *world, prvm_edict_t *ed)
                avelocity[PITCH] *= pitchsign;
        }
 
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.origin);if (val) VectorCopy(origin, val->vector);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.velocity);if (val) VectorCopy(velocity, val->vector);
-       //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_forward);if (val) VectorCopy(forward, val->vector);
-       //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_left);if (val) VectorCopy(left, val->vector);
-       //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_up);if (val) VectorCopy(up, val->vector);
-       //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.spinvelocity);if (val) VectorCopy(spinvelocity, val->vector);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.angles);if (val) VectorCopy(angles, val->vector);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.avelocity);if (val) VectorCopy(avelocity, val->vector);
+       VectorCopy(origin, PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.origin));
+       VectorCopy(velocity, PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.velocity));
+       //VectorCopy(forward, PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.axis_forward));
+       //VectorCopy(left, PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.axis_left));
+       //VectorCopy(up, PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.axis_up));
+       //VectorCopy(spinvelocity, PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.spinvelocity));
+       VectorCopy(angles, PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.angles));
+       VectorCopy(avelocity, PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.avelocity));
 
        // values for BodyFromEntity to check if the qc modified anything later
        VectorCopy(origin, ed->priv.server->ode_origin);
@@ -1850,19 +1848,18 @@ static void World_Physics_Frame_JointFromEntity(world_t *world, prvm_edict_t *ed
        int enemy = 0, aiment = 0;
        vec3_t origin, velocity, angles, forward, left, up, movedir;
        vec_t CFM, ERP, FMax, Stop, Vel;
-       prvm_eval_t *val;
        VectorClear(origin);
        VectorClear(velocity);
        VectorClear(angles);
        VectorClear(movedir);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.movetype);if (val) movetype = (int)val->_float;
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.jointtype);if (val) jointtype = (int)val->_float;
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.enemy);if (val) enemy = val->_int;
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.aiment);if (val) aiment = val->_int;
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.origin);if (val) VectorCopy(val->vector, origin);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.velocity);if (val) VectorCopy(val->vector, velocity);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.angles);if (val) VectorCopy(val->vector, angles);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.movedir);if (val) VectorCopy(val->vector, movedir);
+       movetype = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.movetype);
+       jointtype = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.jointtype);
+       enemy = PRVM_EDICTFIELDEDICT(ed, prog->fieldoffsets.enemy);
+       aiment = PRVM_EDICTFIELDEDICT(ed, prog->fieldoffsets.aiment);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.origin), origin);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.velocity), velocity);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.angles), angles);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.movedir), movedir);
        if(movetype == MOVETYPE_PHYSICS)
                jointtype = 0; // can't have both
        if(enemy <= 0 || enemy >= prog->num_edicts || prog->edicts[enemy].priv.required->free || prog->edicts[enemy].priv.server->ode_body == 0)
@@ -2044,7 +2041,6 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
        int triangleindex;
        int vertexindex;
        mempool_t *mempool;
-       prvm_eval_t *val;
        qboolean modified = false;
        vec3_t angles;
        vec3_t avelocity;
@@ -2074,9 +2070,9 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
 #endif
        VectorClear(entmins);
        VectorClear(entmaxs);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.solid);if (val) solid = (int)val->_float;
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.movetype);if (val) movetype = (int)val->_float;
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.scale);if (val && val->_float) scale = val->_float;
+       solid = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.solid);
+       movetype = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.movetype);
+       scale = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.scale);if (!scale) scale = 1.0f;
        modelindex = 0;
        if (world == &sv.world)
                mempool = sv_mempool;
@@ -2088,9 +2084,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
        switch(solid)
        {
        case SOLID_BSP:
-               val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.modelindex);
-               if (val)
-                       modelindex = (int)val->_float;
+               modelindex = (int)PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.modelindex);
                if (world == &sv.world)
                        model = SV_GetModelByIndex(modelindex);
                else if (world == &cl.world)
@@ -2101,7 +2095,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                {
                        VectorScale(model->normalmins, scale, entmins);
                        VectorScale(model->normalmaxs, scale, entmaxs);
-                       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.mass);if (val) massval = val->_float;
+                       massval = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.mass);
                }
                else
                {
@@ -2115,9 +2109,9 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
        case SOLID_PHYSICS_BOX:
        case SOLID_PHYSICS_SPHERE:
        case SOLID_PHYSICS_CAPSULE:
-               val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.mins);if (val) VectorCopy(val->vector, entmins);
-               val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.maxs);if (val) VectorCopy(val->vector, entmaxs);
-               val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.mass);if (val) massval = val->_float;
+               VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.mins), entmins);
+               VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.maxs), entmaxs);
+               massval = PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.mass);
                break;
        default:
                if (ed->priv.server->ode_physics)
@@ -2157,7 +2151,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                if (massval * geomsize[0] * geomsize[1] * geomsize[2] == 0)
                {
                        if (movetype == MOVETYPE_PHYSICS)
-                               Con_Printf("entity %i (classname %s) .mass * .size_x * .size_y * .size_z == 0\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.classname)->string));
+                               Con_Printf("entity %i (classname %s) .mass * .size_x * .size_y * .size_z == 0\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.classname)));
                        massval = 1.0f;
                        VectorSet(geomsize, 1.0f, 1.0f, 1.0f);
                }
@@ -2168,7 +2162,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                        ed->priv.server->ode_offsetmatrix = identitymatrix;
                        if (!model)
                        {
-                               Con_Printf("entity %i (classname %s) has no model\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.classname)->string));
+                               Con_Printf("entity %i (classname %s) has no model\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.classname)));
                                goto treatasbox;
                        }
                        // add an optimized mesh to the model containing only the SUPERCONTENTS_SOLID surfaces
@@ -2176,7 +2170,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                                Mod_CreateCollisionMesh(model);
                        if (!model->brush.collisionmesh || !model->brush.collisionmesh->numtriangles)
                        {
-                               Con_Printf("entity %i (classname %s) has no geometry\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.classname)->string));
+                               Con_Printf("entity %i (classname %s) has no geometry\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.classname)));
                                goto treatasbox;
                        }
                        // ODE requires persistent mesh storage, so we need to copy out
@@ -2294,16 +2288,16 @@ treatasbox:
        VectorClear(angles);
        VectorClear(avelocity);
        gravity = true;
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.origin);if (val) VectorCopy(val->vector, origin);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.velocity);if (val) VectorCopy(val->vector, velocity);
-       //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_forward);if (val) VectorCopy(val->vector, forward);
-       //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_left);if (val) VectorCopy(val->vector, left);
-       //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.axis_up);if (val) VectorCopy(val->vector, up);
-       //val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.spinvelocity);if (val) VectorCopy(val->vector, spinvelocity);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.angles);if (val) VectorCopy(val->vector, angles);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.avelocity);if (val) VectorCopy(val->vector, avelocity);
-       val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.gravity);if (val) { if(val->_float != 0.0f && val->_float < 0.5f) gravity = false; }
-       if(ed == prog->edicts)
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.origin), origin);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.velocity), velocity);
+       //VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.axis_forward), forward);
+       //VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.axis_left), left);
+       //VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.axis_up), up);
+       //VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.spinvelocity), spinvelocity);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.angles), angles);
+       VectorCopy(PRVM_EDICTFIELDVECTOR(ed, prog->fieldoffsets.avelocity), avelocity);
+       if (PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.gravity) != 0.0f && PRVM_EDICTFIELDFLOAT(ed, prog->fieldoffsets.gravity) < 0.5f) gravity = false;
+       if (ed == prog->edicts)
                gravity = false;
 
        // compatibility for legacy entities
@@ -2352,9 +2346,9 @@ treatasbox:
                if (IS_NAN(test))
                {
                        modified = true;
-                       //Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .axis_forward = '%f %f %f' .axis_left = '%f %f %f' .axis_up = %f %f %f' .spinvelocity = '%f %f %f'\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.classname)->string), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], forward[0], forward[1], forward[2], left[0], left[1], left[2], up[0], up[1], up[2], spinvelocity[0], spinvelocity[1], spinvelocity[2]);
+                       //Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .axis_forward = '%f %f %f' .axis_left = '%f %f %f' .axis_up = %f %f %f' .spinvelocity = '%f %f %f'\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.classname)), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], forward[0], forward[1], forward[2], left[0], left[1], left[2], up[0], up[1], up[2], spinvelocity[0], spinvelocity[1], spinvelocity[2]);
                        if (physics_ode_trick_fixnan.integer >= 2)
-                               Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .angles = '%f %f %f' .avelocity = '%f %f %f'\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.classname)->string), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], angles[0], angles[1], angles[2], avelocity[0], avelocity[1], avelocity[2]);
+                               Con_Printf("Fixing NAN values on entity %i : .classname = \"%s\" .origin = '%f %f %f' .velocity = '%f %f %f' .angles = '%f %f %f' .avelocity = '%f %f %f'\n", PRVM_NUM_FOR_EDICT(ed), PRVM_GetString(PRVM_EDICTFIELDSTRING(ed, prog->fieldoffsets.classname)), origin[0], origin[1], origin[2], velocity[0], velocity[1], velocity[2], angles[0], angles[1], angles[2], avelocity[0], avelocity[1], avelocity[2]);
                        test = VectorLength2(origin);
                        if (IS_NAN(test))
                                VectorClear(origin);
@@ -2506,7 +2500,6 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
        dJointID c;
        int i;
        int numcontacts;
-       prvm_eval_t *val;
        float bouncefactor1 = 0.0f;
        float bouncestop1 = 60.0f / 800.0f;
        float bouncefactor2 = 0.0f;
@@ -2541,13 +2534,10 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
                ed1 = NULL;
        if(ed1)
        {
-               val = PRVM_EDICTFIELDVALUE(ed1, prog->fieldoffsets.bouncefactor);
-               if (val!=0 && val->_float)
-                       bouncefactor1 = val->_float;
-
-               val = PRVM_EDICTFIELDVALUE(ed1, prog->fieldoffsets.bouncestop);
-               if (val!=0 && val->_float)
-                       bouncestop1 = val->_float;
+               bouncefactor1 = PRVM_EDICTFIELDFLOAT(ed1, prog->fieldoffsets.bouncefactor);
+               bouncestop1 = PRVM_EDICTFIELDFLOAT(ed1, prog->fieldoffsets.bouncestop);
+               if (!bouncestop1)
+                       bouncestop1 = 60.0f / 800.0f;
        }
 
        ed2 = (prvm_edict_t *) dGeomGetData(o2);
@@ -2555,13 +2545,10 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
                ed2 = NULL;
        if(ed2)
        {
-               val = PRVM_EDICTFIELDVALUE(ed2, prog->fieldoffsets.bouncefactor);
-               if (val!=0 && val->_float)
-                       bouncefactor2 = val->_float;
-
-               val = PRVM_EDICTFIELDVALUE(ed2, prog->fieldoffsets.bouncestop);
-               if (val!=0 && val->_float)
-                       bouncestop2 = val->_float;
+               bouncefactor2 = PRVM_EDICTFIELDFLOAT(ed2, prog->fieldoffsets.bouncefactor);
+               bouncestop2 = PRVM_EDICTFIELDFLOAT(ed2, prog->fieldoffsets.bouncestop);
+               if (!bouncestop2)
+                       bouncestop2 = 60.0f / 800.0f;
        }
 
        if(!strcmp(prog->name, "server"))