2023-10-03 17:23:56 +03:00
//===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
2020-04-22 12:56:21 -04:00
//
// Purpose: Mouse input routines
//
// $Workfile: $
// $Date: $
// $NoKeywords: $
//===========================================================================//
# if defined( WIN32 ) && !defined( _X360 )
# include <windows.h>
# endif
2023-10-03 17:23:56 +03:00
# ifdef OSX
# include <Carbon/Carbon.h>
# endif
2020-04-22 12:56:21 -04:00
# include "hud.h"
# include "cdll_int.h"
# include "kbutton.h"
# include "basehandle.h"
# include "usercmd.h"
# include "input.h"
# include "iviewrender.h"
# include "iclientmode.h"
# include "tier0/icommandline.h"
2023-10-03 17:23:56 +03:00
# include "vgui/isurface.h"
# include "vgui_controls/controls.h"
# include "vgui/cursor.h"
2020-04-22 12:56:21 -04:00
# include "cdll_client_int.h"
# include "cdll_util.h"
# include "tier1/convar_serverbounded.h"
2023-10-03 17:23:56 +03:00
# include "inputsystem/iinputstacksystem.h"
2020-04-22 12:56:21 -04:00
# if defined( _X360 )
# include "xbox/xbox_win32stubs.h"
# endif
// memdbgon must be the last include file in a .cpp file!!!
# include "tier0/memdbgon.h"
// up / down
# define PITCH 0
// left / right
# define YAW 1
extern ConVar lookstrafe ;
extern ConVar cl_pitchdown ;
extern ConVar cl_pitchup ;
extern const ConVar * sv_cheats ;
2023-10-03 17:23:56 +03:00
2020-04-22 12:56:21 -04:00
class ConVar_m_pitch : public ConVar_ServerBounded
{
public :
ConVar_m_pitch ( ) :
2023-10-03 17:23:56 +03:00
ConVar_ServerBounded ( " m_pitch " , " 0.022 " , FCVAR_ARCHIVE | FCVAR_SS , " Mouse pitch factor. " )
2020-04-22 12:56:21 -04:00
{
}
virtual float GetFloat ( ) const
{
if ( ! sv_cheats )
sv_cheats = cvar - > FindVar ( " sv_cheats " ) ;
2023-10-03 17:23:56 +03:00
float flBaseValue ;
2020-04-22 12:56:21 -04:00
// If sv_cheats is on then it can be anything.
2023-10-03 17:23:56 +03:00
int nSlot = GET_ACTIVE_SPLITSCREEN_SLOT ( ) ;
if ( nSlot ! = 0 )
{
static SplitScreenConVarRef s_m_pitch ( " m_pitch " ) ;
flBaseValue = s_m_pitch . GetFloat ( nSlot ) ;
}
else
{
flBaseValue = GetBaseFloatValue ( ) ;
}
2020-04-22 12:56:21 -04:00
if ( ! sv_cheats | | sv_cheats - > GetBool ( ) )
return flBaseValue ;
// If sv_cheats is off than it can only be 0.022 or -0.022 (if they've reversed the mouse in the options).
if ( flBaseValue > 0 )
return 0.022f ;
else
return - 0.022f ;
}
} cvar_m_pitch ;
ConVar_ServerBounded * m_pitch = & cvar_m_pitch ;
extern ConVar cam_idealyaw ;
extern ConVar cam_idealpitch ;
extern ConVar thirdperson_platformer ;
2023-10-03 17:23:56 +03:00
static ConVar m_filter ( " m_filter " , " 0 " , FCVAR_ARCHIVE | FCVAR_SS , " Mouse filtering (set this to 1 to average the mouse over 2 frames) . " ) ;
2020-04-22 12:56:21 -04:00
ConVar sensitivity ( " sensitivity " , " 3 " , FCVAR_ARCHIVE , " Mouse sensitivity. " , true , 0.0001f , true , 10000000 ) ;
static ConVar m_side ( " m_side " , " 0.8 " , FCVAR_ARCHIVE , " Mouse side factor. " ) ;
static ConVar m_yaw ( " m_yaw " , " 0.022 " , FCVAR_ARCHIVE , " Mouse yaw factor. " ) ;
static ConVar m_forward ( " m_forward " , " 1 " , FCVAR_ARCHIVE , " Mouse forward factor. " ) ;
2023-10-03 17:23:56 +03:00
static ConVar m_customaccel ( " m_customaccel " , " 0 " , FCVAR_ARCHIVE , " Custom mouse acceleration (0 disable, 1 to enable, 2 enable with separate yaw/pitch rescale). " \
" \n Formula: mousesensitivity = ( rawmousedelta^m_customaccel_exponent ) * m_customaccel_scale + sensitivity " \
" \n If mode is 2, then x and y sensitivity are scaled by m_pitch and m_yaw respectively. " , true , 0 , false , 0.0f ) ;
2020-04-22 12:56:21 -04:00
static ConVar m_customaccel_scale ( " m_customaccel_scale " , " 0.04 " , FCVAR_ARCHIVE , " Custom mouse acceleration value. " , true , 0 , false , 0.0f ) ;
static ConVar m_customaccel_max ( " m_customaccel_max " , " 0 " , FCVAR_ARCHIVE , " Max mouse move scale factor, 0 for no limit " ) ;
2023-10-03 17:23:56 +03:00
static ConVar m_customaccel_exponent ( " m_customaccel_exponent " , " 1 " , FCVAR_ARCHIVE , " Mouse move is raised to this power before being scaled by scale factor. " ) ;
2020-04-22 12:56:21 -04:00
static ConVar m_mouseaccel1 ( " m_mouseaccel1 " , " 0 " , FCVAR_ARCHIVE , " Windows mouse acceleration initial threshold (2x movement) . " , true, 0, false, 0.0f ) ;
static ConVar m_mouseaccel2 ( " m_mouseaccel2 " , " 0 " , FCVAR_ARCHIVE , " Windows mouse acceleration secondary threshold (4x movement) . " , true, 0, false, 0.0f ) ;
2023-10-03 17:23:56 +03:00
static ConVar m_mousespeed ( " m_mousespeed " , " 1 " , FCVAR_ARCHIVE , " Windows mouse speed factor (range 1 to 20) . " , true, 1, true, 20 ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
ConVar cl_mouselook ( " cl_mouselook " , " 1 " , FCVAR_ARCHIVE | FCVAR_NOT_CONNECTED | FCVAR_USERINFO | FCVAR_SS , " Set to 1 to use mouse for look, 0 for keyboard look. Cannot be set while connected to a server. " ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
ConVar cl_mouseenable ( " cl_mouseenable " , " 1 " , FCVAR_RELEASE ) ;
2020-04-22 12:56:21 -04:00
//-----------------------------------------------------------------------------
// Purpose: Hides cursor and starts accumulation/re-centering
//-----------------------------------------------------------------------------
void CInput : : ActivateMouse ( void )
{
if ( m_fMouseActive )
return ;
if ( m_fMouseInitialized )
{
if ( m_fMouseParmsValid )
{
2023-10-03 17:23:56 +03:00
# ifdef WIN32
2020-04-22 12:56:21 -04:00
m_fRestoreSPI = SystemParametersInfo ( SPI_SETMOUSE , 0 , m_rgNewMouseParms , 0 ) ? true : false ;
# endif
}
m_fMouseActive = true ;
ResetMouse ( ) ;
2023-10-03 17:23:56 +03:00
g_pInputStackSystem - > SetCursorIcon ( m_hInputContext , INPUT_CURSOR_HANDLE_INVALID ) ;
2020-04-22 12:56:21 -04:00
// Clear accumulated error, too
2023-10-03 17:23:56 +03:00
for ( int hh = 0 ; hh < MAX_SPLITSCREEN_PLAYERS ; + + hh )
{
GetPerUser ( hh ) . m_flAccumulatedMouseXMovement = 0 ;
GetPerUser ( hh ) . m_flAccumulatedMouseYMovement = 0 ;
}
2020-04-22 12:56:21 -04:00
}
}
//-----------------------------------------------------------------------------
// Purpose: Gives back the cursor and stops centering of mouse
//-----------------------------------------------------------------------------
void CInput : : DeactivateMouse ( void )
{
// This gets called whenever the mouse should be inactive. We only respond to it if we had
// previously activated the mouse. We'll show the cursor in here.
if ( ! m_fMouseActive )
return ;
if ( m_fMouseInitialized )
{
if ( m_fRestoreSPI )
{
2023-10-03 17:23:56 +03:00
# ifdef WIN32
2020-04-22 12:56:21 -04:00
SystemParametersInfo ( SPI_SETMOUSE , 0 , m_rgOrigMouseParms , 0 ) ;
# endif
}
m_fMouseActive = false ;
2023-10-03 17:23:56 +03:00
g_pInputStackSystem - > SetCursorIcon ( m_hInputContext , g_pInputSystem - > GetStandardCursor ( INPUT_CURSOR_ARROW ) ) ;
2020-04-22 12:56:21 -04:00
// Clear accumulated error, too
2023-10-03 17:23:56 +03:00
for ( int hh = 0 ; hh < MAX_SPLITSCREEN_PLAYERS ; + + hh )
{
ACTIVE_SPLITSCREEN_PLAYER_GUARD ( hh ) ;
GetPerUser ( ) . m_flAccumulatedMouseXMovement = 0 ;
GetPerUser ( ) . m_flAccumulatedMouseYMovement = 0 ;
}
2020-04-22 12:56:21 -04:00
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CInput : : CheckMouseAcclerationVars ( )
{
// Don't change them if the mouse is inactive, invalid, or not using parameters for restore
if ( ! m_fMouseActive | |
! m_fMouseInitialized | |
! m_fMouseParmsValid | |
! m_fRestoreSPI )
{
return ;
}
int values [ NUM_MOUSE_PARAMS ] ;
values [ MOUSE_SPEED_FACTOR ] = m_mousespeed . GetInt ( ) ;
values [ MOUSE_ACCEL_THRESHHOLD1 ] = m_mouseaccel1 . GetInt ( ) ;
values [ MOUSE_ACCEL_THRESHHOLD2 ] = m_mouseaccel2 . GetInt ( ) ;
bool dirty = false ;
int i ;
for ( i = 0 ; i < NUM_MOUSE_PARAMS ; i + + )
{
if ( ! m_rgCheckMouseParam [ i ] )
continue ;
if ( values [ i ] ! = m_rgNewMouseParms [ i ] )
{
dirty = true ;
m_rgNewMouseParms [ i ] = values [ i ] ;
char const * name = " " ;
switch ( i )
{
default :
case MOUSE_SPEED_FACTOR :
name = " m_mousespeed " ;
break ;
case MOUSE_ACCEL_THRESHHOLD1 :
name = " m_mouseaccel1 " ;
break ;
case MOUSE_ACCEL_THRESHHOLD2 :
name = " m_mouseaccel2 " ;
break ;
}
char sz [ 256 ] ;
Q_snprintf ( sz , sizeof ( sz ) , " Mouse parameter '%s' set to %i \n " , name , values [ i ] ) ;
DevMsg ( " %s " , sz ) ;
}
}
if ( dirty )
{
// Update them
# ifdef WIN32
m_fRestoreSPI = SystemParametersInfo ( SPI_SETMOUSE , 0 , m_rgNewMouseParms , 0 ) ? true : false ;
# endif
}
}
//-----------------------------------------------------------------------------
// Purpose: One-time initialization
//-----------------------------------------------------------------------------
void CInput : : Init_Mouse ( void )
{
if ( CommandLine ( ) - > FindParm ( " -nomouse " ) )
return ;
2023-10-03 17:23:56 +03:00
for ( int hh = 0 ; hh < MAX_SPLITSCREEN_PLAYERS ; + + hh )
{
ACTIVE_SPLITSCREEN_PLAYER_GUARD ( hh ) ;
GetPerUser ( ) . m_flPreviousMouseXPosition = 0.0f ;
GetPerUser ( ) . m_flPreviousMouseYPosition = 0.0f ;
}
2020-04-22 12:56:21 -04:00
m_fMouseInitialized = true ;
m_fMouseParmsValid = false ;
if ( CommandLine ( ) - > FindParm ( " -useforcedmparms " ) )
{
# ifdef WIN32
m_fMouseParmsValid = SystemParametersInfo ( SPI_GETMOUSE , 0 , m_rgOrigMouseParms , 0 ) ? true : false ;
# else
m_fMouseParmsValid = false ;
# endif
if ( m_fMouseParmsValid )
{
if ( CommandLine ( ) - > FindParm ( " -noforcemspd " ) )
{
m_rgNewMouseParms [ MOUSE_SPEED_FACTOR ] = m_rgOrigMouseParms [ MOUSE_SPEED_FACTOR ] ;
}
else
{
2023-10-03 17:23:56 +03:00
m_rgCheckMouseParam [ MOUSE_SPEED_FACTOR ] = true ;
2020-04-22 12:56:21 -04:00
}
if ( CommandLine ( ) - > FindParm ( " -noforcemaccel " ) )
{
m_rgNewMouseParms [ MOUSE_ACCEL_THRESHHOLD1 ] = m_rgOrigMouseParms [ MOUSE_ACCEL_THRESHHOLD1 ] ;
m_rgNewMouseParms [ MOUSE_ACCEL_THRESHHOLD2 ] = m_rgOrigMouseParms [ MOUSE_ACCEL_THRESHHOLD2 ] ;
}
else
{
m_rgCheckMouseParam [ MOUSE_ACCEL_THRESHHOLD1 ] = true ;
m_rgCheckMouseParam [ MOUSE_ACCEL_THRESHHOLD2 ] = true ;
}
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Get the center point of the engine window
// Input : int&x -
// y -
//-----------------------------------------------------------------------------
void CInput : : GetWindowCenter ( int & x , int & y )
{
int w , h ;
engine - > GetScreenSize ( w , h ) ;
x = w > > 1 ;
y = h > > 1 ;
}
//-----------------------------------------------------------------------------
// Purpose: Recenter the mouse
//-----------------------------------------------------------------------------
void CInput : : ResetMouse ( void )
{
int x , y ;
GetWindowCenter ( x , y ) ;
SetMousePos ( x , y ) ;
}
//-----------------------------------------------------------------------------
// Purpose: GetAccumulatedMouse -- the mouse can be sampled multiple times per frame and
// these results are accumulated each time. This function gets the accumulated mouse changes and resets the accumulators
// Input : *mx -
// *my -
//-----------------------------------------------------------------------------
2023-10-03 17:23:56 +03:00
void CInput : : GetAccumulatedMouseDeltasAndResetAccumulators ( int nSlot , float * mx , float * my )
2020-04-22 12:56:21 -04:00
{
Assert ( mx ) ;
Assert ( my ) ;
2023-10-03 17:23:56 +03:00
PerUserInput_t & user = GetPerUser ( nSlot ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
* mx = user . m_flAccumulatedMouseXMovement ;
* my = user . m_flAccumulatedMouseYMovement ;
user . m_flAccumulatedMouseXMovement = 0 ;
user . m_flAccumulatedMouseYMovement = 0 ;
2020-04-22 12:56:21 -04:00
}
//-----------------------------------------------------------------------------
// Purpose: GetMouseDelta -- Filters the mouse and stores results in old position
// Input : mx -
// my -
// *oldx -
// *oldy -
// *x -
// *y -
//-----------------------------------------------------------------------------
2023-10-03 17:23:56 +03:00
void CInput : : GetMouseDelta ( int nSlot , float inmousex , float inmousey , float * pOutMouseX , float * pOutMouseY )
2020-04-22 12:56:21 -04:00
{
// Apply filtering?
2023-10-03 17:23:56 +03:00
static SplitScreenConVarRef s_m_filter ( " m_filter " ) ;
if ( s_m_filter . GetBool ( nSlot ) )
2020-04-22 12:56:21 -04:00
{
// Average over last two samples
2023-10-03 17:23:56 +03:00
* pOutMouseX = ( inmousex + GetPerUser ( ) . m_flPreviousMouseXPosition ) * 0.5f ;
* pOutMouseY = ( inmousey + GetPerUser ( ) . m_flPreviousMouseYPosition ) * 0.5f ;
2020-04-22 12:56:21 -04:00
}
else
{
* pOutMouseX = inmousex ;
* pOutMouseY = inmousey ;
}
// Latch previous
2023-10-03 17:23:56 +03:00
GetPerUser ( ) . m_flPreviousMouseXPosition = inmousex ;
GetPerUser ( ) . m_flPreviousMouseYPosition = inmousey ;
2020-04-22 12:56:21 -04:00
}
//-----------------------------------------------------------------------------
// Purpose: Multiplies mouse values by sensitivity. Note that for windows mouse settings
// the input x,y offsets are already scaled based on that. The custom acceleration, therefore,
// is totally engine-specific and applies as a post-process to allow more user tuning.
// Input : *x -
// *y -
//-----------------------------------------------------------------------------
2023-10-03 17:23:56 +03:00
void CInput : : ScaleMouse ( int nSlot , float * x , float * y )
2020-04-22 12:56:21 -04:00
{
float mx = * x ;
float my = * y ;
2023-10-03 17:23:56 +03:00
float flHudSensitivity = GetHud ( nSlot ) . GetSensitivity ( ) ;
float mouse_senstivity = ( flHudSensitivity ! = 0 ) ? flHudSensitivity : sensitivity . GetFloat ( ) ;
2020-04-22 12:56:21 -04:00
2023-10-03 17:23:56 +03:00
if ( m_customaccel . GetBool ( ) )
2020-04-22 12:56:21 -04:00
{
float raw_mouse_movement_distance = sqrt ( mx * mx + my * my ) ;
float acceleration_scale = m_customaccel_scale . GetFloat ( ) ;
float accelerated_sensitivity_max = m_customaccel_max . GetFloat ( ) ;
float accelerated_sensitivity_exponent = m_customaccel_exponent . GetFloat ( ) ;
2023-10-03 17:23:56 +03:00
float accelerated_sensitivity = ( ( float ) pow ( raw_mouse_movement_distance , accelerated_sensitivity_exponent ) * acceleration_scale + mouse_senstivity ) ;
2020-04-22 12:56:21 -04:00
if ( accelerated_sensitivity_max > 0.0001f & &
accelerated_sensitivity > accelerated_sensitivity_max )
{
accelerated_sensitivity = accelerated_sensitivity_max ;
}
* x * = accelerated_sensitivity ;
* y * = accelerated_sensitivity ;
2023-10-03 17:23:56 +03:00
// Further re-scale by yaw and pitch magnitude if user requests alternate mode 2
2020-04-22 12:56:21 -04:00
// This means that they will need to up their value for m_customaccel_scale greatly (>40x) since m_pitch/yaw default
// to 0.022
2023-10-03 17:23:56 +03:00
if ( m_customaccel . GetInt ( ) = = 2 )
2020-04-22 12:56:21 -04:00
{
* x * = m_yaw . GetFloat ( ) ;
* y * = m_pitch - > GetFloat ( ) ;
}
}
else
{
2023-10-03 17:23:56 +03:00
* x * = mouse_senstivity ;
* y * = mouse_senstivity ;
2020-04-22 12:56:21 -04:00
}
}
//-----------------------------------------------------------------------------
// Purpose: ApplyMouse -- applies mouse deltas to CUserCmd
// Input : viewangles -
// *cmd -
// mouse_x -
// mouse_y -
//-----------------------------------------------------------------------------
2023-10-03 17:23:56 +03:00
void CInput : : ApplyMouse ( int nSlot , QAngle & viewangles , CUserCmd * cmd , float mouse_x , float mouse_y )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
PerUserInput_t & user = GetPerUser ( nSlot ) ;
//roll the view angles so roll is 0 (the HL2 assumed state) and mouse adjustments are relative to the screen.
//Assuming roll is unchanging, we want mouse left to translate to screen left at all times (same for right, up, and down)
if ( ! ( ( in_strafe . GetPerUser ( nSlot ) . state & 1 ) | | lookstrafe . GetInt ( ) ) )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
if ( CAM_IsThirdPerson ( ) & & thirdperson_platformer . GetInt ( ) )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
if ( mouse_x )
{
// use the mouse to orbit the camera around the player, and update the idealAngle
user . m_vecCameraOffset [ YAW ] - = m_yaw . GetFloat ( ) * mouse_x ;
cam_idealyaw . SetValue ( user . m_vecCameraOffset [ YAW ] - viewangles [ YAW ] ) ;
// why doesn't this work??? CInput::AdjustYaw is why
//cam_idealyaw.SetValue( cam_idealyaw.GetFloat() - m_yaw.GetFloat() * mouse_x );
}
2020-04-22 12:56:21 -04:00
}
else
{
2023-10-03 17:23:56 +03:00
// Otherwize, use mouse to spin around vertical axis
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
viewangles [ YAW ] - = m_yaw . GetFloat ( ) * mouse_x ;
2020-04-22 12:56:21 -04:00
}
}
}
else
{
// If holding strafe key or mlooking and have lookstrafe set to true, then apply
// horizontal mouse movement to sidemove.
cmd - > sidemove + = m_side . GetFloat ( ) * mouse_x ;
}
// If mouselooking and not holding strafe key, then use vertical mouse
// to adjust view pitch.
2023-10-03 17:23:56 +03:00
if ( ! ( in_strafe . GetPerUser ( nSlot ) . state & 1 ) )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
if ( CAM_IsThirdPerson ( ) & & thirdperson_platformer . GetInt ( ) )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
if ( mouse_y )
{
// use the mouse to orbit the camera around the player, and update the idealAngle
user . m_vecCameraOffset [ PITCH ] + = m_pitch - > GetFloat ( ) * mouse_y ;
cam_idealpitch . SetValue ( user . m_vecCameraOffset [ PITCH ] - viewangles [ PITCH ] ) ;
// why doesn't this work??? CInput::AdjustYaw is why
//cam_idealpitch.SetValue( cam_idealpitch.GetFloat() + m_pitch->GetFloat() * mouse_y );
}
2020-04-22 12:56:21 -04:00
}
else
{
{
2022-03-01 23:00:42 +03:00
viewangles [ PITCH ] + = m_pitch - > GetFloat ( ) * mouse_y ;
2020-04-22 12:56:21 -04:00
}
// Check pitch bounds
if ( viewangles [ PITCH ] > cl_pitchdown . GetFloat ( ) )
{
viewangles [ PITCH ] = cl_pitchdown . GetFloat ( ) ;
}
if ( viewangles [ PITCH ] < - cl_pitchup . GetFloat ( ) )
{
viewangles [ PITCH ] = - cl_pitchup . GetFloat ( ) ;
}
2023-10-03 17:23:56 +03:00
}
2020-04-22 12:56:21 -04:00
}
else
{
// Otherwise if holding strafe key and noclipping, then move upward
/* if ((in_strafe.state & 1) && IsNoClipping() )
{
cmd - > upmove - = m_forward . GetFloat ( ) * mouse_y ;
}
else */
{
// Default is to apply vertical mouse movement as a forward key press.
cmd - > forwardmove - = m_forward . GetFloat ( ) * mouse_y ;
}
}
// Finally, add mouse state to usercmd.
// NOTE: Does rounding to int cause any issues? ywb 1/17/04
cmd - > mousedx = ( int ) mouse_x ;
cmd - > mousedy = ( int ) mouse_y ;
}
2023-10-03 17:23:56 +03:00
extern bool UsingMouselook ( int nSlot ) ;
2020-04-22 12:56:21 -04:00
//-----------------------------------------------------------------------------
// Purpose: AccumulateMouse
//-----------------------------------------------------------------------------
2023-10-03 17:23:56 +03:00
void CInput : : AccumulateMouse ( int nSlot )
2020-04-22 12:56:21 -04:00
{
if ( ! cl_mouseenable . GetBool ( ) )
{
return ;
}
2023-10-03 17:23:56 +03:00
if ( ! UsingMouselook ( nSlot ) )
2020-04-22 12:56:21 -04:00
{
return ;
}
int w , h ;
engine - > GetScreenSize ( w , h ) ;
// x,y = screen center
2023-10-03 17:23:56 +03:00
int x = w > > 1 ;
int y = h > > 1 ;
// Clamp
if ( m_fMouseActive )
{
int ox , oy ;
GetMousePos ( ox , oy ) ;
ox = clamp ( ox , 0 , w - 1 ) ;
oy = clamp ( oy , 0 , h - 1 ) ;
SetMousePos ( ox , oy ) ;
}
2020-04-22 12:56:21 -04:00
//only accumulate mouse if we are not moving the camera with the mouse
2023-10-03 17:23:56 +03:00
PerUserInput_t & user = GetPerUser ( nSlot ) ;
if ( ! user . m_fCameraInterceptingMouse & & vgui : : surface ( ) - > IsCursorLocked ( ) )
2020-04-22 12:56:21 -04:00
{
//Assert( !vgui::surface()->IsCursorVisible() );
2023-10-03 17:23:56 +03:00
# ifdef WIN32
2020-04-22 12:56:21 -04:00
int current_posx , current_posy ;
GetMousePos ( current_posx , current_posy ) ;
2023-10-03 17:23:56 +03:00
user . m_flAccumulatedMouseXMovement + = current_posx - x ;
user . m_flAccumulatedMouseYMovement + = current_posy - y ;
// force the mouse to the center, so there's room to move
ResetMouse ( ) ;
# elif defined(OSX)
CGMouseDelta deltaX , deltaY ;
CGGetLastMouseDelta ( & deltaX , & deltaY ) ;
user . m_flAccumulatedMouseXMovement + = deltaX ;
user . m_flAccumulatedMouseYMovement + = deltaY ;
2020-04-22 12:56:21 -04:00
# else
# error
# endif
}
}
//-----------------------------------------------------------------------------
// Purpose: Get raw mouse position
// Input : &ox -
// &oy -
//-----------------------------------------------------------------------------
void CInput : : GetMousePos ( int & ox , int & oy )
{
2023-10-03 17:23:56 +03:00
g_pInputSystem - > GetCursorPosition ( & ox , & oy ) ;
2020-04-22 12:56:21 -04:00
}
//-----------------------------------------------------------------------------
// Purpose: Force raw mouse position
// Input : x -
// y -
//-----------------------------------------------------------------------------
2023-10-03 17:23:56 +03:00
void CInput : : SetMousePos ( int x , int y )
2020-04-22 12:56:21 -04:00
{
2023-10-03 17:23:56 +03:00
g_pInputStackSystem - > SetCursorPosition ( m_hInputContext , x , y ) ;
2020-04-22 12:56:21 -04:00
}
//-----------------------------------------------------------------------------
// Purpose: MouseMove -- main entry point for applying mouse
// Input : *cmd -
//-----------------------------------------------------------------------------
2023-10-03 17:23:56 +03:00
void CInput : : MouseMove ( int nSlot , CUserCmd * cmd )
2020-04-22 12:56:21 -04:00
{
float mouse_x , mouse_y ;
float mx , my ;
QAngle viewangles ;
// Get view angles from engine
engine - > GetViewAngles ( viewangles ) ;
// Validate mouse speed/acceleration settings
CheckMouseAcclerationVars ( ) ;
// Don't drift pitch at all while mouselooking.
view - > StopPitchDrift ( ) ;
//jjb - this disables normal mouse control if the user is trying to
// move the camera, or if the mouse cursor is visible
2023-10-03 17:23:56 +03:00
if ( ! GetPerUser ( nSlot ) . m_fCameraInterceptingMouse & & g_pInputStackSystem - > IsTopmostEnabledContext ( m_hInputContext ) )
2020-04-22 12:56:21 -04:00
{
// Sample mouse one more time
2023-10-03 17:23:56 +03:00
AccumulateMouse ( nSlot ) ;
2020-04-22 12:56:21 -04:00
// Latch accumulated mouse movements and reset accumulators
2023-10-03 17:23:56 +03:00
GetAccumulatedMouseDeltasAndResetAccumulators ( nSlot , & mx , & my ) ;
2020-04-22 12:56:21 -04:00
// Filter, etc. the delta values and place into mouse_x and mouse_y
2023-10-03 17:23:56 +03:00
GetMouseDelta ( nSlot , mx , my , & mouse_x , & mouse_y ) ;
2020-04-22 12:56:21 -04:00
// Apply scaling factor
2023-10-03 17:23:56 +03:00
ScaleMouse ( nSlot , & mouse_x , & mouse_y ) ;
2020-04-22 12:56:21 -04:00
// Let the client mode at the mouse input before it's used
2023-10-03 17:23:56 +03:00
GetClientMode ( ) - > OverrideMouseInput ( & mouse_x , & mouse_y ) ;
2020-04-22 12:56:21 -04:00
// Add mouse X/Y movement to cmd
2023-10-03 17:23:56 +03:00
ApplyMouse ( nSlot , viewangles , cmd , mouse_x , mouse_y ) ;
2020-04-22 12:56:21 -04:00
// Re-center the mouse.
ResetMouse ( ) ;
}
// Store out the new viewangles.
engine - > SetViewAngles ( viewangles ) ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *mx -
// *my -
// *unclampedx -
// *unclampedy -
//-----------------------------------------------------------------------------
void CInput : : GetFullscreenMousePos ( int * mx , int * my , int * unclampedx /*=NULL*/ , int * unclampedy /*=NULL*/ )
{
Assert ( mx ) ;
Assert ( my ) ;
2023-10-03 17:23:56 +03:00
# if !(INFESTED_DLL)
if ( g_pInputStackSystem - > IsTopmostEnabledContext ( m_hInputContext ) )
2020-04-22 12:56:21 -04:00
return ;
2023-10-03 17:23:56 +03:00
# endif
2020-04-22 12:56:21 -04:00
int x , y ;
GetWindowCenter ( x , y ) ;
int current_posx , current_posy ;
GetMousePos ( current_posx , current_posy ) ;
current_posx - = x ;
current_posy - = y ;
// Now need to add back in mid point of viewport
//
int w , h ;
vgui : : surface ( ) - > GetScreenSize ( w , h ) ;
current_posx + = w / 2 ;
current_posy + = h / 2 ;
if ( unclampedx )
{
* unclampedx = current_posx ;
}
if ( unclampedy )
{
* unclampedy = current_posy ;
}
// Clamp
current_posx = MAX ( 0 , current_posx ) ;
current_posx = MIN ( ScreenWidth ( ) , current_posx ) ;
current_posy = MAX ( 0 , current_posy ) ;
current_posy = MIN ( ScreenHeight ( ) , current_posy ) ;
* mx = current_posx ;
* my = current_posy ;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : mx -
// my -
//-----------------------------------------------------------------------------
void CInput : : SetFullscreenMousePos ( int mx , int my )
{
SetMousePos ( mx , my ) ;
}
//-----------------------------------------------------------------------------
// Purpose: ClearStates -- Resets mouse accumulators so you don't get a pop when returning to trapped mouse
//-----------------------------------------------------------------------------
void CInput : : ClearStates ( void )
{
if ( ! m_fMouseActive )
return ;
2023-10-03 17:23:56 +03:00
for ( int hh = 0 ; hh < MAX_SPLITSCREEN_PLAYERS ; + + hh )
{
ACTIVE_SPLITSCREEN_PLAYER_GUARD ( hh ) ;
GetPerUser ( ) . m_flAccumulatedMouseXMovement = 0 ;
GetPerUser ( ) . m_flAccumulatedMouseYMovement = 0 ;
}
}