From: divverent Date: Fri, 29 Apr 2011 20:32:35 +0000 (+0000) Subject: CL_RotateMoves: helper builtin for Xonotic for perfect warpzone prediction X-Git-Tag: xonotic-v0.6.0~163^2~462 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=7c9b33c2b122a788bb81c3e1dd0bb172f9cdc706;p=xonotic%2Fdarkplaces.git CL_RotateMoves: helper builtin for Xonotic for perfect warpzone prediction git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11084 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_input.c b/cl_input.c index 1a0704d7..577df505 100644 --- a/cl_input.c +++ b/cl_input.c @@ -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 diff --git a/client.h b/client.h index af413434..11f9aa17 100644 --- 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 diff --git a/clvm_cmds.c b/clvm_cmds.c index 2beea3ce..ffcff83f 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -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); diff --git a/svvm_cmds.c b/svvm_cmds.c index fc35514d..0efb61bf 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -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 "