]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - clvm_cmds.c
Refactor the code to make r_view and r_viewcache members of r_refdef,
[xonotic/darkplaces.git] / clvm_cmds.c
index 804db8a79017e7622bb16f8a285493d4f9f05582..c077f2877328412ff7327be8c06bd2bf8f9a4638 100644 (file)
@@ -96,6 +96,7 @@ static void VM_CL_setmodel (void)
 
        e->fields.client->modelindex = 0;
        e->fields.client->model = 0;
+       VM_Warning ("setmodel: model '%s' not precached\n", m);
 }
 
 // #4 void(entity e, vector min, vector max) setsize
@@ -200,6 +201,7 @@ static void VM_CL_spawn (void)
 {
        prvm_edict_t *ed;
        ed = PRVM_ED_Alloc();
+       // FIXME: WTF.. this should be removed imo.. entnum points to the server.. [12/17/2007 Black]
        ed->fields.client->entnum = PRVM_NUM_FOR_EDICT(ed);     //[515]: not needed any more ?
        VM_RETURN_EDICT(ed);
 }
@@ -212,7 +214,7 @@ static void VM_CL_traceline (void)
        int             move;
        prvm_edict_t    *ent;
 
-       VM_SAFEPARMCOUNTRANGE(4, 8, VM_CL_traceline); // allow more parameters for future expansion
+       VM_SAFEPARMCOUNTRANGE(4, 4, VM_CL_traceline);
 
        prog->xfunction->builtinsprofile += 30;
 
@@ -639,7 +641,7 @@ extern qboolean CSQC_AddRenderEdict (prvm_edict_t *ed);//csprogs.c
 static void CSQC_R_RecalcView (void)
 {
        extern matrix4x4_t viewmodelmatrix;
-       Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], 1);
+       Matrix4x4_CreateFromQuakeEntity(&r_refdef.view.matrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], 1);
        Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], cl_viewmodel_scale.value);
 }
 
@@ -652,20 +654,20 @@ static void VM_CL_R_ClearScene (void)
        r_refdef.numentities = 0;
        r_refdef.numlights = 0;
        // FIXME: restore these to the values from VM_CL_UpdateView
-       r_view.x = 0;
-       r_view.y = 0;
-       r_view.z = 0;
-       r_view.width = vid.width;
-       r_view.height = vid.height;
-       r_view.depth = 1;
+       r_refdef.view.x = 0;
+       r_refdef.view.y = 0;
+       r_refdef.view.z = 0;
+       r_refdef.view.width = vid.width;
+       r_refdef.view.height = vid.height;
+       r_refdef.view.depth = 1;
        // FIXME: restore frustum_x/frustum_y
-       r_view.useperspective = true;
-       r_view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
-       r_view.frustum_x = r_view.frustum_y * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
-       r_view.frustum_x *= r_refdef.frustumscale_x;
-       r_view.frustum_y *= r_refdef.frustumscale_y;
-       r_view.ortho_x = scr_fov.value * (3.0 / 4.0) * (float)r_view.width / (float)r_view.height / vid_pixelheight.value;
-       r_view.ortho_y = scr_fov.value * (3.0 / 4.0);
+       r_refdef.view.useperspective = true;
+       r_refdef.view.frustum_y = tan(scr_fov.value * M_PI / 360.0) * (3.0/4.0) * cl.viewzoom;
+       r_refdef.view.frustum_x = r_refdef.view.frustum_y * (float)r_refdef.view.width / (float)r_refdef.view.height / vid_pixelheight.value;
+       r_refdef.view.frustum_x *= r_refdef.frustumscale_x;
+       r_refdef.view.frustum_y *= r_refdef.frustumscale_y;
+       r_refdef.view.ortho_x = scr_fov.value * (3.0 / 4.0) * (float)r_refdef.view.width / (float)r_refdef.view.height / vid_pixelheight.value;
+       r_refdef.view.ortho_y = scr_fov.value * (3.0 / 4.0);
        // FIXME: restore cl.csqc_origin
        // FIXME: restore cl.csqc_angles
        cl.csqc_vidvars.drawworld = true;
