CL_RotateMoves: helper builtin for Xonotic for perfect warpzone prediction
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 29 Apr 2011 20:32:35 +0000 (20:32 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 29 Apr 2011 20:32:35 +0000 (20:32 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11084 d7cf8633-e32d-0410-b094-e92efae38249

cl_input.c
client.h
clvm_cmds.c
svvm_cmds.c

index 1a0704d..577df50 100644 (file)
@@ -1697,6 +1697,25 @@ void CL_NewFrameReceived(int num)
        cl.latestframenumsposition = (cl.latestframenumsposition + 1) % LATESTFRAMENUMS;
 }
 
+void CL_RotateMoves(const matrix4x4_t *m)
+{
+       // rotate viewangles in all previous moves
+       vec3_t v;
+       vec3_t f, r, u;
+       int i;
+       for (i = 0;i < CL_MAX_USERCMDS;i++)
+       {
+               if (cl.movecmd[i].sequence > cls.servermovesequence)
+               {
+                       usercmd_t *c = &cl.movecmd[i];
+                       AngleVectors(c->viewangles, f, r, u);
+                       Matrix4x4_Transform(m, f, v); VectorCopy(v, f);
+                       Matrix4x4_Transform(m, u, v); VectorCopy(v, u);
+                       AnglesFromVectors(c->viewangles, f, u, false);
+               }
+       }
+}
+
 /*
 ==============
 CL_SendMove
index af41343..11f9aa1 100644 (file)
--- a/client.h
+++ b/client.h
@@ -1836,5 +1836,8 @@ r_refdef_t;
 
 extern r_refdef_t r_refdef;
 
+// warpzone prediction hack (CSQC builtin)
+void CL_RotateMoves(const matrix4x4_t *m);
+
 #endif
 
index 2beea3c..ffcff83 100644 (file)
@@ -3990,6 +3990,44 @@ static void VM_CL_frameduration(void)
                PRVM_G_FLOAT(OFS_RETURN) = model->animscenes[framenum].framecount / model->animscenes[framenum].framerate;
 }
 
+void VM_CL_RotateMoves(void)
+{
+       /*
+        * Obscure builtin used by GAME_XONOTIC.
+        *
+        * Edits the input history of cl_movement by rotating all move commands
+        * currently in the queue using the given transform.
+        *
+        * The vector passed is an "angles transform" as used by warpzonelib, i.e.
+        * v_angle-like (non-inverted) euler angles that perform the rotation
+        * of the space that is to be done.
+        *
+        * This is meant to be used as a fixangle replacement after passing
+        * through a warpzone/portal: the client is told about the warp transform,
+        * and calls this function in the same frame as the one on which the
+        * client's origin got changed by the serverside teleport. Then this code
+        * transforms the pre-warp input (which matches the empty space behind
+        * the warp plane) into post-warp input (which matches the target area
+        * of the warp). Also, at the same time, the client has to use
+        * R_SetView to adjust VF_CL_VIEWANGLES according to the same transform.
+        *
+        * This together allows warpzone motion to be perfectly predicted by
+        * the client!
+        *
+        * Furthermore, for perfect warpzone behaviour, the server side also
+        * has to detect input the client sent before it received the origin
+        * update, but after the warp occurred on the server, and has to adjust
+        * input appropriately.
+        */
+       matrix4x4_t m;
+       vec3_t v = {0, 0, 0};
+       vec3_t x, y, z;
+       VM_SAFEPARMCOUNT(1, VM_CL_RotateMoves);
+       AngleVectorsFLU(PRVM_G_VECTOR(OFS_PARM0), x, y, z);
+       Matrix4x4_FromVectors(&m, x, y, z, v);
+       CL_RotateMoves(&m);
+}
+
 //============================================================================
 
 // To create a almost working builtin file from this replace:
@@ -4638,6 +4676,12 @@ VM_setkeybind,                                           // #630 float(float key, string bind[, float bindmap]) setke
 VM_getbindmaps,                                                // #631 vector(void) getbindmap
 VM_setbindmaps,                                                // #632 float(vector bm) setbindmap
 NULL,                                                  // #633
+NULL,                                                  // #634
+NULL,                                                  // #635
+NULL,                                                  // #636
+NULL,                                                  // #637
+VM_CL_RotateMoves,                                     // #638
+NULL,                                                  // #639
 };
 
 const int vm_cl_numbuiltins = sizeof(vm_cl_builtins) / sizeof(prvm_builtin_t);
index fc35514..0efb61b 100644 (file)
@@ -27,6 +27,7 @@ const char *vm_sv_extensions =
 "DP_CSQC_BOXPARTICLES "
 "DP_CSQC_SPAWNPARTICLE "
 "DP_CSQC_QUERYRENDERENTITY "
+"DP_CSQC_ROTATEMOVES "
 "DP_CSQC_SETPAUSE "
 "DP_EF_ADDITIVE "
 "DP_EF_BLUE "