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

📄 in_win.pas

📁 delphi编的不错的贪吃蛇
💻 PAS
📖 第 1 页 / 共 2 页
字号:
begin
  if not mouseinitialized then
    exit;

  if (in_mouse = nil) or (not in_appactive) then
  begin
    IN_DeactivateMouse;
    exit;
  end;

  if (not cl.refresh_prepped)
    or (cls.key_dest = key_console)
    or (cls.key_dest = key_menu) then
  begin
    // temporarily deactivate if in fullscreen
    if (Cvar_VariableValue('vid_fullscreen') = 0) then
    begin
      IN_DeactivateMouse;
      exit;
    end;
  end;

  IN_ActivateMouse;
end;

(*
===========
IN_Move
===========
*)

procedure IN_Move(cmd: usercmd_p);
begin
  IN_MouseMove(cmd);

  if (ActiveApp <> 0) then
    IN_JoyMove(cmd);
end;

(*
===================
IN_ClearStates
===================
*)

procedure IN_ClearStates;
begin
  mx_accum := 0;
  my_accum := 0;
  mouse_oldbuttonstate := 0;
end;

(*
=========================================================================

JOYSTICK

=========================================================================
*)

(*
===============
IN_StartupJoystick
===============
*)

procedure IN_StartupJoystick;
var
  numdevs: Integer;
  jc: JOYCAPS;
  mmr: MMRESULT;
  cv: cvar_p;