@@ -726,79 +728,103 @@ static void VM_CL_R_SetView (void)
 
        switch(c)
        {
-       case VF_MIN:                    r_view.x = (int)(f[0] * vid.width / vid_conwidth.value);
-                                                       r_view.y = (int)(f[1] * vid.height / vid_conheight.value);
-                                                       break;
-       case VF_MIN_X:                  r_view.x = (int)(k * vid.width / vid_conwidth.value);
-                                                       break;
-       case VF_MIN_Y:                  r_view.y = (int)(k * vid.height / vid_conheight.value);
-                                                       break;
-       case VF_SIZE:                   r_view.width = (int)(f[0] * vid.width / vid_conwidth.value);
-                                                       r_view.height = (int)(f[1] * vid.height / vid_conheight.value);
-                                                       break;
-       case VF_SIZE_Y:                 r_view.width = (int)(k * vid.width / vid_conwidth.value);
-                                                       break;
-       case VF_SIZE_X:                 r_view.height = (int)(k * vid.height / vid_conheight.value);
-                                                       break;
-       case VF_VIEWPORT:               r_view.x = (int)(f[0] * vid.width / vid_conwidth.value);
-                                                       r_view.y = (int)(f[1] * vid.height / vid_conheight.value);
-                                                       f = PRVM_G_VECTOR(OFS_PARM2);
-                                                       r_view.width = (int)(f[0] * vid.width / vid_conwidth.value);
-                                                       r_view.height = (int)(f[1] * vid.height / vid_conheight.value);
-                                                       break;
-       case VF_FOV:                    r_view.frustum_x = tan(f[0] * M_PI / 360.0);r_view.ortho_x = f[0];
-                                                       r_view.frustum_y = tan(f[1] * M_PI / 360.0);r_view.ortho_y = f[1];
-                                                       break;
-       case VF_FOVX:                   r_view.frustum_x = tan(k * M_PI / 360.0);r_view.ortho_x = k;
-                                                       break;
-       case VF_FOVY:                   r_view.frustum_y = tan(k * M_PI / 360.0);r_view.ortho_y = k;
-                                                       break;
-       case VF_ORIGIN:                 VectorCopy(f, cl.csqc_origin);
-                                                       CSQC_R_RecalcView();
-                                                       break;
-       case VF_ORIGIN_X:               cl.csqc_origin[0] = k;
-                                                       CSQC_R_RecalcView();
-                                                       break;
-       case VF_ORIGIN_Y:               cl.csqc_origin[1] = k;
-                                                       CSQC_R_RecalcView();
-                                                       break;
-       case VF_ORIGIN_Z:               cl.csqc_origin[2] = k;
-                                                       CSQC_R_RecalcView();
-                                                       break;
-       case VF_ANGLES:                 VectorCopy(f, cl.csqc_angles);
-                                                       CSQC_R_RecalcView();
-                                                       break;
-       case VF_ANGLES_X:               cl.csqc_angles[0] = k;
-                                                       CSQC_R_RecalcView();
-                                                       break;
-       case VF_ANGLES_Y:               cl.csqc_angles[1] = k;
-                                                       CSQC_R_RecalcView();
-                                                       break;
-       case VF_ANGLES_Z:               cl.csqc_angles[2] = k;
-                                                       CSQC_R_RecalcView();
-                                                       break;
-       case VF_DRAWWORLD:              cl.csqc_vidvars.drawworld = k;
-                                                       break;
-       case VF_DRAWENGINESBAR: cl.csqc_vidvars.drawenginesbar = k;
-                                                       break;
-       case VF_DRAWCROSSHAIR:  cl.csqc_vidvars.drawcrosshair = k;
-                                                       break;
-
-       case VF_CL_VIEWANGLES:  VectorCopy(f, cl.viewangles);
-                                                       break;
-       case VF_CL_VIEWANGLES_X:cl.viewangles[0] = k;
-                                                       break;
-       case VF_CL_VIEWANGLES_Y:cl.viewangles[1] = k;
-                                                       break;
-       case VF_CL_VIEWANGLES_Z:cl.viewangles[2] = k;
-                                                       break;
-
-       case VF_PERSPECTIVE:    r_view.useperspective = k != 0;
-                                                       break;
-
-       default:                                PRVM_G_FLOAT(OFS_RETURN) = 0;
-                                                       VM_Warning("VM_CL_R_SetView : unknown parm %i\n", c);
-                                                       return;
+       case VF_MIN:
+               r_refdef.view.x = (int)(f[0] * vid.width / vid_conwidth.value);
+               r_refdef.view.y = (int)(f[1] * vid.height / vid_conheight.value);
+               break;
+       case VF_MIN_X:
+               r_refdef.view.x = (int)(k * vid.width / vid_conwidth.value);
+               break;
+       case VF_MIN_Y:
+               r_refdef.view.y = (int)(k * vid.height / vid_conheight.value);
+               break;
+       case VF_SIZE:
+               r_refdef.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
+               r_refdef.view.height = (int)(f[1] * vid.height / vid_conheight.value);
+               break;
+       case VF_SIZE_Y:
+               r_refdef.view.width = (int)(k * vid.width / vid_conwidth.value);
+               break;
+       case VF_SIZE_X:
+               r_refdef.view.height = (int)(k * vid.height / vid_conheight.value);
+               break;
+       case VF_VIEWPORT:
+               r_refdef.view.x = (int)(f[0] * vid.width / vid_conwidth.value);
+               r_refdef.view.y = (int)(f[1] * vid.height / vid_conheight.value);
+               f = PRVM_G_VECTOR(OFS_PARM2);
+               r_refdef.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
+               r_refdef.view.height = (int)(f[1] * vid.height / vid_conheight.value);
+               break;
+       case VF_FOV:
+               r_refdef.view.frustum_x = tan(f[0] * M_PI / 360.0);r_refdef.view.ortho_x = f[0];
+               r_refdef.view.frustum_y = tan(f[1] * M_PI / 360.0);r_refdef.view.ortho_y = f[1];
+               break;
+       case VF_FOVX:
+               r_refdef.view.frustum_x = tan(k * M_PI / 360.0);r_refdef.view.ortho_x = k;
+               break;
+       case VF_FOVY:
+               r_refdef.view.frustum_y = tan(k * M_PI / 360.0);r_refdef.view.ortho_y = k;
+               break;
+       case VF_ORIGIN:
+               VectorCopy(f, cl.csqc_origin);
+               CSQC_R_RecalcView();
+               break;
+       case VF_ORIGIN_X:
+               cl.csqc_origin[0] = k;
+               CSQC_R_RecalcView();
+               break;
+       case VF_ORIGIN_Y:
+               cl.csqc_origin[1] = k;
+               CSQC_R_RecalcView();
+               break;
+       case VF_ORIGIN_Z:
+               cl.csqc_origin[2] = k;
+               CSQC_R_RecalcView();
+               break;
+       case VF_ANGLES:
+               VectorCopy(f, cl.csqc_angles);
+               CSQC_R_RecalcView();
+               break;
+       case VF_ANGLES_X:
+               cl.csqc_angles[0] = k;
+               CSQC_R_RecalcView();
+               break;
+       case VF_ANGLES_Y:
+               cl.csqc_angles[1] = k;
+               CSQC_R_RecalcView();
+               break;
+       case VF_ANGLES_Z:
+               cl.csqc_angles[2] = k;
+               CSQC_R_RecalcView();
+               break;
+       case VF_DRAWWORLD:
+               cl.csqc_vidvars.drawworld = k;
+               break;
+       case VF_DRAWENGINESBAR:
+               cl.csqc_vidvars.drawenginesbar = k;
+               break;
+       case VF_DRAWCROSSHAIR:
+               cl.csqc_vidvars.drawcrosshair = k;
+               break;
+       case VF_CL_VIEWANGLES:
+               VectorCopy(f, cl.viewangles);
+               break;
+       case VF_CL_VIEWANGLES_X:
+               cl.viewangles[0] = k;
+               break;
+       case VF_CL_VIEWANGLES_Y:
+               cl.viewangles[1] = k;
+               break;
+       case VF_CL_VIEWANGLES_Z:
+               cl.viewangles[2] = k;
+               break;
+       case VF_PERSPECTIVE:
+               r_refdef.view.useperspective = k != 0;
+               break;
+       default:
+               PRVM_G_FLOAT(OFS_RETURN) = 0;
+               VM_Warning("VM_CL_R_SetView : unknown parm %i\n", c);
+               return;
        }
        PRVM_G_FLOAT(OFS_RETURN) = 1;
 }
