// rights reserved.
#include "quakedef.h"
+#include "csprogs.h"
/*
===============================================================================
kbutton_t in_up, in_down;
// LordHavoc: added 6 new buttons
kbutton_t in_button3, in_button4, in_button5, in_button6, in_button7, in_button8;
+//even more
+kbutton_t in_button9, in_button10, in_button11, in_button12, in_button13, in_button14, in_button15, in_button16;
int in_impulse;
void IN_Button8Down(void) {KeyDown(&in_button8);}
void IN_Button8Up(void) {KeyUp(&in_button8);}
+void IN_Button9Down(void) {KeyDown(&in_button9);}
+void IN_Button9Up(void) {KeyUp(&in_button9);}
+void IN_Button10Down(void) {KeyDown(&in_button10);}
+void IN_Button10Up(void) {KeyUp(&in_button10);}
+void IN_Button11Down(void) {KeyDown(&in_button11);}
+void IN_Button11Up(void) {KeyUp(&in_button11);}
+void IN_Button12Down(void) {KeyDown(&in_button12);}
+void IN_Button12Up(void) {KeyUp(&in_button12);}
+void IN_Button13Down(void) {KeyDown(&in_button13);}
+void IN_Button13Up(void) {KeyUp(&in_button13);}
+void IN_Button14Down(void) {KeyDown(&in_button14);}
+void IN_Button14Up(void) {KeyUp(&in_button14);}
+void IN_Button15Down(void) {KeyDown(&in_button15);}
+void IN_Button15Up(void) {KeyUp(&in_button15);}
+void IN_Button16Down(void) {KeyDown(&in_button16);}
+void IN_Button16Up(void) {KeyUp(&in_button16);}
+
void IN_JumpDown (void) {KeyDown(&in_jump);}
void IN_JumpUp (void) {KeyUp(&in_jump);}
old_mouse_y = my;
// if not in menu, apply mouse move to viewangles/movement
- if (in_client_mouse)
+ if (!cl.csqc_wantsmousemove && in_client_mouse)
{
if (cl_prydoncursor.integer)
{
{
// strafing mode, all looking is movement
V_StopPitchDrift();
- cl.cmd.sidemove += m_side.value * in_mouse_x * sensitivity.value * cl.viewzoom;
+ cl.cmd.sidemove += m_side.value * in_mouse_x * sensitivity.value;
if (noclip_anglehack)
- cl.cmd.upmove -= m_forward.value * in_mouse_y * sensitivity.value * cl.viewzoom;
+ cl.cmd.upmove -= m_forward.value * in_mouse_y * sensitivity.value;
else
- cl.cmd.forwardmove -= m_forward.value * in_mouse_y * sensitivity.value * cl.viewzoom;
+ cl.cmd.forwardmove -= m_forward.value * in_mouse_y * sensitivity.value;
}
else if ((in_mlook.state & 1) || freelook.integer)
{
// mouselook, lookstrafe causes turning to become strafing
V_StopPitchDrift();
if (lookstrafe.integer)
- cl.cmd.sidemove += m_side.value * in_mouse_x * sensitivity.value * cl.viewzoom;
+ cl.cmd.sidemove += m_side.value * in_mouse_x * sensitivity.value;
else
cl.viewangles[YAW] -= m_yaw.value * in_mouse_x * sensitivity.value * cl.viewzoom;
cl.viewangles[PITCH] += m_pitch.value * in_mouse_y * sensitivity.value * cl.viewzoom;
{
// non-mouselook, yaw turning and forward/back movement
cl.viewangles[YAW] -= m_yaw.value * in_mouse_x * sensitivity.value * cl.viewzoom;
- cl.cmd.forwardmove -= m_forward.value * in_mouse_y * sensitivity.value * cl.viewzoom;
+ cl.cmd.forwardmove -= m_forward.value * in_mouse_y * sensitivity.value;
}
}
#include "cl_collision.h"
+extern void V_CalcRefdef(void);
void CL_UpdatePrydonCursor(void)
{
vec3_t temp, scale;
cl.cmd.cursor_screen[1] = bound(-1, cl.cmd.cursor_screen[1], 1);
cl.cmd.cursor_screen[2] = 1;
- scale[0] = -tan(r_refdef.fov_x * M_PI / 360.0);
- scale[1] = -tan(r_refdef.fov_y * M_PI / 360.0);
+ scale[0] = -r_refdef.frustum_x;
+ scale[1] = -r_refdef.frustum_y;
scale[2] = 1;
// trace distance
VectorScale(scale, 1000000, scale);
- // FIXME: use something other than renderer variables here
- // (but they need to match)
- VectorCopy(r_vieworigin, cl.cmd.cursor_start);
+ // calculate current view matrix
+ V_CalcRefdef();
+ VectorClear(temp);
+ Matrix4x4_Transform(&r_refdef.viewentitymatrix, temp, cl.cmd.cursor_start);
VectorSet(temp, cl.cmd.cursor_screen[2] * scale[2], cl.cmd.cursor_screen[0] * scale[0], cl.cmd.cursor_screen[1] * scale[1]);
- Matrix4x4_Transform(&r_view_matrix, temp, cl.cmd.cursor_end);
- cl.cmd.cursor_fraction = CL_SelectTraceLine(cl.cmd.cursor_start, cl.cmd.cursor_end, cl.cmd.cursor_impact, cl.cmd.cursor_normal, &cl.cmd.cursor_entitynumber, (chase_active.integer || cl.intermission) ? &cl_entities[cl.playerentity].render : NULL);
+ Matrix4x4_Transform(&r_refdef.viewentitymatrix, temp, cl.cmd.cursor_end);
+ // trace from view origin to the cursor
+ cl.cmd.cursor_fraction = CL_SelectTraceLine(cl.cmd.cursor_start, cl.cmd.cursor_end, cl.cmd.cursor_impact, cl.cmd.cursor_normal, &cl.cmd.cursor_entitynumber, (chase_active.integer || cl.intermission) ? &cl_entities[cl.playerentity].render : NULL, false);
// makes sparks where cursor is
//CL_SparkShower(cl.cmd.cursor_impact, cl.cmd.cursor_normal, 5, 0);
}
-void CL_ClientMovement(qboolean buttonjump, qboolean buttoncrouch)
+void CL_ClientMovement_Input(qboolean buttonjump, qboolean buttoncrouch)
{
int i;
int n;
- int bump;
- int contents;
- int crouch;
- int onground;
- double edgefriction;
- double frametime;
- double t;
- vec_t wishspeed;
- vec_t addspeed;
- vec_t accelspeed;
- vec_t f;
- vec_t *playermins;
- vec_t *playermaxs;
- vec3_t currentorigin;
- vec3_t currentvelocity;
- vec3_t forward;
- vec3_t right;
- vec3_t up;
- vec3_t wishvel;
- vec3_t wishdir;
- vec3_t neworigin;
- vec3_t currentorigin2;
- vec3_t neworigin2;
- vec3_t yawangles;
- trace_t trace;
- trace_t trace2;
- trace_t trace3;
// remove stale queue items
n = cl.movement_numqueue;
cl.movement_numqueue = 0;
cl.movement_queue[cl.movement_numqueue++] = cl.movement_queue[i];
}
// add to input queue if there is room
- if (cl_movement.integer && cl.movement_numqueue < sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0]) && cl.mtime[0] > cl.mtime[1])
+ if (cl_movement.integer && cl.movement_numqueue < (int)(sizeof(cl.movement_queue)/sizeof(cl.movement_queue[0])) && cl.mtime[0] > cl.mtime[1])
{
// add to input queue
cl.movement_queue[cl.movement_numqueue].sequence = cl.movesequence;
cl.movement_queue[cl.movement_numqueue].crouch = buttoncrouch;
cl.movement_numqueue++;
}
+ cl.movement = cl_movement.integer && cl.stats[STAT_HEALTH] > 0 && !cls.demoplayback && !cl.intermission;
+ // clear queue if client movement is disabled
+ if (!cl.movement)
+ cl.movement_numqueue = 0;
+ cl.movement_replay = true;
+}
+
+void CL_ClientMovement_Replay(void)
+{
+ int i;
+ int bump;
+ int contents;
+ int crouch;
+ int onground;
+ double edgefriction;
+ double frametime;
+ double t;
+ vec_t wishspeed;
+ vec_t addspeed;
+ vec_t accelspeed;
+ vec_t f;
+ vec_t *playermins;
+ vec_t *playermaxs;
+ vec3_t currentorigin;
+ vec3_t currentvelocity;
+ vec3_t forward;
+ vec3_t right;
+ vec3_t up;
+ vec3_t wishvel;
+ vec3_t wishdir;
+ vec3_t neworigin;
+ vec3_t currentorigin2;
+ vec3_t neworigin2;
+ vec3_t yawangles;
+ trace_t trace;
+ trace_t trace2;
+ trace_t trace3;
+ if (!cl.movement_replay)
+ return;
+ cl.movement_replay = false;
+
// fetch current starting values
VectorCopy(cl_entities[cl.playerentity].state_current.origin, currentorigin);
VectorCopy(cl.mvelocity[0], currentvelocity);
- // check if onground
- VectorSet(currentorigin2, currentorigin[0], currentorigin[1], currentorigin[2] + 1);
- VectorSet(neworigin2, currentorigin[0], currentorigin[1], currentorigin[2] - 1);
- trace = CL_TraceBox(currentorigin2, cl_playercrouchmins, cl_playercrouchmaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
- onground = trace.fraction < 1 && trace.plane.normal[2] > 0.7;
// FIXME: try minor nudges in various directions if startsolid to find a
// safe place to start the walk (due to network compression in some
// protocols this starts in solid)
//currentorigin[2] += (1.0 / 32.0); // slight nudge to get out of the floor
crouch = false; // this will be updated on first move
+
+ // check if onground
+ VectorSet(currentorigin2, currentorigin[0], currentorigin[1], currentorigin[2] + 1);
+ VectorSet(neworigin2, currentorigin[0], currentorigin[1], currentorigin[2] - 1);
+ trace = CL_TraceBox(currentorigin2, cl_playercrouchmins, cl_playercrouchmaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+ onground = trace.fraction < 1 && trace.plane.normal[2] > 0.7;
//Con_Printf("%f: ", cl.mtime[0]);
- // replay input queue, and remove any stale queue items
+
+ // replay the input queue to predict current location
// note: this relies on the fact there's always one queue item at the end
- // abort if client movement is disabled
- cl.movement = cl_movement.integer && cl.stats[STAT_HEALTH] > 0 && !cls.demoplayback;
- if (!cl.movement)
- cl.movement_numqueue = 0;
+
for (i = 0;i < cl.movement_numqueue;i++)
{
client_movementqueue_t *q = cl.movement_queue + bound(0, i, cl.movement_numqueue - 1);
wishspeed = VectorLength(wishvel);
if (wishspeed)
VectorScale(wishvel, 1 / wishspeed, wishdir);
+ else
+ VectorSet( wishdir, 0.0, 0.0, 0.0 );
wishspeed = min(wishspeed, cl_movement_maxspeed.value);
if (crouch)
wishspeed *= 0.5;
wishspeed = VectorLength(wishvel);
if (wishspeed)
VectorScale(wishvel, 1 / wishspeed, wishdir);
+ else
+ VectorSet( wishdir, 0.0, 0.0, 0.0 );
wishspeed = min(wishspeed, cl_movement_maxspeed.value);
if (crouch)
wishspeed *= 0.5;
int i;
int bits;
sizebuf_t buf;
- qbyte data[128];
+ unsigned char data[128];
#define MOVEAVERAGING 0
#if MOVEAVERAGING
static float forwardmove, sidemove, upmove, total; // accumulation
upmove = cl.cmd.upmove;
#endif
+ CL_UpdatePrydonCursor();
+
buf.maxsize = 128;
buf.cursize = 0;
buf.data = data;
if (in_use.state & 3) bits |= 256;in_use.state &= ~2;
if (key_dest != key_game || key_consoleactive) bits |= 512;
if (cl_prydoncursor.integer) bits |= 1024;
- // button bits 11-31 unused currently
+ if (in_button9.state & 3) bits |= 2048;in_button9.state &= ~2;
+ if (in_button10.state & 3) bits |= 4096;in_button10.state &= ~2;
+ if (in_button11.state & 3) bits |= 8192;in_button11.state &= ~2;
+ if (in_button12.state & 3) bits |= 16384;in_button12.state &= ~2;
+ if (in_button13.state & 3) bits |= 32768;in_button13.state &= ~2;
+ if (in_button14.state & 3) bits |= 65536;in_button14.state &= ~2;
+ if (in_button15.state & 3) bits |= 131072;in_button15.state &= ~2;
+ if (in_button16.state & 3) bits |= 262144;in_button16.state &= ~2;
+ // button bits 19-31 unused currently
// rotate/zoom view serverside if PRYDON_CLIENTCURSOR cursor is at edge of screen
if (cl.cmd.cursor_screen[0] <= -1) bits |= 8;
if (cl.cmd.cursor_screen[0] >= 1) bits |= 16;
if (cl.cmd.cursor_screen[1] <= -1) bits |= 32;
if (cl.cmd.cursor_screen[1] >= 1) bits |= 64;
+ csqc_buttons = bits;
+
// always dump the first two messages, because they may contain leftover inputs from the last level
if (++cl.movemessages >= 2)
{
if (!buf.cursize)
return;
- // FIXME: bits & 64 is +button5, Nexuiz specific
- CL_ClientMovement((bits & 2) != 0, (bits & 64) != 0);
+ // FIXME: bits & 16 is +button5, Nexuiz specific
+ CL_ClientMovement_Input((bits & 2) != 0, (bits & 16) != 0);
if (NetConn_SendUnreliableMessage(cls.netcon, &buf) == -1)
{
Cmd_AddCommand ("-button7", IN_Button7Up);
Cmd_AddCommand ("+button8", IN_Button8Down);
Cmd_AddCommand ("-button8", IN_Button8Up);
+ Cmd_AddCommand ("+button9", IN_Button9Down);
+ Cmd_AddCommand ("-button9", IN_Button9Up);
+ Cmd_AddCommand ("+button10", IN_Button10Down);
+ Cmd_AddCommand ("-button10", IN_Button10Up);
+ Cmd_AddCommand ("+button11", IN_Button11Down);
+ Cmd_AddCommand ("-button11", IN_Button11Up);
+ Cmd_AddCommand ("+button12", IN_Button12Down);
+ Cmd_AddCommand ("-button12", IN_Button12Up);
+ Cmd_AddCommand ("+button13", IN_Button13Down);
+ Cmd_AddCommand ("-button13", IN_Button13Up);
+ Cmd_AddCommand ("+button14", IN_Button14Down);
+ Cmd_AddCommand ("-button14", IN_Button14Up);
+ Cmd_AddCommand ("+button15", IN_Button15Down);
+ Cmd_AddCommand ("-button15", IN_Button15Up);
+ Cmd_AddCommand ("+button16", IN_Button16Down);
+ Cmd_AddCommand ("-button16", IN_Button16Up);
Cvar_RegisterVariable(&cl_movement);
Cvar_RegisterVariable(&cl_movement_latency);