📄 in_win.pas
字号:
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 + -