//----------------------------------------------------------------------------- // 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 ) { #ifdef WIN32 SystemParametersInfo( SPI_SETMOUSE, 0, m_rgOrigMouseParms, 0 ); #endif } m_fMouseActive = false; g_pInputStackSystem->SetCursorIcon( m_hInputContext, g_pInputSystem->GetStandardCursor( INPUT_CURSOR_ARROW ) ); // Clear accumulated error, too for ( int hh = 0; hh < MAX_SPLITSCREEN_PLAYERS; ++hh ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( hh ); GetPerUser().m_flAccumulatedMouseXMovement = 0; GetPerUser().m_flAccumulatedMouseYMovement = 0; } } }
//----------------------------------------------------------------------------- // Purpose: Hides cursor and starts accumulation/re-centering //----------------------------------------------------------------------------- void CInput::ActivateMouse (void) { if ( m_fMouseActive ) return; if ( m_fMouseInitialized ) { if ( m_fMouseParmsValid ) { #ifdef WIN32 m_fRestoreSPI = SystemParametersInfo (SPI_SETMOUSE, 0, m_rgNewMouseParms, 0) ? true : false; #endif } m_fMouseActive = true; ResetMouse(); g_pInputStackSystem->SetCursorIcon( m_hInputContext, INPUT_CURSOR_HANDLE_INVALID ); // Clear accumulated error, too for ( int hh = 0; hh < MAX_SPLITSCREEN_PLAYERS; ++hh ) { GetPerUser( hh ).m_flAccumulatedMouseXMovement = 0; GetPerUser( hh ).m_flAccumulatedMouseYMovement = 0; } } }
/* ============================== CAM_StartDistance routines to start the process of moving the cam in or out using the mouse ============================== */ void CASWInput::CAM_StartDistance(void) { // asw GetPerUser().m_fCameraDistanceMove=false; GetPerUser().m_fCameraMovingWithMouse=false; GetPerUser().m_fCameraInterceptingMouse=false; }
void CASWInput::CAM_Think( void ) { Assert( engine->IsLocalPlayerResolvable() ); UpdateOrderArrow(); // update the arrow direction if we're in the middle of ordering a marine (see in_main.cpp) switch( GetPerUser().m_nCamCommand ) { case CAM_COMMAND_TOTHIRDPERSON: CAM_ToThirdPerson(); break; case CAM_COMMAND_TOFIRSTPERSON: CAM_ToFirstPerson(); break; case CAM_COMMAND_NONE: default: break; } if( !GetPerUser().m_fCameraInThirdPerson ) return; GetPerUser().m_vecCameraOffset[ PITCH ] = ASW_GetCameraPitch(); GetPerUser().m_vecCameraOffset[ YAW ] = ASW_GetCameraYaw(); GetPerUser().m_vecCameraOffset[ DIST ] = 0; }
//----------------------------------------------------------------------------- // 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; for ( int hh = 0; hh < MAX_SPLITSCREEN_PLAYERS; ++hh ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( hh ); GetPerUser().m_flAccumulatedMouseXMovement = 0; GetPerUser().m_flAccumulatedMouseYMovement = 0; } }
//----------------------------------------------------------------------------- // Purpose: One-time initialization //----------------------------------------------------------------------------- void CInput::Init_Mouse (void) { if ( CommandLine()->FindParm("-nomouse" ) ) return; for ( int hh = 0; hh < MAX_SPLITSCREEN_PLAYERS; ++hh ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( hh ); GetPerUser().m_flPreviousMouseXPosition = 0.0f; GetPerUser().m_flPreviousMouseYPosition = 0.0f; } 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 { m_rgCheckMouseParam[ MOUSE_SPEED_FACTOR ] = true; } 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: AccumulateMouse //----------------------------------------------------------------------------- void CInput::AccumulateMouse( int nSlot ) { if( !cl_mouseenable.GetBool() ) { return; } if( !UsingMouselook( nSlot ) ) { return; } int w, h; engine->GetScreenSize( w, h ); // x,y = screen center 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 ); } //only accumulate mouse if we are not moving the camera with the mouse PerUserInput_t &user = GetPerUser( nSlot ); if ( !user.m_fCameraInterceptingMouse && vgui::surface()->IsCursorLocked() ) { //Assert( !vgui::surface()->IsCursorVisible() ); #ifdef WIN32 int current_posx, current_posy; GetMousePos(current_posx, current_posy); 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; #else #error #endif } }
//----------------------------------------------------------------------------- // Purpose: GetMouseDelta -- Filters the mouse and stores results in old position // Input : mx - // my - // *oldx - // *oldy - // *x - // *y - //----------------------------------------------------------------------------- void CInput::GetMouseDelta( int nSlot, float inmousex, float inmousey, float *pOutMouseX, float *pOutMouseY ) { // Apply filtering? static SplitScreenConVarRef s_m_filter( "m_filter" ); if ( s_m_filter.GetBool( nSlot ) ) { // Average over last two samples *pOutMouseX = ( inmousex + GetPerUser().m_flPreviousMouseXPosition ) * 0.5f; *pOutMouseY = ( inmousey + GetPerUser().m_flPreviousMouseYPosition ) * 0.5f; } else { *pOutMouseX = inmousex; *pOutMouseY = inmousey; } // Latch previous GetPerUser().m_flPreviousMouseXPosition = inmousex; GetPerUser().m_flPreviousMouseYPosition = inmousey; }
//----------------------------------------------------------------------------- // 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 - //----------------------------------------------------------------------------- void CInput::GetAccumulatedMouseDeltasAndResetAccumulators( int nSlot, float *mx, float *my ) { Assert( mx ); Assert( my ); PerUserInput_t &user = GetPerUser( nSlot ); *mx = user.m_flAccumulatedMouseXMovement; *my = user.m_flAccumulatedMouseYMovement; user.m_flAccumulatedMouseXMovement = 0; user.m_flAccumulatedMouseYMovement = 0; }
//----------------------------------------------------------------------------- // Purpose: ApplyMouse -- applies mouse deltas to CUserCmd // Input : viewangles - // *cmd - // mouse_x - // mouse_y - //----------------------------------------------------------------------------- void CInput::ApplyMouse( int nSlot, QAngle& viewangles, CUserCmd *cmd, float mouse_x, float mouse_y ) { 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()) ) { if ( CAM_IsThirdPerson() && thirdperson_platformer.GetInt() ) { 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 ); } } else { // Otherwize, use mouse to spin around vertical axis { viewangles[YAW] -= m_yaw.GetFloat() * mouse_x; } } } 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. if (!(in_strafe.GetPerUser( nSlot ).state & 1)) { if ( CAM_IsThirdPerson() && thirdperson_platformer.GetInt() ) { 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 ); } } else { { viewangles[PITCH] += m_pitch->GetFloat() * mouse_y; } // 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(); } } } 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; }
//----------------------------------------------------------------------------- // Purpose: Advanced joystick setup //----------------------------------------------------------------------------- void CInput::Joystick_Advanced( bool bSilent ) { m_fJoystickAdvancedInit = true; // called whenever an update is needed int i; DWORD dwTemp; if ( IsX360() ) { // Xbox always uses a joystick in_joystick.SetValue( 1 ); } for ( int hh = 0; hh < MAX_SPLITSCREEN_PLAYERS; ++hh ) { ACTIVE_SPLITSCREEN_PLAYER_GUARD( hh ); PerUserInput_t &user = GetPerUser(); // Initialize all the maps for ( i = 0; i < MAX_JOYSTICK_AXES; i++ ) { user.m_rgAxes[i].AxisMap = GAME_AXIS_NONE; user.m_rgAxes[i].ControlMap = JOY_ABSOLUTE_AXIS; } if ( !joy_advanced.GetBool() ) { // default joystick initialization // 2 axes only with joystick control user.m_rgAxes[JOY_AXIS_X].AxisMap = GAME_AXIS_YAW; user.m_rgAxes[JOY_AXIS_Y].AxisMap = GAME_AXIS_FORWARD; } else { if ( !bSilent && hh == 0 && Q_stricmp( joy_name.GetString(), "joystick") ) { // notify user of advanced controller Msg( "Using joystick '%s' configuration\n", joy_name.GetString() ); } static SplitScreenConVarRef s_joy_movement_stick( "joy_movement_stick" ); bool bJoyMovementStick = s_joy_movement_stick.GetBool( hh ); // advanced initialization here // data supplied by user via joy_axisn cvars dwTemp = ( bJoyMovementStick ) ? (DWORD)joy_advaxisu.GetInt() : (DWORD)joy_advaxisx.GetInt(); user.m_rgAxes[JOY_AXIS_X].AxisMap = dwTemp & 0x0000000f; user.m_rgAxes[JOY_AXIS_X].ControlMap = dwTemp & JOY_RELATIVE_AXIS; dwTemp = ( bJoyMovementStick ) ? (DWORD)joy_advaxisr.GetInt() : (DWORD)joy_advaxisy.GetInt(); user.m_rgAxes[JOY_AXIS_Y].AxisMap = dwTemp & 0x0000000f; user.m_rgAxes[JOY_AXIS_Y].ControlMap = dwTemp & JOY_RELATIVE_AXIS; dwTemp = (DWORD)joy_advaxisz.GetInt(); user.m_rgAxes[JOY_AXIS_Z].AxisMap = dwTemp & 0x0000000f; user.m_rgAxes[JOY_AXIS_Z].ControlMap = dwTemp & JOY_RELATIVE_AXIS; dwTemp = ( bJoyMovementStick ) ? (DWORD)joy_advaxisy.GetInt() : (DWORD)joy_advaxisr.GetInt(); user.m_rgAxes[JOY_AXIS_R].AxisMap = dwTemp & 0x0000000f; user.m_rgAxes[JOY_AXIS_R].ControlMap = dwTemp & JOY_RELATIVE_AXIS; dwTemp = ( bJoyMovementStick ) ? (DWORD)joy_advaxisx.GetInt() : (DWORD)joy_advaxisu.GetInt(); user.m_rgAxes[JOY_AXIS_U].AxisMap = dwTemp & 0x0000000f; user.m_rgAxes[JOY_AXIS_U].ControlMap = dwTemp & JOY_RELATIVE_AXIS; dwTemp = (DWORD)joy_advaxisv.GetInt(); user.m_rgAxes[JOY_AXIS_V].AxisMap = dwTemp & 0x0000000f; user.m_rgAxes[JOY_AXIS_V].ControlMap = dwTemp & JOY_RELATIVE_AXIS; if ( !bSilent ) { Msg( "Advanced joystick settings initialized for joystick %d\n------------\n", hh + 1 ); DescribeJoystickAxis( hh, "x axis", &user.m_rgAxes[JOY_AXIS_X] ); DescribeJoystickAxis( hh, "y axis", &user.m_rgAxes[JOY_AXIS_Y] ); DescribeJoystickAxis( hh, "z axis", &user.m_rgAxes[JOY_AXIS_Z] ); DescribeJoystickAxis( hh, "r axis", &user.m_rgAxes[JOY_AXIS_R] ); DescribeJoystickAxis( hh, "u axis", &user.m_rgAxes[JOY_AXIS_U] ); DescribeJoystickAxis( hh, "v axis", &user.m_rgAxes[JOY_AXIS_V] ); } } } #if defined( SWARM_DLL ) // If we have an xbox controller, load the cfg file if it hasn't been loaded. ConVarRef var( "joy_xcontroller_found" ); if ( var.IsValid() && var.GetBool() && in_joystick.GetBool() ) { if ( joy_xcontroller_cfg_loaded.GetBool() == false ) { if ( IsPC() ) { engine->ClientCmd( "exec 360controller_pc.cfg" ); } else if ( IsX360() ) { engine->ClientCmd( "exec 360controller_xbox.cfg" ); } joy_xcontroller_cfg_loaded.SetValue( 1 ); } } else if ( joy_xcontroller_cfg_loaded.GetBool() ) { engine->ClientCmd( "exec undo360controller.cfg" ); joy_xcontroller_cfg_loaded.SetValue( 0 ); } #else // SWARM_DLL if ( IsPC() ) { // If we have an xcontroller on the PC, load the cfg file if it hasn't been loaded. ConVarRef var( "joy_xcontroller_found" ); if ( var.IsValid() && var.GetBool() && in_joystick.GetBool() ) { if ( joy_xcontroller_cfg_loaded.GetBool() == false ) { engine->ClientCmd( "exec 360controller.cfg" ); joy_xcontroller_cfg_loaded.SetValue( 1 ); } } else if ( joy_xcontroller_cfg_loaded.GetBool() ) { engine->ClientCmd( "exec undo360controller.cfg" ); joy_xcontroller_cfg_loaded.SetValue( 0 ); } } #endif // SWARM_DLL }
/* ============================== CAM_StartMouseMove ============================== */ void CASWInput::CAM_StartMouseMove(void) { GetPerUser().m_fCameraMovingWithMouse=false; GetPerUser().m_fCameraInterceptingMouse=false; }
//----------------------------------------------------------------------------- // Purpose: MouseMove -- main entry point for applying mouse // Input : *cmd - //----------------------------------------------------------------------------- void CInput::MouseMove( int nSlot, CUserCmd *cmd ) { 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 if ( !GetPerUser( nSlot ).m_fCameraInterceptingMouse && g_pInputStackSystem->IsTopmostEnabledContext( m_hInputContext ) ) { // Sample mouse one more time AccumulateMouse( nSlot ); // Latch accumulated mouse movements and reset accumulators GetAccumulatedMouseDeltasAndResetAccumulators( nSlot, &mx, &my ); // Filter, etc. the delta values and place into mouse_x and mouse_y GetMouseDelta( nSlot, mx, my, &mouse_x, &mouse_y ); // Apply scaling factor ScaleMouse( nSlot, &mouse_x, &mouse_y ); // Let the client mode at the mouse input before it's used GetClientMode()->OverrideMouseInput( &mouse_x, &mouse_y ); // Add mouse X/Y movement to cmd ApplyMouse( nSlot, viewangles, cmd, mouse_x, mouse_y ); // Re-center the mouse. ResetMouse(); } // Store out the new viewangles. engine->SetViewAngles( viewangles ); }