]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - clvm_cmds.c
make CSQC support the >0.05s/<0.0005s handling of standard player physics so CSQC...
[xonotic/darkplaces.git] / clvm_cmds.c
index 62b84db36843aee60a0fcab2e8c69059bb8caa75..a0cb94688e374d0e9e169a14687128d1d8d82220 100644 (file)
@@ -24,6 +24,7 @@ extern cvar_t v_flipped;
 extern cvar_t r_equalize_entities_fullbright;
 
 r_refdef_view_t csqc_original_r_refdef_view;
+r_refdef_view_t csqc_main_r_refdef_view;
 
 // #1 void(vector ang) makevectors
 static void VM_CL_makevectors (prvm_prog_t *prog)
@@ -52,6 +53,8 @@ static void VM_CL_setorigin (prvm_prog_t *prog)
        }
        org = PRVM_G_VECTOR(OFS_PARM1);
        VectorCopy (org, PRVM_clientedictvector(e, origin));
+       if(e->priv.required->mark == PRVM_EDICT_MARK_WAIT_FOR_SETORIGIN)
+               e->priv.required->mark = PRVM_EDICT_MARK_SETORIGIN_CAUGHT;
        CL_LinkEdict(e);
 }
 
@@ -873,6 +876,9 @@ static void VM_CL_R_SetView (prvm_prog_t *prog)
                case VF_CLEARSCREEN:
                        PRVM_G_FLOAT(OFS_RETURN) = r_refdef.view.isoverlay;
                        break;
+               case VF_MAINVIEW:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.view.ismain;
+                       break;
                case VF_FOG_DENSITY:
                        PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_density;
                        break;
@@ -905,6 +911,9 @@ static void VM_CL_R_SetView (prvm_prog_t *prog)
                case VF_FOG_FADEDEPTH:
                        PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_fadedepth;
                        break;
+               case VF_MINFPS_QUALITY:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.view.quality;
+                       break;
                default:
                        PRVM_G_FLOAT(OFS_RETURN) = 0;
                        VM_Warning(prog, "VM_CL_R_GetView : unknown parm %i\n", c);
@@ -1020,6 +1029,9 @@ static void VM_CL_R_SetView (prvm_prog_t *prog)
        case VF_CLEARSCREEN:
                r_refdef.view.isoverlay = !k;
                break;
+       case VF_MAINVIEW:
+               PRVM_G_FLOAT(OFS_RETURN) = r_refdef.view.ismain;
+               break;
        case VF_FOG_DENSITY:
                r_refdef.fog_density = k;
                break;
@@ -1052,6 +1064,9 @@ static void VM_CL_R_SetView (prvm_prog_t *prog)
        case VF_FOG_FADEDEPTH:
                r_refdef.fog_fadedepth = k;
                break;
+       case VF_MINFPS_QUALITY:
+               r_refdef.view.quality = k;
+               break;
        default:
                PRVM_G_FLOAT(OFS_RETURN) = 0;
                VM_Warning(prog, "VM_CL_R_SetView : unknown parm %i\n", c);
@@ -1407,6 +1422,7 @@ static void VM_CL_getinputstate (prvm_prog_t *prog)
                        PRVM_clientglobalvector(input_movevalues)[1] = cl.movecmd[i].sidemove;
                        PRVM_clientglobalvector(input_movevalues)[2] = cl.movecmd[i].upmove;
                        PRVM_clientglobalfloat(input_timelength) = cl.movecmd[i].frametime;
+                       // this probably shouldn't be here
                        if(cl.movecmd[i].crouch)
                        {
                                VectorCopy(cl.playercrouchmins, PRVM_clientglobalvector(pmove_mins));
@@ -1430,8 +1446,70 @@ static void VM_CL_setsensitivityscale (prvm_prog_t *prog)
 }
 
 //#347 void() runstandardplayerphysics (EXT_CSQC)
