📄 cl_input.pas
字号:
msec: integer;
begin
key^.state := key^.state and 1; // clear impulses
msec := key^.msec;
key^.msec := 0;
if (key^.state <> 0) then
begin // still down
msec := msec + sys_frame_time - key^.downtime;
key^.downtime := sys_frame_time;
end;
{$ifdef 0}
if (msec) then
begin
Com_Printf ('%d ', [msec]);
end;
{$endif}
val := msec / frame_msec;
if (val < 0) then
val := 0;
if (val > 1) then
val := 1;
result := val;
end;
//==========================================================================
{*
================
CL_AdjustAngles
Moves the local angle positions
================
*}
procedure CL_AdjustAngles;
var
speed, up, down: single;
begin
if (in_speed.state and 1 <> 0) then
speed := cls.frametime * cl_anglespeedkey^.value
else
speed := cls.frametime;
if ((in_strafe.state and 1) = 0) then
begin
cl.viewangles[YAW] := cl.viewangles[YAW] - speed*cl_yawspeed^.value*CL_KeyState (@in_right);
cl.viewangles[YAW] := cl.viewangles[YAW] + speed*cl_yawspeed^.value*CL_KeyState (@in_left);
end;
if (in_klook.state and 1 <> 0) then
begin
cl.viewangles[PITCH] := cl.viewangles[PITCH] - speed*cl_pitchspeed^.value * CL_KeyState (@in_forward);
cl.viewangles[PITCH] := cl.viewangles[PITCH] + speed*cl_pitchspeed^.value * CL_KeyState (@in_back);
end;
up := CL_KeyState (@in_lookup);
down := CL_KeyState(@in_lookdown);
cl.viewangles[PITCH] := cl.viewangles[PITCH] - speed*cl_pitchspeed^.value * up;
cl.viewangles[PITCH] := cl.viewangles[PITCH] + speed*cl_pitchspeed^.value * down;
end;
{*
================
CL_BaseMove
Send the intended movement message to the server
================
*}
procedure CL_BaseMove (cmd: usercmd_p);
begin
CL_AdjustAngles;
FillChar (cmd^, sizeof(cmd^), #0);
VectorCopy (cl.viewangles, cmd^.angles);
if (in_strafe.state and 1 <> 0) then
begin
cmd^.sidemove := Round(cmd^.sidemove + cl_sidespeed^.value * CL_KeyState (@in_right));
cmd^.sidemove := Round(cmd^.sidemove - cl_sidespeed^.value * CL_KeyState (@in_left));
end;
cmd^.sidemove := Round(cmd^.sidemove + cl_sidespeed^.value * CL_KeyState (@in_moveright));
cmd^.sidemove := Round(cmd^.sidemove - cl_sidespeed^.value * CL_KeyState (@in_moveleft));
cmd^.upmove := Round(cmd^.upmove + cl_upspeed^.value * CL_KeyState (@in_up));
cmd^.upmove := Round(cmd^.upmove - cl_upspeed^.value * CL_KeyState (@in_down));
if ((in_klook.state and 1)=0) then
begin
cmd^.forwardmove := Round(cmd^.forwardmove + cl_forwardspeed^.value * CL_KeyState (@in_forward));
cmd^.forwardmove := Round(cmd^.forwardmove - cl_forwardspeed^.value * CL_KeyState (@in_back));
end;
//
// adjust for speed key / running
//
if ((in_speed.state and 1) xor Round(cl_run^.value ))<>0 then
begin
cmd^.forwardmove := cmd^.forwardmove* 2;
cmd^.sidemove := cmd^.sidemove * 2;
cmd^.upmove := cmd^.upmove * 2;
end;
end;
procedure CL_ClampPitch;
var
pitch_: single;
begin
pitch_ := SHORT2ANGLE(Word(cl.frame.playerstate.pmove.delta_angles[PITCH]));
if (pitch_ > 180) then pitch_ := pitch_ - 360;
if (cl.viewangles[PITCH] + pitch_ < -360) then
cl.viewangles[PITCH] := cl.viewangles[PITCH] + 360; // wrapped
if (cl.viewangles[PITCH] + pitch_ > 360) then
cl.viewangles[PITCH] := cl.viewangles[PITCH] + 360; // wrapped
if (cl.viewangles[PITCH] + pitch_ > 89) then cl.viewangles[PITCH] := 89 - pitch_;
if (cl.viewangles[PITCH] + pitch_ < -89) then cl.viewangles[PITCH] := -89 - pitch_;
end;
{*
==============
CL_FinishMove
==============
*}
procedure CL_FinishMove (cmd: usercmd_p);
var
ms, i: integer;
begin
//
// figure button bits
//
if ( in_attack.state and 3 <> 0) then
cmd^.buttons := cmd^.buttons or BUTTON_ATTACK;
in_attack.state := in_attack.state and (not 2);
if (in_use.state and 3 <> 0) then
cmd^.buttons := cmd^.buttons or BUTTON_USE;
in_use.state := in_use.state and (not 2);
if (anykeydown <> 0) and (cls.key_dest = key_game) then
cmd^.buttons := cmd^.buttons or BUTTON_ANY;
// send milliseconds of time to apply the move
ms := Round(cls.frametime * 1000);
if (ms > 250) then ms := 100; // time was unreasonable
cmd^.msec := ms;
CL_ClampPitch;
for i:= 0 to 2 do
cmd^.angles[i] := SmallInt(ANGLE2SHORT(cl.viewangles[i]));
cmd^.impulse := in_impulse_;
in_impulse_ := 0;
// send the ambient light level at the player's current position
cmd^.lightlevel := Round(cl_lightlevel^.value);
end;
{*
=================
CL_CreateCmd
=================
*}
function CL_CreateCmd: usercmd_t;
var
cmd: usercmd_t;
begin
frame_msec := sys_frame_time - old_sys_frame_time;
if (frame_msec < 1) then frame_msec := 1;
if (frame_msec > 200) then frame_msec := 200;
// get basic movement from keyboard
CL_BaseMove (@cmd);
// allow mice or other external controllers to add to the move
IN_Move (@cmd);
CL_FinishMove (@cmd);
old_sys_frame_time := sys_frame_time;
//cmd.impulse := cls.framecount;
result := cmd;
end;
procedure IN_CenterView;
begin
cl.viewangles[PITCH] := -SHORT2ANGLE(cl.frame.playerstate.pmove.delta_angles[PITCH]);
end;
{*
============
CL_InitInput
============
*}
procedure CL_InitInput;
begin
Cmd_AddCommand ('centerview',IN_CenterView);
Cmd_AddCommand ('+moveup',IN_UpDown);
Cmd_AddCommand ('-moveup',IN_UpUp);
Cmd_AddCommand ('+movedown',IN_DownDown);
Cmd_AddCommand ('-movedown',IN_DownUp);
Cmd_AddCommand ('+left',IN_LeftDown);
Cmd_AddCommand ('-left',IN_LeftUp);
Cmd_AddCommand ('+right',IN_RightDown);
Cmd_AddCommand ('-right',IN_RightUp);
Cmd_AddCommand ('+forward',IN_ForwardDown);
Cmd_AddCommand ('-forward',IN_ForwardUp);
Cmd_AddCommand ('+back',IN_BackDown);
Cmd_AddCommand ('-back',IN_BackUp);
Cmd_AddCommand ('+lookup', IN_LookupDown);
Cmd_AddCommand ('-lookup', IN_LookupUp);
Cmd_AddCommand ('+lookdown', IN_LookdownDown);
Cmd_AddCommand ('-lookdown', IN_LookdownUp);
Cmd_AddCommand ('+strafe', IN_StrafeDown);
Cmd_AddCommand ('-strafe', IN_StrafeUp);
Cmd_AddCommand ('+moveleft', IN_MoveleftDown);
Cmd_AddCommand ('-moveleft', IN_MoveleftUp);
Cmd_AddCommand ('+moveright', IN_MoverightDown);
Cmd_AddCommand ('-moveright', IN_MoverightUp);
Cmd_AddCommand ('+speed', IN_SpeedDown);
Cmd_AddCommand ('-speed', IN_SpeedUp);
Cmd_AddCommand ('+attack', IN_AttackDown);
Cmd_AddCommand ('-attack', IN_AttackUp);
Cmd_AddCommand ('+use', IN_UseDown);
Cmd_AddCommand ('-use', IN_UseUp);
Cmd_AddCommand ('impulse', IN_Impulse);
Cmd_AddCommand ('+klook', IN_KLookDown);
Cmd_AddCommand ('-klook', IN_KLookUp);
cl_nodelta := Cvar_Get ('cl_nodelta', '0', 0);
end;
{*
=================
CL_SendCmd
=================
*}
procedure CL_SendCmd;
var
buf: sizebuf_t;
data: array[0..128-1] of byte;
i, checksumIndex: integer;
cmd, oldcmd: usercmd_p;
nullcmd: usercmd_t;
begin
// build a command even if not connected
// save this command off for prediction
i := cls.netchan.outgoing_sequence and (CMD_BACKUP-1);
cmd := @cl.cmds[i];
cl.cmd_time[i] := cls.realtime; // for netgraph ping calculation
cmd^ := CL_CreateCmd;
cl.cmd := cmd^;
if (cls.state = ca_disconnected) or
(cls.state = ca_connecting) then exit;
if (cls.state = ca_connected) then
begin
if (cls.netchan.message.cursize<>0) or
(curtime - cls.netchan.last_sent > 1000 ) then
Netchan_Transmit (cls.netchan, 0, PByte(buf.data));
exit;
end;
// send a userinfo update if needed
if (userinfo_modified) then
begin
CL_FixUpGender;
userinfo_modified := false;
MSG_WriteByte (cls.netchan.message, Integer(clc_userinfo));
MSG_WriteString (cls.netchan.message, Cvar_Userinfo_());
end;
SZ_Init (buf, @data, sizeof(data));
if (cmd^.buttons and cl.cinematictime > 0) and
(not cl.attractloop) and
(cls.realtime - cl.cinematictime > 1000) then
begin // skip the rest of the cinematic
SCR_FinishCinematic;
end;
// begin a client move command
MSG_WriteByte (buf, Integer(clc_move));
// save the position for a checksum byte
checksumIndex := buf.cursize;
MSG_WriteByte (buf, 0);
// let the server know what the last frame we
// got was, so the next message can be delta compressed
if (cl_nodelta^.value <> 0) or (not cl.frame.valid) or (cls.demowaiting) then
MSG_WriteLong (buf, -1) // no compression
else
MSG_WriteLong (buf, cl.frame.serverframe);
// send this and the previous cmds in the message, so
// if the last packet was dropped, it can be recovered
i := (cls.netchan.outgoing_sequence-2) and (CMD_BACKUP-1);
cmd := @cl.cmds[i];
FillChar (nullcmd, sizeof(nullcmd), #0);
MSG_WriteDeltaUsercmd (buf, nullcmd, cmd^);
oldcmd := cmd;
i := (cls.netchan.outgoing_sequence-1) and (CMD_BACKUP-1);
cmd := @cl.cmds[i];
MSG_WriteDeltaUsercmd (buf, oldcmd^, cmd^);
oldcmd := cmd;
i := (cls.netchan.outgoing_sequence) and (CMD_BACKUP-1);
cmd := @cl.cmds[i];
MSG_WriteDeltaUsercmd (buf, oldcmd^, cmd^);
// calculate a checksum over the move commands
buf.data[checksumIndex] :=
COM_BlockSequenceCRCByte(Pointer(Cardinal(buf.data) + checksumIndex + 1),
buf.cursize - checksumIndex - 1,
cls.netchan.outgoing_sequence);
//
// deliver the message
//
Netchan_Transmit (cls.netchan, buf.cursize, PByte(buf.data));
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -