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

📄 cl_input.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
Returns the fraction of the frame that the key was down
===============
*}

function CL_KeyState(key: kbutton_p): single;
var
  val: single;
  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;

  {
    if (msec) then
    begin
      Com_Printf ('%d ', [msec]);
    end;
  }

  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 <> 0) 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 + -