+#define PMF_JUMP_HELD 1 // matches FTEQW
+#define PMF_LADDER 2 // not used by DP, FTEQW sets this in runplayerphysics but does not read it
+#define PMF_DUCKED 4 // FIXME FTEQW doesn't have this for Q1 like movement because Q1 cannot crouch
+#define PMF_ONGROUND 8 // FIXME FTEQW doesn't have this for Q1 like movement and expects CSQC code to do its own trace, this is stupid CPU waste
 static void VM_CL_runplayerphysics (prvm_prog_t *prog)
 {
+       cl_clientmovement_state_t s;
+       prvm_edict_t *ent;
+
+       VM_SAFEPARMCOUNTRANGE(0, 1, VM_CL_runplayerphysics);
+
+       ent = (prog->argc == 1 ? PRVM_G_EDICT(OFS_PARM0) : prog->edicts);
+       if(ent == prog->edicts)
+       {
+               // deprecated use
+               VectorCopy(PRVM_clientglobalvector(pmove_org), s.origin);
+               VectorCopy(PRVM_clientglobalvector(pmove_vel), s.velocity);
+               VectorCopy(PRVM_clientglobalvector(pmove_mins), s.mins);
+               VectorCopy(PRVM_clientglobalvector(pmove_maxs), s.maxs);
+               s.crouched = 0;
+               s.waterjumptime = PRVM_clientglobalfloat(pmove_waterjumptime);
+               s.cmd.canjump = (int)PRVM_clientglobalfloat(pmove_jump_held) == 0;
+       }
+       else
+       {
+               // new use
+               VectorCopy(PRVM_clientedictvector(ent, origin), s.origin);
+               VectorCopy(PRVM_clientedictvector(ent, velocity), s.velocity);
+               VectorCopy(PRVM_clientedictvector(ent, mins), s.mins);
+               VectorCopy(PRVM_clientedictvector(ent, maxs), s.maxs);
+               s.crouched = ((int)PRVM_clientedictfloat(ent, pmove_flags) & PMF_DUCKED) != 0;
+               s.waterjumptime = 0; // FIXME where do we get this from? FTEQW lacks support for this too
+               s.cmd.canjump = ((int)PRVM_clientedictfloat(ent, pmove_flags) & PMF_JUMP_HELD) == 0;
+       }
+
+       VectorCopy(PRVM_clientglobalvector(input_angles), s.cmd.viewangles);
+       s.cmd.forwardmove = PRVM_clientglobalvector(input_movevalues)[0];
+       s.cmd.sidemove = PRVM_clientglobalvector(input_movevalues)[1];
+       s.cmd.upmove = PRVM_clientglobalvector(input_movevalues)[2];
+       s.cmd.buttons = PRVM_clientglobalfloat(input_buttons);
+       s.cmd.frametime = PRVM_clientglobalfloat(input_timelength);
+       s.cmd.jump = (s.cmd.buttons & 2) != 0;
+       s.cmd.crouch = (s.cmd.buttons & 16) != 0;
+
+       CL_ClientMovement_PlayerMove_Frame(&s);
+
+       if(ent == prog->edicts)
+       {
+               // deprecated use
+               VectorCopy(s.origin, PRVM_clientglobalvector(pmove_org));
+               VectorCopy(s.velocity, PRVM_clientglobalvector(pmove_vel));
+               PRVM_clientglobalfloat(pmove_jump_held) = !s.cmd.canjump;
+               PRVM_clientglobalfloat(pmove_waterjumptime) = s.waterjumptime;
+       }
+       else
+       {
+               // new use
+               VectorCopy(s.origin, PRVM_clientedictvector(ent, origin));
+               VectorCopy(s.velocity, PRVM_clientedictvector(ent, velocity));
+               PRVM_clientedictfloat(ent, pmove_flags) =
+                       (s.crouched ? PMF_DUCKED : 0) |
+                       (s.cmd.canjump ? 0 : PMF_JUMP_HELD) |
+                       (s.onground ? PMF_ONGROUND : 0);
+       }
 }
 
 //#348 string(float playernum, string keyname) getplayerkeyvalue (EXT_CSQC)
