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

📄 in_win.pas

📁 雷神之锤2(Quake2)Delphi源码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
{----------------------------------------------------------------------------}
{                                                                            }
{ File(s): in_win.c                                                          }
{ Content: Quake2\Win32\ support for qhost                                   }
{                                                                            }
{ Initial conversion by : andre                                              }
{ Initial conversion on : 02-May-2002                                        }
{                                                                            }
{ This File contains part of convertion of Quake2 source to ObjectPascal.    }
{ More information about this project can be found at:                       }
{ http://www.sulaco.co.za/quake2/                                            }
{                                                                            }
{ Copyright (C) 1997-2001 Id Software, Inc.                                  }
{                                                                            }
{ This program is free software; you can redistribute it and/or              }
{ modify it under the terms of the GNU General Public License                }
{ as published by the Free Software Foundation; either version 2             }
{ of the License, or (at your option) any later version.                     }
{                                                                            }
{ This program is distributed in the hope that it will be useful,            }
{ but WITHOUT ANY WARRANTY; without even the implied warranty of             }
{ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                       }
{                                                                            }
{ See the GNU General Public License for more details.                       }
{                                                                            }
{----------------------------------------------------------------------------}
{ * Updated:                                                                 }
{ 03-jun-2002 Juha Hartikainen (juha@linearteam.org)                         }
{ - Added missing units to uses clause.					     }
{}
{ 06-jun-2002 Juha Hartikainen (juha@linearteam.org)                         }
{ - Finished conversion.					     }
{----------------------------------------------------------------------------}

unit in_win;

// in_win.c -- windows 95 mouse and joystick code
// 02/21/97 JCB Added extended DirectInput code to support external controllers.


//------------------------------------------------------------------------------
// translated by andre: all my comments are marked with (andre),
//                      other comments are original
//------------------------------------------------------------------------------


interface

uses
  q_shared,
  CPas,
  CVar;


procedure IN_Activate (active: qboolean);
procedure IN_Frame;
procedure IN_Commands;
procedure IN_Init;
procedure IN_MouseEvent (mstate: Integer);
procedure IN_Move (cmd: usercmd_p);
procedure IN_Shutdown;

var
  in_joystick: cvar_p;


implementation

uses
  client,
  sys_win,
  cl_input,
  cl_main,
  vid_dll,
  keys,
  common,
  MMSystem,
  Windows,
  Types,
  Cmd;

// joystick defines and variables
// where should defines be moved?
const
  JOY_ABSOLUTE_AXIS =	$00000000;		// control like a joystick
  JOY_RELATIVE_AXIS =	$00000010;		// control like a mouse, spinner, trackball
  JOY_MAX_AXES	   =	6;  			// X, Y, Z, R, U, V
  JOY_AXIS_X	   =	0;
  JOY_AXIS_Y	   =	1;
  JOY_AXIS_Z	   =	2;
  JOY_AXIS_R	   =	3;
  JOY_AXIS_U	   =	4;
  JOY_AXIS_V	   =	5;

type
  _ControlList=(AxisNada = 0, AxisForward, AxisLook, AxisSide, AxisTurn, AxisUp);

const
  dwAxisFlags:    array[0..JOY_MAX_AXES-1] of DWord =
  (
	JOY_RETURNX, JOY_RETURNY, JOY_RETURNZ, JOY_RETURNR, JOY_RETURNU, JOY_RETURNV
  );

var
  dwAxisMap: array[0..JOY_MAX_AXES-1]of DWord;
  dwControlMap: array[0..JOY_MAX_AXES-1]of DWord;
  pdwRawValue: array[0..JOY_MAX_AXES-1]of PDWord;

	in_mouse: cvar_p;


// none of these cvars are saved over a session
// this means that advanced controller configuration needs to be executed
// each time.  this avoids any problems with getting back to a default usage
// or when changing from one controller to another.  this way at least something
// works.
  joy_name:               cvar_p;
  joy_advanced:           cvar_p;
  joy_advaxisx:           cvar_p;
  joy_advaxisy:           cvar_p;
  joy_advaxisz:           cvar_p;
  joy_advaxisr:           cvar_p;
  joy_advaxisu:           cvar_p;
  joy_advaxisv:           cvar_p;
  joy_forwardthreshold:   cvar_p;
  joy_sidethreshold:      cvar_p;
  joy_pitchthreshold:     cvar_p;
  joy_yawthreshold:       cvar_p;
  joy_forwardsensitivity: cvar_p;
  joy_sidesensitivity:    cvar_p;
  joy_pitchsensitivity:   cvar_p;
  joy_yawsensitivity:     cvar_p;
  joy_upthreshold:        cvar_p;
  joy_upsensitivity:      cvar_p;

  joy_avail, joy_advancedinit, joy_haspov:        qboolean;
  joy_oldbuttonstate, joy_oldpovstate:            DWORD;

  joy_id:                 Integer;
  joy_flags:              DWORD;
  joy_numbuttons:         DWORD;

  ji:                     JOYINFOEX;

  in_appactive:           qboolean;

// forward-referenced functions
procedure IN_StartupJoystick;forward;
procedure Joy_AdvancedUpdate_f; cdecl; forward;
procedure IN_JoyMove(cmd: usercmd_p);forward;

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

  MOUSE CONTROL

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

// mouse variables
var
  m_filter:       cvar_p;
  mlooking:       qboolean;


procedure IN_MLookDown; cdecl;
begin
  mlooking := true;
end;

procedure IN_MLookUp; cdecl;
begin
  mlooking := false;
  if (freelook^.value = 0) and (lookspring^.value <> 0) then
		IN_CenterView;
end;

var
  mouse_buttons:          Integer;
  mouse_oldbuttonstate:   Integer;
  current_pos:            TPoint;
  mouse_x, mouse_y,
  old_mouse_x, old_mouse_y,
  mx_accum, my_accum:     Integer;

  old_x, old_y:           Integer;

	mouseactive:            qboolean;	// false when not focus app

  restore_spi:            qboolean;
  mouseinitialized:       qboolean;
  mouseparmsvalid:        qboolean;

  window_center_x,
  window_center_y:        Integer;
  window_rect:            TRECT;

const
  originalmouseparms: array[0..2] of integer = (0,0,1);
  newmouseparms: array[0..2] of integer = (0,0,1);

(*
===========
IN_ActivateMouse

Called when the window gains focus or changes in some way
===========
*)
procedure IN_ActivateMouse;
var width, height:Integer;
begin
	if not mouseinitialized then
		exit;
	if (in_mouse^.value = 0) then
	 begin
		mouseactive := false;
		exit;
	 end;
	if mouseactive then
		exit;

	mouseactive := true;

	if mouseparmsvalid then
		restore_spi := SystemParametersInfo (SPI_SETMOUSE, 0, @newmouseparms, 0);

	width := GetSystemMetrics (SM_CXSCREEN);
	height := GetSystemMetrics (SM_CYSCREEN);

	GetWindowRect ( cl_hwnd, window_rect);
	if window_rect.left < 0 then
		window_rect.left := 0;
	if window_rect.top < 0 then
		window_rect.top := 0;
	if window_rect.right >= width then
		window_rect.right := width-1;
	if window_rect.bottom >= height-1 then
		window_rect.bottom := height-1;

	window_center_x := (window_rect.right + window_rect.left) div 2;
	window_center_y := (window_rect.top + window_rect.bottom) div 2;

	SetCursorPos (window_center_x, window_center_y);

	old_x := window_center_x;
	old_y := window_center_y;

	SetCapture ( cl_hwnd );
	ClipCursor (@window_rect);
	while ShowCursor (FALSE) >= 0 do ;
end;


(*
===========
IN_DeactivateMouse

Called when the window loses focus
===========
*)
procedure IN_DeactivateMouse;
begin
	if not mouseinitialized then
		exit;
	if not mouseactive then
		exit;

	if restore_spi then
		SystemParametersInfo (SPI_SETMOUSE, 0, @originalmouseparms, 0);

	mouseactive := false;

	ClipCursor (NULL);
	ReleaseCapture;
	while (ShowCursor (TRUE) < 0) do
		;
end;



(*
===========
IN_StartupMouse
===========
*)
procedure IN_StartupMouse;
var
  cv: cvar_p;
begin
	cv := Cvar_Get ('in_initmouse', '1', CVAR_NOSET);
	if (cv^.value = 0)  then
		exit;

	mouseinitialized := true;
	mouseparmsvalid := SystemParametersInfo (SPI_GETMOUSE, 0, @originalmouseparms, 0);
	mouse_buttons := 3;
end;

(*
===========
IN_MouseEvent
===========
*)
procedure IN_MouseEvent (mstate: Integer);
var
  i: Integer;
begin
	if not mouseinitialized then
		exit;

// perform button actions
	for i:=0 to mouse_buttons-1 do
	begin
		if ((mstate and (1 shl i)) <>0) and
		    not ((mouse_oldbuttonstate and (1 shl i)) <>0) then
		begin
			keys.Key_Event (K_MOUSE1 + i, true, sys_msg_time);
		end;

		if not ((mstate and (1 shl i)) <>0 ) and
		   ((mouse_oldbuttonstate and (1 shl i))<>0) then
		begin
			keys.Key_Event (K_MOUSE1 + i, false, sys_msg_time);
		end;
	end;

	mouse_oldbuttonstate := mstate;
end;


(*
===========
IN_MouseMove
===========
*)
procedure IN_MouseMove (cmd: usercmd_p);
var mx,my: Integer;
begin
	if  not mouseactive then
		exit;

	// find mouse movement
	if not GetCursorPos (current_pos) then
		exit;

	mx := current_pos.x - window_center_x;
	my := current_pos.y - window_center_y;

	if (m_filter^.value <> 0) then
	 begin
		mouse_x := (mx + old_mouse_x) div 2;
		mouse_y := (my + old_mouse_y) div 2;
	 end
	else
	 begin
		mouse_x := mx;
		mouse_y := my;
	 end;

	old_mouse_x := mx;
	old_mouse_y := my;

	mouse_x := Round(mouse_x*sensitivity^.value);
	mouse_y := Round(mouse_y*sensitivity^.value);
	if ((in_strafe.state and 1 <> 0) or
     ((lookstrafe.value <> 0) and mlooking )) then
		cmd^.sidemove := Round(cmd^.sidemove + (m_side^.value * mouse_x))
	else
		cl.viewangles[YAW] := cl.viewangles[YAW] - (m_yaw^.value * mouse_x);

	if ( (mlooking or (freelook.value <> 0)) and
       not(in_strafe.state and 1 <> 0)) then begin
		cl.viewangles[PITCH] := cl.viewangles[PITCH]+ (m_pitch^.value * mouse_y);
	 end
	else
	 begin
		cmd^.forwardmove := Round(cmd^.forwardmove- (m_forward^.value * mouse_y));
	 end;

	// force the mouse to the center, so there's room to move
	if (mx <> 0) or (my <> 0) then
		SetCursorPos (window_center_x, window_center_y);
end;


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

VIEW CENTERING

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

var
  v_centermove: cvar_p;
  v_centerspeed: cvar_p;


(*
===========
IN_Init
===========
*)
procedure IN_Init;
begin
  // mouse variables
  m_filter     	:= Cvar_Get ('m_filter','0',0);
  in_mouse 			:= Cvar_Get ('in_mouse','1',CVAR_ARCHIVE);

  // joystick variables
  in_joystick			:= Cvar_Get ('in_joystick','0',CVAR_ARCHIVE);
  joy_name			:= Cvar_Get ('joy_name','joystick',0);
  joy_advanced		:= Cvar_Get ('joy_advanced','0',0);
  joy_advaxisx		:= Cvar_Get ('joy_advaxisx','0',0);
  joy_advaxisy		:= Cvar_Get ('joy_advaxisy','0',0);
  joy_advaxisz		:= Cvar_Get ('joy_advaxisz','0',0);
  joy_advaxisr		:= Cvar_Get ('joy_advaxisr','0',0);
  joy_advaxisu		:= Cvar_Get ('joy_advaxisu','0',0);
  joy_advaxisv		:= Cvar_Get ('joy_advaxisv','0',0);
  joy_forwardthreshold	:= Cvar_Get ('joy_forwardthreshold','0.15',0);
  joy_sidethreshold		:= Cvar_Get ('joy_sidethreshold','0.15',0);
  joy_upthreshold  		:= Cvar_Get ('joy_upthreshold','0.15',0);
  joy_pitchthreshold		:= Cvar_Get ('joy_pitchthreshold','0.15',0);
  joy_yawthreshold		:= Cvar_Get ('joy_yawthreshold','0.15',0);
  joy_forwardsensitivity	:= Cvar_Get ('joy_forwardsensitivity','-1',0);
  joy_sidesensitivity		:= Cvar_Get ('joy_sidesensitivity','-1',0);
  joy_upsensitivity		:= Cvar_Get ('joy_upsensitivity','-1',0);
  joy_pitchsensitivity	:= Cvar_Get ('joy_pitchsensitivity','1',0);
  joy_yawsensitivity		:= Cvar_Get ('joy_yawsensitivity','-1',0);
  // centering
  v_centermove		:= Cvar_Get ('v_centermove','0.15',0);
  v_centerspeed		:= Cvar_Get ('v_centerspeed','500',0);

  Cmd_AddCommand ('+mlook', IN_MLookDown);
  Cmd_AddCommand ('-mlook', IN_MLookUp);

  Cmd_AddCommand ('joy_advancedupdate', Joy_AdvancedUpdate_f);

  IN_StartupMouse ();
  IN_StartupJoystick ();
end;

(*
===========
IN_Shutdown
===========
*)
procedure IN_Shutdown;
begin
  IN_DeactivateMouse;
end;


(*
===========
IN_Activate

Called when the main window gains or loses focus.
The window may have been destroyed and recreated
between a deactivate and an activate.
===========
*)
procedure IN_Activate (active: qboolean);
begin
	in_appactive := active;
	mouseactive := not active;		// force a new window check or turn off
end;


(*
==================
IN_Frame

Called every frame, even if not generating commands
==================
*)
procedure IN_Frame;

⌨️ 快捷键说明

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