@@ -819,7 +845,7 @@ static void VM_CL_R_AddDynamicLight (void)
 {
        float           *pos, *col;
        matrix4x4_t     matrix;
-       VM_SAFEPARMCOUNTRANGE(3, 8, VM_CL_R_AddDynamicLight); // allow more than 3 because we may extend this in the future
+       VM_SAFEPARMCOUNTRANGE(3, 3, VM_CL_R_AddDynamicLight);
 
        // if we've run out of dlights, just return
        if (r_refdef.numlights >= MAX_DLIGHTS)
@@ -841,8 +867,8 @@ static void VM_CL_unproject (void)
 
        VM_SAFEPARMCOUNT(1, VM_CL_unproject);
        f = PRVM_G_VECTOR(OFS_PARM0);
-       VectorSet(temp, f[2], f[0] * f[2] * -r_view.frustum_x * 2.0 / r_view.width, f[1] * f[2] * -r_view.frustum_y * 2.0 / r_view.height);
-       Matrix4x4_Transform(&r_view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
+       VectorSet(temp, f[2], f[0] * f[2] * -r_refdef.view.frustum_x * 2.0 / r_refdef.view.width, f[1] * f[2] * -r_refdef.view.frustum_y * 2.0 / r_refdef.view.height);
+       Matrix4x4_Transform(&r_refdef.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
 }
 
 //#311 vector (vector v) cs_project (EXT_CSQC)
@@ -854,9 +880,9 @@ static void VM_CL_project (void)
 
        VM_SAFEPARMCOUNT(1, VM_CL_project);
        f = PRVM_G_VECTOR(OFS_PARM0);
-       Matrix4x4_Invert_Simple(&m, &r_view.matrix);
+       Matrix4x4_Invert_Simple(&m, &r_refdef.view.matrix);
        Matrix4x4_Transform(&m, f, v);
-       VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_view.frustum_x*0.5*r_view.width, v[2]/v[0]/-r_view.frustum_y*r_view.height*0.5, v[0]);
+       VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_refdef.view.frustum_x*0.5*r_refdef.view.width, v[2]/v[0]/-r_refdef.view.frustum_y*r_refdef.view.height*0.5, v[0]);
 }
 
 //#330 float(float stnum) getstatf (EXT_CSQC)
