⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cl_input.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
  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 + -