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.

226 lines
6.2 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: TrackIR handling function
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #ifdef IS_WINDOWS_PC
  10. #include <windows.h>
  11. #endif
  12. #include "string_t.h"
  13. // These two have to be included very early
  14. #include <predictableid.h>
  15. #include <predictable_entity.h>
  16. #include "cdll_util.h"
  17. #include <util_shared.h>
  18. #include "vphysics_interface.h"
  19. #include <icvar.h>
  20. #include <baseentity_shared.h>
  21. #include "basehandle.h"
  22. #include "ehandle.h"
  23. #include "utlvector.h"
  24. #include "cdll_client_int.h"
  25. #include "kbutton.h"
  26. #include "usercmd.h"
  27. #include "iclientvehicle.h"
  28. #include "input.h"
  29. #include "iviewrender.h"
  30. #include "convar.h"
  31. #include "hud.h"
  32. #include "vgui/isurface.h"
  33. #include "vgui_controls/controls.h"
  34. #include "vgui/cursor.h"
  35. #include "tier0/icommandline.h"
  36. #include "inputsystem/iinputsystem.h"
  37. #include "inputsystem/ButtonCode.h"
  38. #include "math.h"
  39. #include "tier1/convar_serverbounded.h"
  40. // memdbgon must be the last include file in a .cpp file!!!
  41. #include "tier0/memdbgon.h"
  42. #ifdef IS_WINDOWS_PC
  43. #include "npsclient.h"
  44. #define TIR_MAX_VALUE 16383
  45. QAngle g_angleCenter;
  46. ConVar tir_maxyaw( "tir_maxyaw", "90", FCVAR_CHEAT, "TrackIR Max Yaw", true, 0.0, true, 180.0);
  47. ConVar tir_maxpitch( "tir_maxpitch", "15", FCVAR_CHEAT, "TrackIR Max Pitch", true, 0.0, true, 180.0);
  48. ConVar tir_maxroll( "tir_maxroll", "90", FCVAR_CHEAT, "TrackIR Max Roll", true, 0.0, true, 180.0);
  49. ConVar tir_maxx( "tir_maxx", "4", FCVAR_CHEAT, "TrackIR Max X", true, 0.0, true, 50.0);
  50. ConVar tir_maxy( "tir_maxy", "6", FCVAR_CHEAT, "TrackIR Max Y", true, 0.0, true, 50.0);
  51. ConVar tir_maxz( "tir_maxz", "1", FCVAR_CHEAT, "TrackIR Max Z", true, 0.0, true, 50.0);
  52. ConVar tir_start( "tir_start", "0", 0, "TrackIR Start", true, 0.0, true, 1.0);
  53. ConVar tir_stop( "tir_stop", "0", 0, "TrackIR Stop", true, 0.0, true, 1.0);
  54. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  55. {
  56. return DefWindowProc(hWnd, message, wParam, lParam);
  57. }
  58. HWND CreateHiddenWindow()
  59. {
  60. HWND hWnd;
  61. HINSTANCE hInstance = GetModuleHandle(NULL);
  62. WNDCLASSEX wcex;
  63. wcex.cbSize = sizeof(WNDCLASSEX);
  64. wcex.style = 0;
  65. wcex.lpfnWndProc = (WNDPROC)WndProc;
  66. wcex.cbClsExtra = 0;
  67. wcex.cbWndExtra = 0;
  68. wcex.hInstance = hInstance;
  69. wcex.hIcon = NULL;
  70. wcex.hCursor = NULL;
  71. wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  72. wcex.lpszMenuName = NULL;
  73. wcex.lpszClassName = TEXT("HL2-TrackIR");
  74. wcex.hIconSm = NULL;
  75. RegisterClassEx(&wcex);
  76. hWnd = CreateWindow(TEXT("HL2-TrackIR"), NULL, WS_OVERLAPPEDWINDOW,
  77. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
  78. if (hWnd)
  79. {
  80. ShowWindow(hWnd, SW_HIDE);
  81. UpdateWindow(hWnd);
  82. }
  83. return hWnd;
  84. }
  85. #endif
  86. //-----------------------------------------------------------------------------
  87. // Purpose: Init_TrackIR
  88. //-----------------------------------------------------------------------------
  89. void CInput::Init_TrackIR( void )
  90. {
  91. #ifdef IS_WINDOWS_PC
  92. if ( !IsHeadTrackingEnabled() )
  93. return;
  94. ZeroMemory(&g_angleCenter, sizeof(g_angleCenter));
  95. HWND hWnd = CreateHiddenWindow();
  96. NPRESULT result = NPS_Init(hWnd);
  97. // Mark the TrackIR as available and advanced initialization not completed
  98. // this is needed as correctly set cvars are not available this early during initialization
  99. // FIXME: Is this still the case?
  100. Msg( "TrackIR initialized [%d]\n", result );
  101. m_fTrackIRAvailable = true;
  102. #endif
  103. }
  104. //-----------------------------------------------------------------------------
  105. // Purpose: Init_TrackIR
  106. //-----------------------------------------------------------------------------
  107. void CInput::Shutdown_TrackIR( void )
  108. {
  109. #ifdef IS_WINDOWS_PC
  110. if ( !IsHeadTrackingEnabled() )
  111. return;
  112. NPS_Shutdown();
  113. Msg( "TrackIR shut down\n" );
  114. #endif
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose: Apply TrackIR to CUserCmd creation
  118. // Input : frametime -
  119. // *cmd -
  120. //-----------------------------------------------------------------------------
  121. void CInput::TrackIRMove( float frametime, CUserCmd *cmd )
  122. {
  123. #ifdef IS_WINDOWS_PC
  124. if ( !IsHeadTrackingEnabled() )
  125. return;
  126. // complete initialization if first time in ( needed as cvars are not available at initialization time )
  127. // verify TrackIR is available and that the user wants to use it
  128. if (!m_fTrackIRAvailable )
  129. {
  130. return;
  131. }
  132. if (tir_start.GetFloat() == 1.0)
  133. {
  134. Init_TrackIR();
  135. tir_start.SetValue(0);
  136. }
  137. if (tir_stop.GetFloat() == 1.0)
  138. {
  139. Shutdown_TrackIR();
  140. tir_stop.SetValue(0);
  141. }
  142. // grab the data from the TrackIR
  143. TRACKIRDATA tid;
  144. NPRESULT result;
  145. // Go get the latest data
  146. result = NPS_GetData(&tid);
  147. if( NP_OK == result )
  148. {
  149. QAngle viewangles;
  150. QAngle engineview;
  151. // get the current player
  152. C_BasePlayer * pPlayer = C_BasePlayer::GetLocalPlayer();
  153. // calculate the amount of rotation from TrackIR
  154. viewangles[YAW] = g_angleCenter[YAW] + (tid.fNPYaw / (float) TIR_MAX_VALUE) * tir_maxyaw.GetFloat();
  155. viewangles[PITCH] = g_angleCenter[PITCH] + (tid.fNPPitch / (float) TIR_MAX_VALUE) * tir_maxpitch.GetFloat();
  156. viewangles[ROLL] = g_angleCenter[ROLL] + (tid.fNPRoll / (float) TIR_MAX_VALUE) * tir_maxroll.GetFloat() * -1.0;
  157. // get the direction the player is facing
  158. QAngle eyeAngle;
  159. eyeAngle = pPlayer->EyeAngles();
  160. // add in the head rotation
  161. eyeAngle += viewangles;
  162. // get the rotation matrix for the head
  163. matrix3x4_t mat;
  164. AngleMatrix( pPlayer->EyeAngles(), mat );
  165. // create a normalized vector based on the TIR input
  166. Vector tirForward, tirEye;
  167. tirForward.x = (tid.fNPZ / (float) TIR_MAX_VALUE) * -1;
  168. tirForward.y = (tid.fNPX / (float) TIR_MAX_VALUE);
  169. tirForward.z = (tid.fNPY / (float) TIR_MAX_VALUE);
  170. // now rotate the vector based on the eye angle
  171. VectorRotate(tirForward, mat, tirEye);
  172. // scale the translation vector
  173. tirEye.x *= tir_maxz.GetFloat();
  174. tirEye.y *= tir_maxx.GetFloat();
  175. tirEye.z *= tir_maxy.GetFloat();
  176. // save the values for later
  177. pPlayer->SetEyeOffset(tirEye);
  178. pPlayer->SetEyeAngleOffset(viewangles);
  179. cmd->headangles = viewangles;
  180. cmd->headoffset = tirEye;
  181. }
  182. #endif
  183. }