@@ -1023,7 +1049,7 @@ static void VM_CL_setcursormode (void)
 {
        VM_SAFEPARMCOUNT(1, VM_CL_setcursormode);
        cl.csqc_wantsmousemove = PRVM_G_FLOAT(OFS_PARM0);
-       cl_ignoremousemove = true;
+       cl_ignoremousemoves = 2;
 }
 
 //#345 float(float framenum) getinputstate (EXT_CSQC)
@@ -1232,12 +1258,12 @@ static void VM_CL_makestatic (void)
                entity_t *staticent = &cl.static_entities[cl.num_static_entities++];
 
                // copy it to the current state
+               memset(staticent, 0, sizeof(*staticent));
                staticent->render.model = CL_GetModelByIndex((int)ent->fields.client->modelindex);
                staticent->render.frame1 = staticent->render.frame2 = (int)ent->fields.client->frame;
                staticent->render.framelerp = 0;
                // make torchs play out of sync
                staticent->render.frame1time = staticent->render.frame2time = lhrandom(-10, -1);
-               staticent->render.colormap = (int)ent->fields.client->colormap; // no special coloring
                staticent->render.skinnum = (int)ent->fields.client->skin;
                staticent->render.effects = (int)ent->fields.client->effects;
                staticent->render.alpha = 1;
@@ -1257,7 +1283,6 @@ static void VM_CL_makestatic (void)
                }
                else
                        Matrix4x4_CreateFromQuakeEntity(&staticent->render.matrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], staticent->render.scale);
-               CL_UpdateRenderEntity(&staticent->render);
 
                // either fullbright or lit
                if (!(staticent->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer)
@@ -1265,6 +1290,8 @@ static void VM_CL_makestatic (void)
                // turn off shadows from transparent objects
                if (!(staticent->render.effects & (EF_NOSHADOW | EF_ADDITIVE | EF_NODEPTHTEST)) && (staticent->render.alpha >= 1))
                        staticent->render.flags |= RENDER_SHADOW;
+
+               CL_UpdateRenderEntity(&staticent->render);
        }
        else
                Con_Printf("Too many static entities");