@@ -2422,7 +2500,8 @@ static void VM_CL_gettagindex (prvm_prog_t *prog)
        {
                tag_index = CL_GetTagIndex(prog, ent, tag_name);
                if (tag_index == 0)
-                       Con_DPrintf("VM_CL_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
+                       if(developer_extra.integer)
+                               Con_DPrintf("VM_CL_gettagindex(entity #%i): tag \"%s\" not found\n", PRVM_NUM_FOR_EDICT(ent), tag_name);
        }
        PRVM_G_FLOAT(OFS_RETURN) = tag_index;
 }
@@ -3039,6 +3118,17 @@ static void VM_CL_R_RenderScene (prvm_prog_t *prog)
        vmpolygons_t *polys = &prog->vmpolygons;
        VM_SAFEPARMCOUNT(0, VM_CL_R_RenderScene);
 
+       // update the views
+       if(r_refdef.view.ismain)
+       {
+               // set the main view
+               csqc_main_r_refdef_view = r_refdef.view;
+
+               // clear the flags so no other view becomes "main" unless CSQC sets VF_MAINVIEW
+               r_refdef.view.ismain = false;
+               csqc_original_r_refdef_view.ismain = false;
+       }
+
        // we need to update any RENDER_VIEWMODEL entities at this point because
        // csqc supplies its own view matrix
        CL_UpdateViewEntities();
@@ -3206,7 +3296,7 @@ void VM_CL_AddPolygonsToMeshQueue (prvm_prog_t *prog)
        for (i = 0;i < polys->num_triangles;i++)
        {
                VectorMAMAM(1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[0], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[1], 1.0f / 3.0f, polys->data_vertex3f + 3*polys->data_triangles[i].elements[2], center);
-               R_MeshQueue_AddTransparent(center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL);
+               R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, VM_DrawPolygonCallback, (entity_render_t *)polys, i, NULL);
        }
 
        /*polys->num_triangles = 0; // now done after rendering the scene,
@@ -4058,6 +4148,39 @@ static void VM_CL_loadcubemap(prvm_prog_t *prog)
        R_GetCubemap(name);
 }
 
+#define REFDEFFLAG_TELEPORTED 1
+#define REFDEFFLAG_JUMPING 2
+static void VM_CL_V_CalcRefdef(prvm_prog_t *prog)
+{
+       matrix4x4_t entrendermatrix;
+       vec3_t clviewangles;
+       qboolean teleported;
+       qboolean clonground;
+       qboolean clcmdjump;
+       float clstatsviewheight;
+       prvm_edict_t *ent;
+       int flags;
+
+       VM_SAFEPARMCOUNT(2, VM_CL_V_CalcRefdef);
+       ent = PRVM_G_EDICT(OFS_PARM0);
+       flags = PRVM_G_FLOAT(OFS_PARM1);
+
+       // use the CL_GetTagMatrix function on self to ensure consistent behavior (duplicate code would be bad)
+       CL_GetTagMatrix(prog, &entrendermatrix, ent, 0);
+
+       VectorCopy(cl.csqc_viewangles, clviewangles);
+       teleported = (flags & REFDEFFLAG_TELEPORTED) != 0;
+       clonground = ((int)PRVM_clientedictfloat(ent, pmove_flags) & PMF_ONGROUND) != 0;
+       clcmdjump = (flags & REFDEFFLAG_JUMPING) != 0;
+       clstatsviewheight = PRVM_clientedictvector(ent, view_ofs)[2];
+
+       V_CalcRefdefUsing(&entrendermatrix, clviewangles, teleported, clonground, clcmdjump, clstatsviewheight);
+
+       VectorCopy(cl.csqc_vieworiginfromengine, cl.csqc_vieworigin);
+       VectorCopy(cl.csqc_viewanglesfromengine, cl.csqc_viewangles);
+       CSQC_R_RecalcView();
+}
+
 //============================================================================
 
 // To create a almost working builtin file from this replace:
@@ -4712,7 +4835,8 @@ NULL,                                                     // #636
 NULL,                                                  // #637
 VM_CL_RotateMoves,                                     // #638
 VM_digest_hex,                                         // #639
-NULL,                                                  // #640
+VM_CL_V_CalcRefdef,                                    // #640 void(entity e) V_CalcRefdef (DP_CSQC_V_CALCREFDEF)
+NULL,                                                  // #641
 };
 
 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);