begin

  // assume no joystick
  joy_avail := false;

  // abort startup if user requests no joystick
  cv := Cvar_Get('in_initjoy', '1', CVAR_NOSET);
  if cv^.value = 0 then
    exit;

  // verify joystick driver is present
  numdevs := joyGetNumDevs();
  if (numdevs = 0) then
  begin
    //		Com_Printf (#10'joystick not found -- driver not present'#10#10, []);
    Exit;
  end;

  // cycle through the joystick ids for the first valid one
  joy_id := 0;
  while joy_id < numdevs do
  begin
    FillChar(ji, sizeof(ji), 0);
    ji.dwSize := sizeof(ji);
    ji.dwFlags := JOY_RETURNCENTERED;
    mmr := joyGetPosEx(joy_id, @ji);
    if (mmr = JOYERR_NOERROR) then
      break;
    Inc(joy_id);
  end;

  // abort startup if we didn't find a valid joystick
  if mmr <> JOYERR_NOERROR then
  begin
    Com_Printf(#10'joystick not found -- no valid joysticks (%x)'#10#10, [mmr]);
    exit;
  end;

  // get the capabilities of the selected joystick
  // abort startup if command fails
  FillChar(jc, sizeof(jc), 0);
  mmr := joyGetDevCaps(joy_id, @jc, sizeof(jc));
  if (mmr <> JOYERR_NOERROR) then
  begin
    Com_Printf(#10'joystick not found -- invalid joystick capabilities (%x)'#10#10, [mmr]);
    exit;
  end;

  // save the joystick's number of buttons and POV status
  joy_numbuttons := jc.wNumButtons;
  joy_haspov := (jc.wCaps and JOYCAPS_HASPOV) <> 0;

  // old button and POV states default to no buttons pressed
  joy_oldbuttonstate := 0;
  joy_oldpovstate := 0;

  // mark the joystick as available and advanced initialization not completed
  // this is needed as cvars are not available during initialization

  joy_avail := true;
  joy_advancedinit := false;

  Com_Printf(#10'joystick detected'#10#10, []);
end;

(*
===========
RawValuePointer
===========
*)

function RawValuePointer(axis: Integer): PDWORD;
begin
  case axis of
    JOY_AXIS_X: Result := @ji.wXpos;
    JOY_AXIS_Y: Result := @ji.wYpos;
    JOY_AXIS_Z: Result := @ji.wZpos;
    JOY_AXIS_R: Result := @ji.dwRpos;
    JOY_AXIS_U: Result := @ji.dwUpos;
    JOY_AXIS_V: Result := @ji.dwVpos;
  end;
end;

(*
===========
Joy_AdvancedUpdate_f
===========
*)

procedure Joy_AdvancedUpdate_f; cdecl;
var
  // called once by IN_ReadJoystick and by user whenever an update is needed
  // cvars are now available
  i: Integer;
  dwTemp: DWORD;
begin
  // initialize all the maps
  for i := 0 to JOY_MAX_AXES - 1 do
  begin
    dwAxisMap[i] := Cardinal(AxisNada);
    dwControlMap[i] := JOY_ABSOLUTE_AXIS;
    pdwRawValue[i] := RawValuePointer(i);
  end;

  if joy_advanced^.value = 0.0 then
  begin
    // default joystick initialization
    // 2 axes only with joystick control
    dwAxisMap[JOY_AXIS_X] := Cardinal(AxisTurn);
    // dwControlMap[JOY_AXIS_X] = JOY_ABSOLUTE_AXIS;
    dwAxisMap[JOY_AXIS_Y] := Cardinal(AxisForward);
    // dwControlMap[JOY_AXIS_Y] = JOY_ABSOLUTE_AXIS;
  end
  else
  begin
    if strcmp(joy_name^.string_, 'joystick') <> 0 then
    begin
      // notify user of advanced controller
      Com_Printf(#10'%s configured'#10#10, [joy_name^.string_]);
    end;

    // advanced initialization here
    // data supplied by user via joy_axisn cvars
    dwTemp := Round(joy_advaxisx^.value);
    dwAxisMap[JOY_AXIS_X] := dwTemp and $0000000F;
    dwControlMap[JOY_AXIS_X] := dwTemp and JOY_RELATIVE_AXIS;
    dwTemp := Round(joy_advaxisy^.value);
    dwAxisMap[JOY_AXIS_Y] := dwTemp and $0000000F;
    dwControlMap[JOY_AXIS_Y] := dwTemp and JOY_RELATIVE_AXIS;
    dwTemp := Round(joy_advaxisz^.value);
    dwAxisMap[JOY_AXIS_Z] := dwTemp and $0000000F;
    dwControlMap[JOY_AXIS_Z] := dwTemp and JOY_RELATIVE_AXIS;
    dwTemp := Round(joy_advaxisr^.value);
    dwAxisMap[JOY_AXIS_R] := dwTemp and $0000000F;
    dwControlMap[JOY_AXIS_R] := dwTemp and JOY_RELATIVE_AXIS;
    dwTemp := Round(joy_advaxisu^.value);
    dwAxisMap[JOY_AXIS_U] := dwTemp and $0000000F;
    dwControlMap[JOY_AXIS_U] := dwTemp and JOY_RELATIVE_AXIS;
    dwTemp := Round(joy_advaxisv^.value);
    dwAxisMap[JOY_AXIS_V] := dwTemp and $0000000F;
    dwControlMap[JOY_AXIS_V] := dwTemp and JOY_RELATIVE_AXIS;
  end;

  // compute the axes to collect from DirectInput
  joy_flags := JOY_RETURNCENTERED or JOY_RETURNBUTTONS or JOY_RETURNPOV;
  for i := 0 to JOY_MAX_AXES - 1 do
  begin
    if (dwAxisMap[i] <> Cardinal(AxisNada)) then
    begin
      joy_flags := joy_flags or dwAxisFlags[i];
    end;
  end;
end;

(*
===========
IN_Commands
===========
*)

procedure IN_Commands;
var
  i, key_index: Integer;
  buttonstate, povstate: DWORD;
begin
  if not joy_avail then
  begin
    exit;
  end;

  // loop through the joystick buttons
  // key a joystick event or auxillary event for higher number buttons for each state change
  buttonstate := ji.wButtons;
  for i := 0 to joy_numbuttons - 1 do
  begin
    if ((buttonstate and (1 shl i) <> 0) and
      not (joy_oldbuttonstate and (1 shl i) <> 0)) then
    begin
      if i < 4 then
        key_index := K_JOY1
      else
        key_index := K_AUX1;
      keys.Key_Event(key_index + i, true, 0);
    end;

    if (not (buttonstate and (1 shl i) <> 0) and
      (joy_oldbuttonstate and (1 shl i) <> 0)) then
    begin
      if i < 4 then
        key_index := K_JOY1
      else
        key_index := K_AUX1;
      keys.Key_Event(key_index + i, false, 0);
    end;
  end;
  joy_oldbuttonstate := buttonstate;

  if joy_haspov then
  begin
    // convert POV information into 4 bits of state information
    // this avoids any potential problems related to moving from one
    // direction to another without going through the center position
    povstate := 0;
    if not (ji.dwPOV = JOY_POVCENTERED) then
    begin
      if (ji.dwPOV = JOY_POVFORWARD) then
        povstate := povstate or $01;
      if (ji.dwPOV = JOY_POVRIGHT) then
        povstate := povstate or $02;
      if (ji.dwPOV = JOY_POVBACKWARD) then
        povstate := povstate or $04;
      if (ji.dwPOV = JOY_POVLEFT) then
        povstate := povstate or $08;
    end;
    // determine which bits have changed and key an auxillary event for each change
    for i := 0 to 3 do
    begin
      if ((povstate and (1 shl i) <> 0) and
        not (joy_oldpovstate and (1 shl i) <> 0)) then
      begin
        keys.Key_Event(K_AUX29 + i, true, 0);
      end;

      if (not (povstate and (1 shl i) <> 0) and
        (joy_oldpovstate and (1 shl i) <> 0)) then
      begin
        keys.Key_Event(K_AUX29 + i, false, 0);
      end;
    end;
    joy_oldpovstate := povstate;
  end;
end;

(*
===============
IN_ReadJoystick
===============
*)

function IN_ReadJoystick: qboolean;
begin

  FillChar(ji, sizeof(ji), 0);
  ji.dwSize := sizeof(ji);
  ji.dwFlags := joy_flags;

  if joyGetPosEx(joy_id, @ji) = JOYERR_NOERROR then
  begin
    Result := true;
  end
  else
  begin
    // read error occurred
    // turning off the joystick seems too harsh for 1 read error,\
    // but what should be done?
    // Com_Printf ('IN_ReadJoystick: no response'#10);
    // joy_avail = false;
    Result := false;
  end;
end;

(*
===========
IN_JoyMove
===========
*)

procedure IN_JoyMove(cmd: usercmd_p);
var
  speed, aspeed: Single;
  fAxisValue: Single;
  i: Integer;
begin

  // complete initialization if first time in
  // this is needed as cvars are not available at initialization time
  if not (joy_advancedinit) then
  begin
    Joy_AdvancedUpdate_f;
    joy_advancedinit := true;
  end;

  // verify joystick is available and that the user wants to use it
  if not (joy_avail) or not (in_joystick^.value <> 0) then
  begin
    exit;
  end;

  // collect the joystick data, if possible
  if not IN_ReadJoystick then
  begin
    exit;
  end;

  if ((in_speed.state and 1) xor (round(cl_run.value)) <> 0) then
    speed := 2
  else
    speed := 1;
  aspeed := speed * cls.frametime;

  // loop through the axes
  for i := 0 to JOY_MAX_AXES - 1 do
  begin
    // get the floating point zero-centered, potentially-inverted data for the current axis
    fAxisValue := pdwRawValue[i]^;
    // move centerpoint to zero
    fAxisValue := fAxisValue - 32768.0;

    // convert range from -32768..32767 to -1..1
    fAxisValue := fAxisValue / 32768.0;

    case _ControlList(dwAxisMap[i]) of
      AxisForward:
        begin
          if ((joy_advanced^.value = 0.0) and mlooking) then
          begin
            // user wants forward control to become look control
            if (fabs(fAxisValue) > joy_pitchthreshold^.value) then
            begin
              // if mouse invert is on, invert the joystick pitch value
              // only absolute control support here (joy_advanced is false)
              if (m_pitch^.value < 0.0) then
              begin
                cl.viewangles[PITCH] := cl.viewangles[PITCH] - (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
              end
              else
              begin
                cl.viewangles[PITCH] := cl.viewangles[PITCH] + (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
              end;
            end;
          end
          else
          begin
            // user wants forward control to be forward control
            if (fabs(fAxisValue) > joy_forwardthreshold^.value) then
            begin
              cmd.forwardmove := Round(cmd.forwardmove + (fAxisValue * joy_forwardsensitivity.value) * speed * cl_forwardspeed.value);
            end;
          end;
        end;
      AxisSide:
        begin
          if (fabs(fAxisValue) > joy_sidethreshold^.value) then
          begin
            cmd.sidemove := Round(cmd.sidemove + (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value);
          end;
        end;
      AxisUp:
        begin
          if (fabs(fAxisValue) > joy_upthreshold^.value) then
          begin
            cmd.upmove := Round(cmd.upmove + (fAxisValue * joy_upsensitivity.value) * speed * cl_upspeed.value);
          end;
        end;
      AxisTurn:
        begin
          if ((in_strafe.state and 1 <> 0) or ((lookstrafe.value <> 0) and mlooking)) then
          begin
            // user wants turn control to become side control
            if (fabs(fAxisValue) > joy_sidethreshold.value) then
            begin
              cmd.sidemove := Round(cmd.sidemove - (fAxisValue * joy_sidesensitivity.value) * speed * cl_sidespeed.value);
            end;
          end
          else
          begin
            // user wants turn control to be turn control
            if (fabs(fAxisValue) > joy_yawthreshold.value) then
            begin
              if (dwControlMap[i] = JOY_ABSOLUTE_AXIS) then
              begin
                cl.viewangles[YAW] := Round(cl.viewangles[YAW] + (fAxisValue * joy_yawsensitivity.value) * aspeed * cl_yawspeed.value);
              end
              else
              begin
                cl.viewangles[YAW] := cl.viewangles[YAW] + (fAxisValue * joy_yawsensitivity.value) * speed * 180.0;
              end;

            end;
          end;
        end;
      AxisLook:
        begin
          if (mlooking) then
          begin
            if (fabs(fAxisValue) > joy_pitchthreshold.value) then
            begin
              // pitch movement detected and pitch movement desired by user
              if (dwControlMap[i] = JOY_ABSOLUTE_AXIS) then
              begin
                cl.viewangles[PITCH] := cl.viewangles[PITCH] + (fAxisValue * joy_pitchsensitivity.value) * aspeed * cl_pitchspeed.value;
              end
              else
              begin
                cl.viewangles[PITCH] := cl.viewangles[PITCH] + (fAxisValue * joy_pitchsensitivity.value) * speed * 180.0;
              end;
            end;
          end;
        end;
    end;
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -