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

📄 in_win.pas

📁 雷神之锤2(Quake2)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;
  joyid: Integer;
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
	for joy_id:=0 to numdevs-1 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;
	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 + -