Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

282 lines
8.6 KiB

  1. //===== Copyright 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose: Mouse input routines
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //===========================================================================//
  9. #if defined( WIN32 ) && !defined( _GAMECONSOLE )
  10. #define _WIN32_WINNT 0x0502
  11. #include <windows.h>
  12. #endif
  13. #ifdef OSX
  14. #include <Carbon/Carbon.h>
  15. #endif
  16. #include "hud.h"
  17. #include "cdll_int.h"
  18. #include "kbutton.h"
  19. #include "basehandle.h"
  20. #include "usercmd.h"
  21. #include "input.h"
  22. #include "iviewrender.h"
  23. #include "iclientmode.h"
  24. #include "tier0/icommandline.h"
  25. #include "vgui/ISurface.h"
  26. #include "vgui_controls/Controls.h"
  27. #include "vgui/Cursor.h"
  28. #include "cdll_client_int.h"
  29. #include "cdll_util.h"
  30. #include "tier1/convar_serverbounded.h"
  31. #include "inputsystem/iinputsystem.h"
  32. #include "inputsystem/iinputstacksystem.h"
  33. #include "ienginevgui.h"
  34. //Debugging for SteamController
  35. #include "engine/ivdebugoverlay.h"
  36. #include "clientsteamcontext.h"
  37. #if defined( _X360 )
  38. #include "xbox/xbox_win32stubs.h"
  39. #endif
  40. // memdbgon must be the last include file in a .cpp file!!!
  41. #include "tier0/memdbgon.h"
  42. extern ConVar cam_idealyaw;
  43. extern ConVar cam_idealpitch;
  44. extern ConVar thirdperson_platformer;
  45. extern ConVar cl_forwardspeed;
  46. extern ConVar cl_backspeed;
  47. extern ConVar cl_sidespeed;
  48. static ConVar sc_enable( "sc_enable","1.0", FCVAR_ARCHIVE | FCVAR_SS , "Enable SteamController" );
  49. static ConVar sc_yaw_sensitivity( "sc_yaw_sensitivity","1.0", FCVAR_ARCHIVE | FCVAR_SS , "SteamController yaw factor." );
  50. static ConVar sc_yaw_sensitivity_default( "sc_yaw_sensitivity_default","1.0", FCVAR_NONE );
  51. static ConVar sc_pitch_sensitivity( "sc_pitch_sensitivity","1.0", FCVAR_ARCHIVE | FCVAR_SS , "SteamController pitch factor." );
  52. static ConVar sc_pitch_sensitivity_default( "sc_pitch_sensitivity_default","1.0", FCVAR_NONE );
  53. void CInput::ApplySteamControllerCameraMove( QAngle& viewangles, CUserCmd *cmd, Vector2D vecPosition )
  54. {
  55. PerUserInput_t &user = GetPerUser();
  56. //roll the view angles so roll is 0 (the HL2 assumed state) and mouse adjustments are relative to the screen.
  57. //Assuming roll is unchanging, we want mouse left to translate to screen left at all times (same for right, up, and down)
  58. ConVarRef cl_pitchdown ( "cl_pitchdown" );
  59. ConVarRef cl_pitchup ( "cl_pitchup" );
  60. ConVarRef cl_mouselook_roll_compensation ( "cl_mouselook_roll_compensation" );
  61. if ( CAM_IsThirdPerson() /*&& thirdperson_platformer.GetInt()*/ )
  62. {
  63. if ( vecPosition.x )
  64. {
  65. // use the mouse to orbit the camera around the player, and update the idealAngle
  66. user.m_vecCameraOffset[ YAW ] -= vecPosition.x;
  67. cam_idealyaw.SetValue( user.m_vecCameraOffset[ YAW ] - viewangles[ YAW ] );
  68. }
  69. }
  70. else
  71. {
  72. // Otherwise, use mouse to spin around vertical axis
  73. viewangles[YAW] -= sc_yaw_sensitivity.GetFloat() * vecPosition.x;
  74. }
  75. if ( CAM_IsThirdPerson() && thirdperson_platformer.GetInt() )
  76. {
  77. if ( vecPosition.y )
  78. {
  79. // use the mouse to orbit the camera around the player, and update the idealAngle
  80. user.m_vecCameraOffset[ PITCH ] += vecPosition.y;
  81. cam_idealpitch.SetValue( user.m_vecCameraOffset[ PITCH ] - viewangles[ PITCH ] );
  82. // why doesn't this work??? CInput::AdjustYaw is why
  83. //cam_idealpitch.SetValue( cam_idealpitch.GetFloat() + m_pitch->GetFloat() * mouse_y );
  84. }
  85. }
  86. else
  87. {
  88. viewangles[PITCH] -= vecPosition.y;
  89. // Check pitch bounds
  90. viewangles[PITCH] = clamp ( viewangles[PITCH], -cl_pitchdown.GetFloat(), cl_pitchup.GetFloat() );
  91. }
  92. // Finally, add mouse state to usercmd.
  93. // NOTE: Does rounding to int cause any issues? ywb 1/17/04
  94. cmd->mousedx = (int)vecPosition.x;
  95. cmd->mousedy = (int)vecPosition.y;
  96. }
  97. static const char *g_ControllerDigitalGameActions[] = {
  98. "+attack", "+attack2", "+reload", "+jump", "+duck", "toggle_duck", "+use", "invnext", "invprev", "lastinv", "buymenu", "+showscores", "drop", "+speed", "slot1", "slot2", "slot3", "slot4", "slot5", "invnextgrenade", "invnextitem", "invnextnongrenade", "+voicerecord", "autobuy", "rebuy", "+lookatweapon",
  99. };
  100. struct ControllerDigitalActionState {
  101. const char* cmd;
  102. ControllerDigitalActionHandle_t handle;
  103. bool bState;
  104. bool bActive;
  105. };
  106. static ControllerDigitalActionState g_ControllerDigitalActionState[ARRAYSIZE(g_ControllerDigitalGameActions)];
  107. static ControllerAnalogActionHandle_t g_ControllerMoveHandle;
  108. static ControllerAnalogActionHandle_t g_ControllerCameraHandle;
  109. static bool InitControllerTables()
  110. {
  111. for ( int i = 0; i < ARRAYSIZE( g_ControllerDigitalGameActions ); ++i )
  112. {
  113. const char *action = g_ControllerDigitalGameActions[ i ];
  114. if ( *action == '+' )
  115. {
  116. ++action;
  117. }
  118. ControllerDigitalActionState& state = g_ControllerDigitalActionState[ i ];
  119. state.handle = steamapicontext->SteamController()->GetDigitalActionHandle( action );
  120. if ( i == 0 && state.handle == 0 )
  121. {
  122. return false;
  123. }
  124. state.cmd = g_ControllerDigitalGameActions[ i ];
  125. state.bState = false;
  126. }
  127. g_ControllerMoveHandle = steamapicontext->SteamController()->GetAnalogActionHandle( "Move" );
  128. g_ControllerCameraHandle = steamapicontext->SteamController()->GetAnalogActionHandle( "Camera" );
  129. return true;
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Purpose: SteamControllerMove -- main entry point for applying Steam Controller Movements
  133. // Input : *cmd -
  134. //-----------------------------------------------------------------------------
  135. void CInput::SteamControllerMove( float flFrametime, CUserCmd *cmd )
  136. {
  137. g_pInputSystem->SetSteamControllerMode( enginevgui->IsGameUIVisible() ? "MenuControls" : "GameControls" );
  138. if ( !steamapicontext || !steamapicontext->SteamController() )
  139. {
  140. return;
  141. }
  142. uint64 nControllerHandles[STEAM_CONTROLLER_MAX_COUNT];
  143. int nControllerCount = steamapicontext->SteamController()->GetConnectedControllers(nControllerHandles);
  144. if ( nControllerCount <= 0 )
  145. {
  146. return;
  147. }
  148. static bool bControllerTablesInitialized = false;
  149. if ( !bControllerTablesInitialized )
  150. {
  151. bControllerTablesInitialized = InitControllerTables();
  152. }
  153. if ( !bControllerTablesInitialized )
  154. {
  155. return;
  156. }
  157. // Look at all our digital actions
  158. for ( int i = 0; i < ARRAYSIZE( g_ControllerDigitalActionState ); ++i )
  159. {
  160. ControllerDigitalActionState& state = g_ControllerDigitalActionState[ i ];
  161. // Since we don't support split screen we just take the union of inputs of all
  162. // connected controllers if there are multiple connected.
  163. bool bState = false, bActive = false;
  164. for ( int nSlot = 0; nSlot < nControllerCount; ++nSlot )
  165. {
  166. ControllerDigitalActionData_t data = steamapicontext->SteamController()->GetDigitalActionData( nControllerHandles[ nSlot ], state.handle );
  167. bState = bState || data.bState;
  168. bActive = bActive || data.bActive;
  169. }
  170. if ( state.bActive && bState != state.bState )
  171. {
  172. if ( bState || state.cmd[0] == '+' )
  173. {
  174. char cmdbuf[128];
  175. Q_snprintf( cmdbuf, sizeof( cmdbuf ), "%s", state.cmd );
  176. if ( !bState )
  177. {
  178. cmdbuf[0] = '-';
  179. }
  180. engine->ClientCmd_Unrestricted( cmdbuf, true );
  181. IClientMode *clientMode = GetClientMode();
  182. if ( clientMode != NULL )
  183. {
  184. clientMode->KeyInput( bState ? true : false, STEAMCONTROLLER_SELECT, cmdbuf );
  185. }
  186. }
  187. }
  188. state.bState = bState;
  189. state.bActive = bActive && ( state.bActive || !state.bState );
  190. }
  191. if ( enginevgui->IsGameUIVisible() )
  192. return;
  193. //Handle movement based on controller data.
  194. for ( int nSlot = 0; nSlot < nControllerCount; ++nSlot )
  195. {
  196. ControllerAnalogActionData_t moveData = steamapicontext->SteamController()->GetAnalogActionData( nControllerHandles[ nSlot ], g_ControllerMoveHandle );
  197. if ( moveData.y > 0.0 )
  198. {
  199. cmd->forwardmove += cl_forwardspeed.GetFloat() * moveData.y;
  200. }
  201. else
  202. {
  203. cmd->forwardmove += cl_backspeed.GetFloat() * moveData.y;
  204. }
  205. cmd->sidemove += cl_sidespeed.GetFloat() * moveData.x;
  206. }
  207. // Now work out if we should change camera direction
  208. QAngle viewangles;
  209. engine->GetViewAngles( viewangles );
  210. view->StopPitchDrift();
  211. for ( int nSlot = 0; nSlot < nControllerCount; ++nSlot )
  212. {
  213. ControllerAnalogActionData_t action = steamapicontext->SteamController()->GetAnalogActionData( nControllerHandles[ nSlot ], g_ControllerCameraHandle );
  214. float mouse_x = action.x;
  215. float mouse_y = action.y;
  216. ScaleMouse(0, &mouse_x, &mouse_y);
  217. Vector2D vecMouseDelta = Vector2D( mouse_x, -mouse_y )*0.015;
  218. ::g_pInputSystem->SetCurrentInputDevice( INPUT_DEVICE_STEAM_CONTROLLER );
  219. if ( vecMouseDelta.Length() > 0 )
  220. {
  221. m_bControllerMode = true;
  222. if ( !GetPerUser().m_fCameraInterceptingMouse && g_pInputStackSystem->IsTopmostEnabledContext( m_hInputContext ) )
  223. {
  224. ApplySteamControllerCameraMove( viewangles, cmd, vecMouseDelta );
  225. }
  226. }
  227. }
  228. engine->SetViewAngles( viewangles );
  229. }