@@ -2017,6 +2044,7 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
        matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
        prvm_edict_t *attachent;
        model_t *model;
+       float scale;
 
        *out = identitymatrix; // warnings and errors return identical matrix
 
@@ -2061,10 +2089,11 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
                                attachmatrix = identitymatrix;
 
                        // apply transformation by child entity matrix
+                       scale = 1;
                        val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
-                       if (val->_float == 0)
-                               val->_float = 1;
-                       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], val->_float);
+                       if (val && val->_float != 0)
+                               scale = val->_float;
+                       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], scale);
                        Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
                        Matrix4x4_Copy(&tagmatrix, out);
 
@@ -2081,22 +2110,24 @@ int CL_GetTagMatrix (matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
        }
 
        // normal or RENDER_VIEWMODEL entity (or main parent entity on attach chain)
+       scale = 1;
        val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
-       if (val->_float == 0)
-               val->_float = 1;
+       if (val && val->_float != 0)
+               scale = val->_float;
        // Alias models have inverse pitch, bmodels can't have tags, so don't check for modeltype...
-       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], val->_float);
+       Matrix4x4_CreateFromQuakeEntity(&entitymatrix, ent->fields.client->origin[0], ent->fields.client->origin[1], ent->fields.client->origin[2], -ent->fields.client->angles[0], ent->fields.client->angles[1], ent->fields.client->angles[2], scale);
        Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
 
        if ((val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.renderflags)) && (RF_VIEWMODEL & (int)val->_float))
        {// RENDER_VIEWMODEL magic
                Matrix4x4_Copy(&tagmatrix, out);
 
+               scale = 1;
                val = PRVM_EDICTFIELDVALUE(ent, prog->fieldoffsets.scale);
-               if (val->_float == 0)
-                       val->_float = 1;
+               if (val && val->_float != 0)
+                       scale = val->_float;
 
-               Matrix4x4_CreateFromQuakeEntity(&entitymatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], val->_float);
+               Matrix4x4_CreateFromQuakeEntity(&entitymatrix, cl.csqc_origin[0], cl.csqc_origin[1], cl.csqc_origin[2], cl.csqc_angles[0], cl.csqc_angles[1], cl.csqc_angles[2], scale);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
 
                /*
@@ -2148,10 +2179,8 @@ static void VM_CL_gettagindex (void)
        }
 
        modelindex = (int)ent->fields.client->modelindex;
-       if(modelindex < 0)
-               modelindex = -(modelindex+1);
        tag_index = 0;
-       if (modelindex <= 0 || modelindex >= MAX_MODELS)
+       if (modelindex >= MAX_MODELS || (modelindex <= -MAX_MODELS /* client models */))
                Con_DPrintf("gettagindex(entity #%i): null or non-precached model\n", PRVM_NUM_FOR_EDICT(ent));
        else
        {
@@ -3193,7 +3222,7 @@ VM_CL_ReadCoord,                          // #364 float() readcoord (EXT_CSQC)
 VM_CL_ReadAngle,                               // #365 float() readangle (EXT_CSQC)
 VM_CL_ReadString,                              // #366 string() readstring (EXT_CSQC)
 VM_CL_ReadFloat,                               // #367 float() readfloat (EXT_CSQC)
-NULL,                                                  // #368
+NULL,                                          // #368
 NULL,                                                  // #369
 NULL,                                                  // #370
 NULL,                                                  // #371
@@ -3340,6 +3369,7 @@ const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
 
 void VM_CL_Cmd_Init(void)
 {
+       VM_Cmd_Init();
        // TODO: replace vm_polygons stuff with a more general debugging polygon system, and make vm_polygons functions use that system
        if(vm_polygons_initialized)
        {
@@ -3350,6 +3380,7 @@ void VM_CL_Cmd_Init(void)
 
 void VM_CL_Cmd_Reset(void)
 {
+       VM_Cmd_Reset();
        if(vm_polygons_initialized)
        {
                Mem_FreePool(&vm_polygons_pool);