Team Fortress 2 Source Code as on 22/4/2020
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.

4276 lines
122 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. #ifndef _XBOX
  3. //#include <windows.h>
  4. #endif
  5. #include "cbase.h"
  6. #include "convar.h"
  7. #ifdef SIXENSE
  8. #include "in_buttons.h"
  9. #include "sixense/in_sixense.h"
  10. #include "sixense/sixense_convars_extern.h"
  11. #if !defined( HL2_CLIENT_DLL) && !defined( TF_CLIENT_DLL )
  12. #include "weapon_csbase.h"
  13. #endif
  14. #if defined( HL2_CLIENT_DLL )
  15. #include "c_basehlplayer.h"
  16. #endif
  17. #if defined( TF_CLIENT_DLL )
  18. #include "c_tf_player.h"
  19. #include "tf_weaponbase.h"
  20. #include "tf_weapon_sniperrifle.h"
  21. #include "tf_gamerules.h"
  22. #include "backpack_panel.h"
  23. #include "baseviewport.h"
  24. extern ConVar _cl_classmenuopen;
  25. extern const char *COM_GetModDirectory();
  26. #endif
  27. #if defined( CSTRIKE15 ) || defined (CSTRIKE_DLL)
  28. #include "c_cs_player.h"
  29. #endif
  30. #include <isixense.h>
  31. #include <sixense_math.hpp>
  32. #include <sixense_utils/interfaces.hpp>
  33. using sixenseMath::Vector2;
  34. using sixenseMath::Vector3;
  35. using sixenseMath::Vector4;
  36. using sixenseMath::Quat;
  37. using sixenseMath::Line;
  38. #if defined( WIN32 ) && !defined( _X360 )
  39. #define _WIN32_WINNT 0x0502
  40. #endif
  41. #include <winlite.h>
  42. #include "vgui/IVGui.h"
  43. #include "vgui/IInput.h"
  44. #include "vgui/ISurface.h"
  45. #include "vgui_controls/Label.h"
  46. #include "ienginevgui.h"
  47. #include "vgui_controls/ImagePanel.h"
  48. #include "flashlighteffect.h"
  49. #include "weapon_selection.h"
  50. #include "iinput.h"
  51. #include "game/client/iviewport.h"
  52. #include "filesystem.h"
  53. #include "sourcevr/isourcevirtualreality.h"
  54. #ifdef TF_CLIENT_DLL
  55. #include "tf_hud_menu_engy_build.h"
  56. #include "tf_hud_menu_engy_destroy.h"
  57. #include "tf_hud_menu_spy_disguise.h"
  58. #endif
  59. #ifdef PORTAL2
  60. #include "BasePanel.h"
  61. #include "usermessages.h"
  62. #include "cdll_int.h"
  63. #include "iclientmode.h"
  64. #include "c_gameinstructor.h"
  65. #include "glow_outline_effect.h"
  66. #include "portal2/vsixensevideohint.h"
  67. #include "portal2/basemodframe.h"
  68. #include "portal2/c_prop_weightedcube.h"
  69. #include "portal/c_portal_player.h"
  70. #include "c_weapon_portalgun.h"
  71. #include "radialmenu.h"
  72. #endif
  73. #ifdef CSTRIKE15
  74. #include "basepanel.h"
  75. #endif
  76. using sixenseMath::Plane;
  77. using sixenseMath::Vector3;
  78. matrix3x4_t ConvertMatrix( sixenseMath::Matrix4 ss_mat );
  79. static void SixenseSensitivityLevelChanged( IConVar *var, const char *pOldValue, float flOldValue );
  80. static void SixenseConvarChanged( IConVar *var, const char *pOldValue, float flOldValue );
  81. extern ConVar cl_forwardspeed;
  82. extern ConVar cl_sidespeed;
  83. #ifdef PORTAL2
  84. extern BaseModUI::SixenseVideoHint *_video_hint_panel;
  85. static SixenseBaseWarning *base_warning = NULL;
  86. #endif
  87. // sixense variables
  88. ConVar sixense_weapon_select_sensitivity( "sixense_weapon_select_sensitivity", "1.65", FCVAR_ARCHIVE );
  89. ConVar sixense_crouch_sensitivity( "sixense_crouch_sensitivity", "1.5", FCVAR_ARCHIVE );
  90. ConVar sixense_jump_sensitivity( "sixense_jump_sensitivity", "1.2", FCVAR_ARCHIVE );
  91. ConVar sixense_reload_sensitivity( "sixense_reload_sensitivity", "1.5", FCVAR_ARCHIVE );
  92. ConVar sixense_left_handed( "sixense_left_handed", "0", FCVAR_ARCHIVE );
  93. #ifdef PORTAL2
  94. ConVar sixense_scale_disables_jump_timer( "sixense_scale_disables_jump_timer", "1.0" );
  95. ConVar sixense_auto_one_to_one_enabled( "sixense_auto_one_to_one_enabled", "0", FCVAR_ARCHIVE );
  96. ConVar sixense_auto_one_to_one_center_z_bias( "sixense_auto_one_to_one_center_z_bias", "0", FCVAR_ARCHIVE );
  97. ConVar sixense_large_objects_lock_one_to_one( "sixense_large_objects_lock_one_to_one", "0", FCVAR_ARCHIVE );
  98. ConVar sixense_large_objects_lock_one_to_one_size( "sixense_large_objects_lock_one_to_one_size", "3.0", FCVAR_ARCHIVE );
  99. ConVar sixense_dist_one_to_one_enabled( "sixense_dist_one_to_one_enabled", "1", FCVAR_ARCHIVE );
  100. ConVar sixense_dist_one_to_one_dist( "sixense_dist_one_to_one_dist", "65", FCVAR_ARCHIVE );
  101. ConVar sixense_dist_one_to_one_end_ratchet_delay( "sixense_dist_one_to_one_end_ratchet_delay", "0.05", FCVAR_ARCHIVE );
  102. ConVar sixense_pickup_momentary_time( "sixense_pickup_momentary_time", "45", FCVAR_ARCHIVE );
  103. ConVar sixense_auto_one_to_one_start_vel( "sixense_auto_one_to_one_start_vel", "550.0f", FCVAR_ARCHIVE );
  104. ConVar sixense_auto_one_to_one_start_accel( "sixense_auto_one_to_one_start_accel", "2500.0f", FCVAR_ARCHIVE );
  105. ConVar sixense_auto_one_to_one_start_accel_timer( "sixense_auto_one_to_one_start_accel_timer", "800", FCVAR_ARCHIVE );
  106. ConVar sixense_auto_one_to_one_angle_thresh( "sixense_auto_one_to_one_angle_thresh", "0.5235f", FCVAR_ARCHIVE );
  107. ConVar sixense_auto_one_to_one_stop_xy_dist( "sixense_auto_one_to_one_stop_xy_dist", "100", FCVAR_ARCHIVE );
  108. ConVar sixense_auto_one_to_one_stop_z_dist( "sixense_auto_one_to_one_stop_z_dist", "10.0f", FCVAR_ARCHIVE );
  109. ConVar sixense_hold_spin_start_screen_ratio( "sixense_hold_spin_start_screen_ratio", "0.5", FCVAR_ARCHIVE );
  110. ConVar sixense_hold_spin_speed( "sixense_hold_spin_speed", "1.0", FCVAR_ARCHIVE );
  111. ConVar sixense_hold_spin_speed_bias( "sixense_hold_spin_speed_bias", "0.2", FCVAR_ARCHIVE );
  112. ConVar sixense_hold_spin_fade_min_dist( "sixense_hold_spin_fade_min_dist", "0.0", FCVAR_ARCHIVE );
  113. ConVar sixense_hold_spin_fade_max_dist( "sixense_hold_spin_fade_max_dist", "0.0", FCVAR_ARCHIVE );
  114. ConVar sixense_hold_spin_damp( "sixense_hold_spin_damp", "0.95", FCVAR_ARCHIVE, "dampening for camera panning, 0 is no dampening" );
  115. ConVar sixense_hold_spin_max_angle( "sixense_hold_spin_max_angle", "75", FCVAR_ARCHIVE, "disallow camera tracking if the held object is greater than this angle relative to the players view" );
  116. ConVar sixense_hold_slide_z_min_dist( "sixense_hold_slide_z_min_dist", "20.0f", FCVAR_ARCHIVE );
  117. ConVar sixense_hold_slide_xy_radius( "sixense_hold_slide_xy_radius", "80.0f", FCVAR_ARCHIVE );
  118. ConVar sixense_played_tutorial("sixense_played_tutorial", "0", FCVAR_ARCHIVE);
  119. #endif
  120. // 0 = low, 1 = med, 2 = high, 3 = custom
  121. ConVar sixense_sensitivity_level( "sixense_sensitivity_level", "-1", FCVAR_ARCHIVE );
  122. ConVar sixense_controller_angle_mode( "sixense_controller_angle_mode", "0.0f", FCVAR_ARCHIVE );
  123. ConVar sixense_roll_correct_blend( "sixense_roll_correct_blend", "0.965f", FCVAR_ARCHIVE );
  124. ConVar sixense_exit_one_to_one_dot( "sixense_exit_one_to_one_dot", "0.85", FCVAR_ARCHIVE );
  125. ConVar sixense_exit_metroid_blend( "sixense_exit_metroid_blend", "0.95f", FCVAR_ARCHIVE );
  126. ConVar sixense_max_charge_spin( "sixense_max_charge_spin", "3.0f", FCVAR_ARCHIVE );
  127. ConVar sixense_zoom_momentary_time( "sixense_zoom_momentary_time", "500", FCVAR_ARCHIVE );
  128. ConVar sixense_base_offset_x( "sixense_base_offset_x", "0.0", FCVAR_ARCHIVE );
  129. ConVar sixense_base_offset_y( "sixense_base_offset_y", "0.0", FCVAR_ARCHIVE );
  130. ConVar sixense_base_offset_z( "sixense_base_offset_z", "-20.0", FCVAR_ARCHIVE );
  131. ConVar sixense_trigger_threshold( "sixense_trigger_threshold", "0.05", FCVAR_ARCHIVE );
  132. ConVar sixense_tilt_gesture_angle_threshold( "sixense_tilt_gesture_angle_threshold", "35.0", FCVAR_ARCHIVE );
  133. ConVar sixense_point_gesture_angle_threshold( "sixense_point_gesture_angle_threshold", "15.0", FCVAR_ARCHIVE );
  134. ConVar sixense_mouse_enabled( "sixense_mouse_enabled", "1.0",FCVAR_ARCHIVE );
  135. ConVar sixense_mouse_sensitivity( "sixense_mouse_sensitivity", "1.0", FCVAR_ARCHIVE );
  136. ConVar sixense_spring_view_enabled( "sixense_spring_view_enabled", "1.0f", FCVAR_ARCHIVE );
  137. ConVar sixense_spring_view_min_spring( "sixense_spring_view_min_spring", "0.025f", FCVAR_ARCHIVE );
  138. ConVar sixense_spring_view_max_spring( "sixense_spring_view_max_spring", "0.9999f", FCVAR_ARCHIVE );
  139. ConVar sixense_spring_view_min_angle( "sixense_spring_view_min_angle", "1.0f", FCVAR_ARCHIVE );
  140. ConVar sixense_spring_view_max_angle( "sixense_spring_view_max_angle", "45.0f", FCVAR_ARCHIVE );
  141. // mode 0:
  142. ConVar sixense_aim_freeaim_heading_multiplier( "sixense_aim_freeaim_heading_multiplier", "1.5", FCVAR_ARCHIVE );
  143. ConVar sixense_aim_freeaim_pitch_multiplier( "sixense_aim_freeaim_pitch_multiplier", "1.5", FCVAR_ARCHIVE );
  144. ConVar sixense_aim_freeaim_dead_zone_radius( "sixense_aim_freeaim_dead_zone_radius", "0.25", FCVAR_ARCHIVE );
  145. ConVar sixense_aim_freeaim_accel_band_size( "sixense_aim_freeaim_accel_band_size", "20.0", FCVAR_ARCHIVE );
  146. ConVar sixense_aim_freeaim_max_speed( "sixense_aim_freeaim_max_speed", "7.0", FCVAR_ARCHIVE );
  147. ConVar sixense_aim_freeaim_auto_level_rate( "sixense_aim_freeaim_auto_level_rate", "1.0", FCVAR_ARCHIVE );
  148. ConVar sixense_aim_freeaim_accel_band_exponent( "sixense_aim_freeaim_accel_band_exponent", "1.0", FCVAR_ARCHIVE );
  149. ConVar sixense_aim_freeaim_switch_blend_time_enter( "sixense_aim_freeaim_switch_blend_time_enter", "0.5", FCVAR_CHEAT );
  150. ConVar sixense_aim_freeaim_switch_blend_time_exit( "sixense_aim_freeaim_switch_blend_time_exit", "0.25", FCVAR_ARCHIVE );
  151. ConVar sixense_teleport_metroid_blend_time( "sixense_teleport_metroid_blend_time", "3.0", FCVAR_CHEAT );
  152. ConVar sixense_teleport_wait_to_blend_time( "sixense_teleport_wait_to_blend_time", "0.75", FCVAR_CHEAT );
  153. // mode 1:
  154. ConVar sixense_aim_1to1_ratchet_vertical( "sixense_aim_1to1_ratchet_vertical", "1.0", FCVAR_ARCHIVE );
  155. ConVar sixense_aim_1to1_heading_multiplier( "sixense_aim_1to1_heading_multiplier", "3.0", FCVAR_ARCHIVE );
  156. ConVar sixense_aim_1to1_pitch_multiplier( "sixense_aim_1to1_pitch_multiplier", "2.0", FCVAR_ARCHIVE );
  157. ConVar sixense_feet_angles_offset_stick_spin_horiz_multiplier( "sixense_feet_angles_offset_stick_spin_horiz_multiplier", "4.0", FCVAR_ARCHIVE );
  158. ConVar sixense_feet_angles_offset_stick_spin_vert_multiplier( "sixense_feet_angles_offset_stick_spin_vert_multiplier", "2.0", FCVAR_ARCHIVE );
  159. ConVar sixense_feet_angles_offset_stick_spin_invert_pitch( "sixense_feet_angles_offset_stick_spin_invert_pitch", "1.0", FCVAR_ARCHIVE );
  160. ConVar sixense_feet_angles_offset_stick_spin_exponent( "sixense_feet_angles_offset_stick_spin_exponent", "1.0", FCVAR_ARCHIVE );
  161. ConVar sixense_aim_scope_heading_multiplier( "sixense_aim_scope_heading_multiplier", "0.6", FCVAR_ARCHIVE );
  162. ConVar sixense_aim_scope_pitch_multiplier( "sixense_aim_scope_pitch_multiplier", "0.6", FCVAR_ARCHIVE );
  163. ConVar sixense_melee_pitch_blend_val( "sixense_melee_pitch_blend_val", "0.99", FCVAR_ARCHIVE );
  164. ConVar sixense_crosshair_horiz_multiplier( "sixense_crosshair_horiz_multiplier", "1.0", FCVAR_ARCHIVE );
  165. ConVar sixense_crosshair_vert_multiplier( "sixense_crosshair_vert_multiplier", "1.0", FCVAR_ARCHIVE );
  166. ConVar sixense_always_draw_crosshair( "sixense_always_draw_crosshair", "1", FCVAR_ARCHIVE );
  167. // walking
  168. ConVar sixense_walking_dead_zone_percent( "sixense_walking_dead_zone_percent", "10.0", FCVAR_ARCHIVE );
  169. ConVar sixense_walking_exponent( "sixense_walking_exponent", "1.0", FCVAR_ARCHIVE );
  170. SixenseGUIFrame *SixenseInput::m_SixenseFrame = NULL;
  171. SixenseInput *g_pSixenseInput = NULL;
  172. CSysModule *g_pSixenseModule = NULL;
  173. CSysModule *g_pSixenseUtilsModule = NULL;
  174. // A bunch of our convars have their values pushed down into the sixense_utils lib, so install a handler on each
  175. // to let us know if there are any changes
  176. void SixenseInput::InstallConvarCallbacks()
  177. {
  178. sixense_mode.InstallChangeCallback( SixenseConvarChanged );
  179. sixense_weapon_select_sensitivity.InstallChangeCallback( SixenseConvarChanged );
  180. sixense_crouch_sensitivity.InstallChangeCallback( SixenseConvarChanged );
  181. sixense_jump_sensitivity.InstallChangeCallback( SixenseConvarChanged );
  182. sixense_reload_sensitivity.InstallChangeCallback( SixenseConvarChanged );
  183. sixense_controller_angle_mode.InstallChangeCallback( SixenseConvarChanged );
  184. sixense_aim_freeaim_heading_multiplier.InstallChangeCallback( SixenseConvarChanged );
  185. sixense_aim_freeaim_pitch_multiplier.InstallChangeCallback( SixenseConvarChanged );
  186. sixense_aim_freeaim_dead_zone_radius.InstallChangeCallback( SixenseConvarChanged );
  187. sixense_aim_freeaim_accel_band_size.InstallChangeCallback( SixenseConvarChanged );
  188. sixense_aim_freeaim_auto_level_rate.InstallChangeCallback( SixenseConvarChanged );
  189. sixense_aim_freeaim_accel_band_exponent.InstallChangeCallback( SixenseConvarChanged );
  190. #ifdef PORTAL2
  191. sixense_auto_one_to_one_start_vel.InstallChangeCallback( SixenseConvarChanged );
  192. sixense_auto_one_to_one_start_accel.InstallChangeCallback( SixenseConvarChanged );
  193. sixense_auto_one_to_one_start_accel_timer.InstallChangeCallback( SixenseConvarChanged );
  194. sixense_auto_one_to_one_angle_thresh.InstallChangeCallback( SixenseConvarChanged );
  195. sixense_auto_one_to_one_stop_xy_dist.InstallChangeCallback( SixenseConvarChanged );
  196. sixense_auto_one_to_one_stop_z_dist.InstallChangeCallback( SixenseConvarChanged );
  197. #endif
  198. sixense_aim_freeaim_switch_blend_time_exit.InstallChangeCallback( SixenseConvarChanged );
  199. sixense_roll_correct_blend.InstallChangeCallback( SixenseConvarChanged );
  200. sixense_exit_metroid_blend.InstallChangeCallback( SixenseConvarChanged );
  201. sixense_spring_view_min_spring.InstallChangeCallback( SixenseConvarChanged );
  202. sixense_spring_view_max_spring.InstallChangeCallback( SixenseConvarChanged );
  203. sixense_spring_view_min_angle.InstallChangeCallback( SixenseConvarChanged );
  204. sixense_spring_view_max_angle.InstallChangeCallback( SixenseConvarChanged );
  205. sixense_melee_pitch_blend_val.InstallChangeCallback( SixenseConvarChanged );
  206. sixense_aim_1to1_ratchet_vertical.InstallChangeCallback( SixenseConvarChanged );
  207. sixense_aim_1to1_heading_multiplier.InstallChangeCallback( SixenseConvarChanged );
  208. sixense_aim_1to1_pitch_multiplier.InstallChangeCallback( SixenseConvarChanged );
  209. sixense_spring_view_enabled.InstallChangeCallback( SixenseConvarChanged );
  210. sixense_feet_angles_offset_stick_spin_horiz_multiplier.InstallChangeCallback( SixenseConvarChanged );
  211. sixense_feet_angles_offset_stick_spin_vert_multiplier.InstallChangeCallback( SixenseConvarChanged );
  212. sixense_feet_angles_offset_stick_spin_invert_pitch.InstallChangeCallback( SixenseConvarChanged );
  213. sixense_feet_angles_offset_stick_spin_exponent.InstallChangeCallback( SixenseConvarChanged );
  214. sixense_walking_dead_zone_percent.InstallChangeCallback( SixenseConvarChanged );
  215. sixense_walking_exponent.InstallChangeCallback( SixenseConvarChanged );
  216. sixense_tilt_gesture_angle_threshold.InstallChangeCallback( SixenseConvarChanged );
  217. sixense_point_gesture_angle_threshold.InstallChangeCallback( SixenseConvarChanged );
  218. sixense_trigger_threshold.InstallChangeCallback( SixenseConvarChanged );
  219. sixense_aim_scope_heading_multiplier.InstallChangeCallback( SixenseConvarChanged );
  220. }
  221. // If any of the interesting convars changed this frame, this call will push all the values to where they need to be.
  222. void SixenseInput::UpdateValuesFromConvars()
  223. {
  224. if( !m_pFPSEvents )
  225. {
  226. return;
  227. }
  228. int mode = sixense_mode.GetInt();
  229. if ( mode < 0 || mode > 2 )
  230. {
  231. mode = 0;
  232. }
  233. SetMode( mode );
  234. // Set all the parameters from the cvars
  235. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::WEAPON_SELECT_SENSITIVITY, sixense_weapon_select_sensitivity.GetFloat() );
  236. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::CROUCH_SENSITIVITY, sixense_crouch_sensitivity.GetFloat() );
  237. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::JUMP_SENSITIVITY, sixense_jump_sensitivity.GetFloat() );
  238. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::RELOAD_SENSITIVITY, sixense_reload_sensitivity.GetFloat() );
  239. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::CONTROLLER_ANGLE_MODE, sixense_controller_angle_mode.GetFloat() );
  240. #ifdef PORTAL2
  241. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::AUTO_ONE_TO_ONE_START_VEL, sixense_auto_one_to_one_start_vel.GetFloat() );
  242. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::AUTO_ONE_TO_ONE_START_ACCEL, sixense_auto_one_to_one_start_accel.GetFloat() );
  243. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::AUTO_ONE_TO_ONE_START_ACCEL_TIMER, sixense_auto_one_to_one_start_accel_timer.GetFloat() );
  244. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::AUTO_ONE_TO_ONE_START_ANGLE_THRESH, sixense_auto_one_to_one_angle_thresh.GetFloat() );
  245. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::AUTO_ONE_TO_ONE_STOP_XY_DIST, sixense_auto_one_to_one_stop_xy_dist.GetFloat() );
  246. m_pFPSEvents->setParameter( sixenseUtils::IFPSEvents::AUTO_ONE_TO_ONE_STOP_Z_DIST, sixense_auto_one_to_one_stop_z_dist.GetFloat() );
  247. #endif
  248. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_HEADING_MULTIPLIER, sixense_aim_freeaim_heading_multiplier.GetFloat() );
  249. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_PITCH_MULTIPLIER, sixense_aim_freeaim_pitch_multiplier.GetFloat() );
  250. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_DEAD_ZONE_RADIUS, sixense_aim_freeaim_dead_zone_radius.GetFloat() );
  251. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_ACCEL_BAND_SIZE, sixense_aim_freeaim_accel_band_size.GetFloat() );
  252. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_AUTO_LEVEL_RATE, sixense_aim_freeaim_auto_level_rate.GetFloat() );
  253. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_ACCEL_BAND_EXPONENT, sixense_aim_freeaim_accel_band_exponent.GetFloat() );
  254. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_SWITCH_BLEND_TIME_EXIT, sixense_aim_freeaim_switch_blend_time_exit.GetFloat() );
  255. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::CONTROLLER_ANGLE_MODE, sixense_controller_angle_mode.GetFloat() );
  256. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::ROLL_CORRECTION_BLEND, sixense_roll_correct_blend.GetFloat() );
  257. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::EXIT_METROID_BLEND, sixense_exit_metroid_blend.GetFloat() );
  258. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::SPRING_VIEW_MIN_SPRING, sixense_spring_view_min_spring.GetFloat() );
  259. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::SPRING_VIEW_MAX_SPRING, sixense_spring_view_max_spring.GetFloat() );
  260. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::SPRING_VIEW_MIN_ANGLE, sixense_spring_view_min_angle.GetFloat() );
  261. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::SPRING_VIEW_MAX_ANGLE, sixense_spring_view_max_angle.GetFloat() );
  262. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::PITCH_CHANGE_BLEND_VAL, sixense_melee_pitch_blend_val.GetFloat() );
  263. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_1TO1_RATCHET_VERTICAL, sixense_aim_1to1_ratchet_vertical.GetFloat() );
  264. // In metroid mode, we switch into mouselook when looking down scope, so configure mouselook differently.
  265. if( sixense_mode.GetInt() == 1 )
  266. {
  267. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_1TO1_HEADING_MULTIPLIER, sixense_aim_1to1_heading_multiplier.GetFloat() );
  268. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_1TO1_PITCH_MULTIPLIER, sixense_aim_1to1_pitch_multiplier.GetFloat() );
  269. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::SPRING_VIEW_ENABLED, sixense_spring_view_enabled.GetFloat() );
  270. }
  271. else if( sixense_mode.GetInt() == 0 )
  272. {
  273. // Use scope sensitivites in metroid mode, so when we look down the scope it's set correctly
  274. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_1TO1_HEADING_MULTIPLIER, sixense_aim_scope_heading_multiplier.GetFloat() );
  275. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_1TO1_PITCH_MULTIPLIER, sixense_aim_scope_pitch_multiplier.GetFloat() );
  276. // No springview when looking down scope
  277. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::SPRING_VIEW_ENABLED, 0 );
  278. }
  279. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::FEET_ANGLES_OFFSET_STICK_SPIN_HORIZ_MULTIPLIER, sixense_feet_angles_offset_stick_spin_horiz_multiplier.GetFloat() );
  280. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::FEET_ANGLES_OFFSET_STICK_SPIN_VERT_MULTIPLIER, sixense_feet_angles_offset_stick_spin_vert_multiplier.GetFloat() );
  281. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::FEET_ANGLES_OFFSET_STICK_SPIN_INVERT_PITCH, sixense_feet_angles_offset_stick_spin_invert_pitch.GetFloat() );
  282. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::FEET_ANGLES_OFFSET_STICK_SPIN_EXPONENT, sixense_feet_angles_offset_stick_spin_exponent.GetFloat() );
  283. m_pFPSPlayerMovement->setParameter( sixenseUtils::IFPSPlayerMovement::DEAD_ZONE_PERCENT, sixense_walking_dead_zone_percent.GetFloat() );
  284. m_pFPSPlayerMovement->setParameter( sixenseUtils::IFPSPlayerMovement::EXPONENTIAL, sixense_walking_exponent.GetFloat() );
  285. m_pLeftButtonStates->setAbsoluteTiltAngleThresholdInDeg( sixense_tilt_gesture_angle_threshold.GetFloat() );
  286. m_pLeftButtonStates->setRelativeTiltAngleThresholdInDeg( sixense_point_gesture_angle_threshold.GetFloat() );
  287. m_pLeftButtonStates->setTriggerThreshold( sixense_trigger_threshold.GetFloat() );
  288. m_pRightButtonStates->setTriggerThreshold( sixense_trigger_threshold.GetFloat() );
  289. }
  290. // Try to load sixense.dll and sixense_utils.dll
  291. bool SixenseInput::LoadModules()
  292. {
  293. // If the modules are already loaded return success
  294. if( m_bModulesLoaded )
  295. return true;
  296. // Try to load the sixense DLLs
  297. g_pSixenseModule = Sys_LoadModule( "sixense" );
  298. if( !g_pSixenseModule )
  299. {
  300. Msg("Failed to load sixense.dll\n");
  301. return false;
  302. }
  303. g_pSixenseUtilsModule = Sys_LoadModule( "sixense_utils" );
  304. if( !g_pSixenseUtilsModule )
  305. {
  306. Msg("Failed to load sixense_utils.dll\n");
  307. return false;
  308. }
  309. Msg("Successfully loaded sixense modules.\n");
  310. bool found_objects = false;
  311. if(g_pSixenseModule)
  312. {
  313. CreateInterfaceFn factory = Sys_GetFactory( g_pSixenseModule );
  314. if( factory )
  315. {
  316. m_pSixenseAPI = reinterpret_cast< ISixenseAPI* >( factory( "SixenseAPI", NULL ) );
  317. if( m_pSixenseAPI )
  318. {
  319. found_objects = true;
  320. }
  321. }
  322. }
  323. if( !found_objects )
  324. {
  325. Msg("Failed to find factory in sixense.dll\n");
  326. return false;
  327. }
  328. // Now try to init from sixense_utils
  329. found_objects = false;
  330. if(g_pSixenseUtilsModule)
  331. {
  332. CreateInterfaceFn factory = Sys_GetFactory( g_pSixenseUtilsModule );
  333. if( factory )
  334. {
  335. m_pFPSViewAngles = reinterpret_cast< sixenseUtils::IFPSViewAngles* >( factory( "FPSViewAngles0", NULL ) );
  336. m_pFPSPlayerMovement = reinterpret_cast< sixenseUtils::IFPSPlayerMovement* >( factory( "FPSPlayerMovement0", NULL ) );
  337. m_pFPSEvents = reinterpret_cast< sixenseUtils::IFPSEvents* >( factory( "FPSEvents0", NULL ) );
  338. m_pLaserPointer = reinterpret_cast< sixenseUtils::ILaserPointer* >( factory( "LaserPointer0", NULL ) );
  339. m_pLeftDeriv = reinterpret_cast< sixenseUtils::IDerivatives* >( factory( "Derivatives0", NULL ) );
  340. m_pRightDeriv = reinterpret_cast< sixenseUtils::IDerivatives* >( factory( "Derivatives1", NULL ) );
  341. m_pLeftButtonStates = reinterpret_cast< sixenseUtils::IButtonStates* >( factory( "ButtonStates0", NULL ) );
  342. m_pRightButtonStates = reinterpret_cast< sixenseUtils::IButtonStates* >( factory( "ButtonStates1", NULL ) );
  343. m_pControllerManager = reinterpret_cast< sixenseUtils::IControllerManager* >( factory( "ControllerManager", NULL ) );
  344. if( m_pFPSViewAngles && m_pFPSPlayerMovement && m_pFPSEvents && m_pLaserPointer && m_pLeftDeriv &&
  345. m_pRightDeriv && m_pLeftButtonStates && m_pRightButtonStates && m_pControllerManager )
  346. {
  347. found_objects = true;
  348. }
  349. }
  350. }
  351. if( !found_objects )
  352. {
  353. Msg("Failed to find factory in sixense_utils.dll\n");
  354. return false;
  355. }
  356. m_bModulesLoaded = true;
  357. Init();
  358. // We can't set the mode until modules are loaded, so do it now
  359. SetMode( sixense_mode.GetInt() );
  360. return true;
  361. }
  362. bool SixenseInput::UnloadModules()
  363. {
  364. if( g_pSixenseModule )
  365. {
  366. Sys_UnloadModule( g_pSixenseModule );
  367. g_pSixenseModule = NULL;
  368. }
  369. if( g_pSixenseUtilsModule )
  370. {
  371. Sys_UnloadModule( g_pSixenseUtilsModule );
  372. g_pSixenseUtilsModule = NULL;
  373. }
  374. m_bModulesLoaded = false;
  375. Shutdown();
  376. return true;
  377. }
  378. #if 0
  379. static void update_controller_manager_visibility( sixenseAllControllerData *acd )
  380. {
  381. if( !SixenseInput::m_SixenseFrame ) return;
  382. bool controllers_docked = acd->controllers[0].is_docked || acd->controllers[1].is_docked;
  383. bool power_up_screens_showing = false;
  384. // It's ok for there to be no device plugged in, don't show the controller manager in that case
  385. std::string current_step = m_pControllerManager->getTextureFileName();
  386. if( current_step == "1P2C/p1c2_power_up_0.tif" || current_step == "1P2C/p1c2_power_up_1.tif" )
  387. {
  388. power_up_screens_showing = true;
  389. }
  390. //Msg("current step %s\n", current_step.c_str() );
  391. // if sixense is enabled, and the cm is trying to say something, and it's not trying to show the power up screens, and the controllers arent docked show the frame
  392. if( g_pSixenseInput->IsEnabled() &&
  393. m_pControllerManager->isMenuVisible() &&
  394. !power_up_screens_showing &&
  395. !controllers_docked )
  396. {
  397. if( !SixenseInput::m_SixenseFrame->IsVisible() )
  398. {
  399. SixenseInput::m_SixenseFrame->SetVisible( true );
  400. SixenseInput::m_SixenseFrame->MoveToFront();
  401. // Pause the engine if we can...
  402. engine->ClientCmd_Unrestricted( "setpause nomsg" );
  403. }
  404. }
  405. else
  406. {
  407. if( SixenseInput::m_SixenseFrame->IsVisible() ) // otherwise turn it off
  408. {
  409. SixenseInput::m_SixenseFrame->SetVisible( false );
  410. engine->ClientCmd_Unrestricted( "unpause nomsg" );
  411. }
  412. }
  413. }
  414. #endif
  415. static void controller_manager_setup_callback( sixenseUtils::IControllerManager::setup_step SetupStep )
  416. {
  417. g_pSixenseInput->controllerManagerCallback( (int)SetupStep );
  418. }
  419. void SixenseInput::controllerManagerCallback( int iSetupStep )
  420. {
  421. #if 0
  422. Msg( "controller_manager_setup_callback: %s\n", m_pControllerManager->getTextureFileName() );
  423. if ( m_pControllerManager->isMenuVisible() )
  424. {
  425. if ( SixenseInput::m_SixenseFrame )
  426. {
  427. sixenseUtils::sixense_utils_string tex_name = m_pControllerManager->getTextureFileName();
  428. std::string image_name( tex_name.begin(), tex_name.end() );
  429. image_name = image_name.substr( image_name.find_last_of( '/' ) );
  430. image_name = image_name.substr( 0, image_name.find_first_of( '.' ) );
  431. CUtlString cm_str( "../sixense_controller_manager" );
  432. cm_str.Append( image_name.c_str() );
  433. SixenseInput::m_SixenseFrame->setImage( cm_str );
  434. }
  435. }
  436. if ( m_pControllerManager->shouldPlaySound() == sixenseUtils::IControllerManager::SUCCESS_BEEP )
  437. {
  438. vgui::surface()->PlaySound( "UI/buttonclickrelease.wav" );
  439. }
  440. #endif
  441. }
  442. #ifdef PORTAL2
  443. ConCommand sixense_reset_view( "sixense_reset_view", reset_view );
  444. static void reset_view( const CCommand &args )
  445. {
  446. if ( args.ArgC() != 4 )
  447. {
  448. Warning( "Incorrect parameters. Format: sixense_reset_view <pitch> <yaw> <roll>\n" );
  449. return;
  450. }
  451. QAngle reset_angs;
  452. reset_angs[PITCH] = ( float )atof( args[1] );
  453. reset_angs[YAW] = ( float )atof( args[2] );
  454. reset_angs[ROLL] = ( float )atof( args[3] );
  455. g_pSixenseInput->ResetView( reset_angs );
  456. }
  457. static void SixenseAutosave( const CCommand &args )
  458. {
  459. if ( sixense_enabled.GetInt() )
  460. {
  461. const char szSaveName[32] = "autosave_motionpack";
  462. char szFullSaveFileName[32];
  463. char szComment[32];
  464. engine->SaveGame(
  465. szSaveName,
  466. IsX360(),
  467. szFullSaveFileName,
  468. sizeof( szFullSaveFileName ),
  469. szComment,
  470. sizeof( szComment ) );
  471. }
  472. }
  473. ConCommand sixense_autosave( "sixense_autosave", SixenseAutosave );
  474. #endif
  475. ////////////
  476. #define INPUT_EVENTS
  477. #ifdef INPUT_EVENTS
  478. static void sendMouseClick( int click, int release )
  479. {
  480. #ifdef WIN32
  481. // Set up the input event struct
  482. INPUT input_ev[1];
  483. input_ev[0].type = INPUT_MOUSE;
  484. PMOUSEINPUT mouse_evp;
  485. mouse_evp = &input_ev[0].mi;
  486. mouse_evp->dx = 0;
  487. mouse_evp->dy = 0;
  488. mouse_evp->time=0;
  489. if( click )
  490. {
  491. if( click == 1 )
  492. {
  493. mouse_evp->dwFlags = MOUSEEVENTF_LEFTDOWN;
  494. }
  495. else if( click == 2 )
  496. {
  497. mouse_evp->dwFlags = MOUSEEVENTF_RIGHTDOWN;
  498. }
  499. else if( click == 3 )
  500. {
  501. mouse_evp->dwFlags = MOUSEEVENTF_MIDDLEDOWN;
  502. }
  503. SendInput( 1, input_ev, sizeof( INPUT ) );
  504. }
  505. if( release )
  506. {
  507. if( release == 1 )
  508. {
  509. mouse_evp->dwFlags = MOUSEEVENTF_LEFTUP;
  510. }
  511. else if( release == 2 )
  512. {
  513. mouse_evp->dwFlags = MOUSEEVENTF_RIGHTUP;
  514. }
  515. else if( release == 3 )
  516. {
  517. mouse_evp->dwFlags = MOUSEEVENTF_MIDDLEUP;
  518. }
  519. SendInput( 1, input_ev, sizeof( INPUT ) );
  520. }
  521. #endif
  522. }
  523. static void sendKeyState( char key, int press, int release )
  524. {
  525. #ifdef WIN32
  526. // Set up the input event struct
  527. INPUT input_ev[1];
  528. input_ev[0].type = INPUT_KEYBOARD;
  529. PKEYBDINPUT key_evp;
  530. key_evp = &input_ev[0].ki;
  531. key_evp->wScan = key;
  532. key_evp->time = 0;
  533. unsigned short extended = 0;
  534. if( key & 0x80 ) {
  535. extended = KEYEVENTF_EXTENDEDKEY;
  536. key_evp->wScan = key & ~0xff80;
  537. }
  538. if( press ) {
  539. key_evp->dwFlags = extended | KEYEVENTF_SCANCODE;
  540. SendInput( 1, input_ev, sizeof( INPUT ) );
  541. }
  542. if( release ) {
  543. key_evp->dwFlags = extended | KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
  544. SendInput( 1, input_ev, sizeof( INPUT ) );
  545. }
  546. #endif
  547. }
  548. static void sendAbsoluteMouseMove( float x, float y )
  549. {
  550. #ifdef WIN32
  551. // Set up the input event struct
  552. INPUT input_ev[1];
  553. input_ev[0].type = INPUT_MOUSE;
  554. PMOUSEINPUT mouse_evp;
  555. mouse_evp = &input_ev[0].mi;
  556. mouse_evp->time=0;
  557. mouse_evp->dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE | 0x2000;
  558. mouse_evp->dx = (int)(65535.0f*x);
  559. mouse_evp->dy = 65535-(int)(65535.0f*y);
  560. SendInput( 1, input_ev, sizeof( INPUT ) );
  561. #endif
  562. }
  563. #endif
  564. #if 0
  565. #ifdef DEBUG
  566. extern "C" int sixenseSetDebugParam( const char *param_name, float val );
  567. extern "C" int sixenseGetDebugParam( const char *param_name, float *val );
  568. static void inc_debug_val( const CCommand &args )
  569. {
  570. if ( args.ArgC() != 3 )
  571. {
  572. Warning( "Incorrect parameters. Format: sixense_set_debug_val <var> <val>\n" );
  573. return;
  574. }
  575. float current;
  576. sixenseGetDebugParam( args[1], &current );
  577. float new_val = current + atof( args[2] );
  578. sixenseSetDebugParam( args[1], new_val );
  579. Msg( "set \"%s\" to %f\n", args[1], new_val );
  580. }
  581. ConCommand sixense_inc_debug_val( "sixense_inc_debug_val", inc_debug_val );
  582. #endif
  583. #endif
  584. void SixenseConvarChanged( IConVar *var, const char *pOldValue, float flOldValue )
  585. {
  586. if( g_pSixenseInput )
  587. {
  588. g_pSixenseInput->ConvarChanged();
  589. }
  590. }
  591. void SixenseInput::ConvarChanged()
  592. {
  593. m_bConvarChanged = true;
  594. }
  595. SixenseInput::SixenseInput()
  596. {
  597. m_bModulesLoaded = false;
  598. m_pSixenseAPI = NULL;
  599. m_pFPSViewAngles = NULL;
  600. m_pFPSPlayerMovement = NULL;
  601. m_pFPSEvents = NULL;
  602. m_pLaserPointer = NULL;
  603. m_pLeftDeriv = NULL;
  604. m_pRightDeriv = NULL;
  605. m_pLeftButtonStates = NULL;
  606. m_pRightButtonStates = NULL;
  607. m_bWasInMenuMode = false;
  608. m_pLaserPointer = NULL;
  609. m_pControllerManager = NULL;
  610. m_pACD = NULL;
  611. m_bConvarChanged = true;
  612. m_bIsEnabled = false; // sixense.dll loaded
  613. m_bIsActive = false; // controllers not docked
  614. m_nFilterLevel = 1;
  615. m_bMoveMouseToCenter = false;
  616. m_bShouldSetBaseOffset = false;
  617. m_LastViewMode = sixenseUtils::IFPSViewAngles::FREE_AIM_TWO_CONTROLLER;
  618. sixense_sensitivity_level.InstallChangeCallback( SixenseSensitivityLevelChanged );
  619. // Don't listen to our convars until sixense is loaded
  620. InstallConvarCallbacks();
  621. m_nFreeaimSpinDisabled = 0;
  622. m_nGesturesDisabled = 0;
  623. m_fTeleportWaitToBlendTime = 0.0f;
  624. m_bPlayerValid = false;
  625. m_nShouldUnduck = false;
  626. m_nLeftIndex = -1;
  627. m_nRightIndex = -1;
  628. m_bJustSpawned = false;
  629. // For keeping track of the previous mode when looking down the scope changes it.
  630. m_bScopeSwitchedMode = false;
  631. m_nScopeSwitchedPrevSpringViewEnabled = 0;
  632. m_pGestureBindings = new SixenseGestureBindings;
  633. #ifdef PORTAL2
  634. m_bJustPortalled = false;
  635. m_bIsLeftTriggerDown = false;
  636. m_bIsRightTriggerDown = false;
  637. m_fDisableJumpUntil = 0.0f;
  638. m_AnglesToRightHand.Init();
  639. m_AnglesToLeftHand.Init();
  640. m_bIsIn1to1Mode = false;
  641. m_bIs1to1ModeLocked = false;
  642. m_bIs1to1ModeScaling = false;
  643. m_bIs1to1ModeRatcheting = false;
  644. m_bExitOneWhenAimingForwards = false;
  645. m_bScalingLockedOneToOne = false;
  646. m_bIsTweaking = false;
  647. m_nGlowIndex = -1;
  648. m_fLastHorizSpeedMult = 0.0f;
  649. m_fLastVertSpeedMult = 0.0f;
  650. #endif
  651. }
  652. SixenseInput::~SixenseInput()
  653. {
  654. }
  655. bool SixenseInput::IsSixenseMap()
  656. {
  657. #ifdef PORTAL2
  658. if ( Q_strncmp( engine->GetLevelName(), "maps/sixense_", 13 ) == 0 )
  659. {
  660. return true;
  661. }
  662. #endif
  663. return false;
  664. }
  665. SixenseGestureBindings *SixenseInput::GetGestureBindings()
  666. {
  667. return m_pGestureBindings;
  668. }
  669. void SixenseInput::FireGameEvent( IGameEvent *pEvent )
  670. {
  671. const char *eventName = pEvent->GetName();
  672. if ( !eventName )
  673. return;
  674. if( FStrEq(eventName, "player_spawn") )
  675. {
  676. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  677. C_BasePlayer *spawner = UTIL_PlayerByUserId( pEvent->GetInt( "userid" ) );
  678. if( pPlayer == spawner )
  679. {
  680. m_bJustSpawned = true;
  681. }
  682. }
  683. #ifdef PORTAL2
  684. if ( Q_strcmp( type, "sixense_player_teleported" ) == 0 )
  685. {
  686. int playerId = pEvent->GetInt( "userid", 0 );
  687. // Only set view on player that sent the event
  688. C_BasePlayer * pPlayer = C_BasePlayer::GetLocalPlayer();
  689. if ( pPlayer && pPlayer->GetUserID() == playerId )
  690. {
  691. float x = pEvent->GetFloat( "pitch", 0 );
  692. float y = pEvent->GetFloat( "yaw", 0 );
  693. float z = pEvent->GetFloat( "roll", 0 );
  694. float isInitialSpawn = pEvent->GetBool( "isInitialSpawn", false );
  695. if ( isInitialSpawn )
  696. {
  697. PlayerSpawn();
  698. }
  699. QAngle newAngle;
  700. newAngle.Init( x, y, z );
  701. ResetView( newAngle );
  702. m_fTeleportWaitToBlendTime = gpGlobals->curtime + sixense_teleport_wait_to_blend_time.GetFloat();
  703. }
  704. }
  705. else if ( Q_strcmp( type, "player_drop" ) == 0 )
  706. {
  707. int playerId = pEvent->GetInt( "userid", 0 );
  708. C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
  709. if ( pPlayer && ( pPlayer->GetUserID() == playerId ) )
  710. {
  711. PlayerDroppedEntity( pEvent->GetInt( "entity", 0 ) );
  712. }
  713. }
  714. else if ( Q_strcmp( type, "player_use" ) == 0 )
  715. {
  716. int playerId = pEvent->GetInt( "userid", 0 );
  717. C_BasePlayer* pPlayer = C_BasePlayer::GetLocalPlayer();
  718. if ( pPlayer && pPlayer->GetUserID() == playerId )
  719. {
  720. PlayerUsedEntity( pEvent->GetInt( "entity", 0 ) );
  721. }
  722. }
  723. #endif
  724. }
  725. #ifdef PORTAL2
  726. void SixenseInput::PlayerDroppedEntity( int entityID )
  727. {
  728. if ( UTIL_IsScaledCube( cl_entitylist->GetBaseEntity( entityID ) ) &&
  729. !m_bIsIn1to1Mode &&
  730. m_pFPSViewAngles &&
  731. ( m_pFPSViewAngles->getParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_MAX_SPEED ) <= sixense_aim_freeaim_max_speed.GetFloat() ) )
  732. {
  733. m_pFPSViewAngles->forceMetroidBlend( m_pFPSViewAngles->getParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_MAX_SPEED ) / sixense_aim_freeaim_max_speed.GetFloat() );
  734. }
  735. }
  736. void SixenseInput::PlayerUsedEntity( int entityID )
  737. {
  738. }
  739. void SixenseInput::PlayerPortalled( const VMatrix &PortalMatrix )
  740. {
  741. sixenseMath::Vector3 ss_view_angles = g_pSixenseInput->m_pFPSViewAngles->getViewAngles();
  742. QAngle new_viewangles;
  743. new_viewangles[YAW] = ss_view_angles[0];
  744. new_viewangles[PITCH] = ss_view_angles[1];
  745. new_viewangles[ROLL] = ss_view_angles[2];
  746. QAngle corrected_viewangles;
  747. UTIL_Portal_AngleTransform( PortalMatrix, new_viewangles, corrected_viewangles );
  748. //Msg("Fixed local view angles %f %f %f\n", corrected_viewangles[YAW], corrected_viewangles[PITCH], corrected_viewangles[ROLL] );
  749. g_pSixenseInput->ForceViewAngles( corrected_viewangles );
  750. }
  751. void SixenseInput::SetPortalTweakingParameters( bool bIsTweaking )
  752. {
  753. // set params if state changed
  754. if ( m_bIsTweaking != bIsTweaking )
  755. {
  756. // set new state
  757. m_bIsTweaking = bIsTweaking;
  758. // set params
  759. if ( m_bIsTweaking )
  760. {
  761. // save previous values
  762. m_fTweakSixenseAimFreeaimAccelBandExponent = sixense_aim_freeaim_accel_band_exponent.GetFloat();
  763. m_fTweakSixenseAimFreeaimAutoLevelRate = sixense_aim_freeaim_auto_level_rate.GetFloat();
  764. m_fTweakSixenseAimFreeaimAccelBandSize = sixense_aim_freeaim_accel_band_size.GetFloat();
  765. m_fTweakSixenseAimFreeaimMaxSpeed = sixense_aim_freeaim_max_speed.GetFloat();
  766. m_fTweakSixenseAimFreeaimDeadZoneRadius = sixense_aim_freeaim_dead_zone_radius.GetFloat();
  767. m_fTweakSixenseAimFreeaimHeadingMultiplier = sixense_aim_freeaim_heading_multiplier.GetFloat();
  768. m_fTweakSixenseAimFreeaimPitchMultiplier = sixense_aim_freeaim_pitch_multiplier.GetFloat();
  769. m_fTweakSixenseAim1to1HeadingMultiplier = sixense_aim_1to1_heading_multiplier.GetFloat();
  770. m_fTweakSixenseAim1to1PitchMultiplier = sixense_aim_1to1_pitch_multiplier.GetFloat();
  771. // set tweak values
  772. sixense_aim_freeaim_accel_band_exponent.SetValue( 1.0f );
  773. sixense_aim_freeaim_auto_level_rate.SetValue( 1.0f );
  774. sixense_aim_freeaim_accel_band_size.SetValue( 25.0f );
  775. sixense_aim_freeaim_max_speed.SetValue( 3.0f );
  776. sixense_aim_freeaim_dead_zone_radius.SetValue( 2.0f );
  777. sixense_aim_freeaim_heading_multiplier.SetValue( 1.0f );
  778. sixense_aim_freeaim_pitch_multiplier.SetValue( 1.0f );
  779. sixense_aim_1to1_heading_multiplier.SetValue( 2.0f );
  780. sixense_aim_1to1_pitch_multiplier.SetValue( 1.5f );
  781. }
  782. else
  783. {
  784. // restore values
  785. sixense_aim_freeaim_accel_band_exponent.SetValue( m_fTweakSixenseAimFreeaimAccelBandExponent );
  786. sixense_aim_freeaim_auto_level_rate.SetValue( m_fTweakSixenseAimFreeaimAutoLevelRate );
  787. sixense_aim_freeaim_accel_band_size.SetValue( m_fTweakSixenseAimFreeaimAccelBandSize );
  788. sixense_aim_freeaim_max_speed.SetValue( m_fTweakSixenseAimFreeaimMaxSpeed );
  789. sixense_aim_freeaim_dead_zone_radius.SetValue( m_fTweakSixenseAimFreeaimDeadZoneRadius );
  790. sixense_aim_freeaim_heading_multiplier.SetValue( m_fTweakSixenseAimFreeaimHeadingMultiplier );
  791. sixense_aim_freeaim_pitch_multiplier.SetValue( m_fTweakSixenseAimFreeaimPitchMultiplier );
  792. sixense_aim_1to1_heading_multiplier.SetValue( m_fTweakSixenseAim1to1HeadingMultiplier );
  793. sixense_aim_1to1_pitch_multiplier.SetValue( m_fTweakSixenseAim1to1PitchMultiplier );
  794. // force blend back to original mode
  795. if ( m_pFPSViewAngles->getParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_MAX_SPEED ) <= sixense_aim_freeaim_max_speed.GetFloat() )
  796. {
  797. m_pFPSViewAngles->forceMetroidBlend( m_pFPSViewAngles->getParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_MAX_SPEED ) / sixense_aim_freeaim_max_speed.GetFloat() );
  798. }
  799. }
  800. }
  801. }
  802. void SixenseInput::SetOneToOneMode( bool bOnOrOff )
  803. {
  804. // Dont do anything if we're already in that mode
  805. if ( bOnOrOff == m_bIsIn1to1Mode ) return;
  806. Vector glowColor;
  807. glowColor.x = 1.0f;
  808. glowColor.y = 1.0f;
  809. glowColor.z = 0.5f;
  810. if ( bOnOrOff )
  811. {
  812. m_LastViewMode = m_pFPSViewAngles->getMode();
  813. m_pFPSViewAngles->setMode( sixenseUtils::IFPSViewAngles::DUAL_ANALOG );
  814. m_bIsIn1to1Mode = true;
  815. m_bIs1to1ModeLocked = true;
  816. // Start glowing
  817. m_nGlowIndex = g_GlowObjectManager.RegisterGlowObject( GetHeldObject(), glowColor, 0.25f, GET_ACTIVE_SPLITSCREEN_SLOT() );
  818. if ( !sixense_dist_one_to_one_enabled.GetInt() )
  819. {
  820. // Auto calib
  821. SetBaseOffset();
  822. }
  823. }
  824. else
  825. {
  826. m_bScalingLockedOneToOne = false;
  827. m_pFPSViewAngles->setMode( m_LastViewMode );
  828. m_bIsIn1to1Mode = false;
  829. m_bIs1to1ModeLocked = false;
  830. // Stop glowing
  831. if ( m_nGlowIndex != -1 )
  832. {
  833. g_GlowObjectManager.UnregisterGlowObject( m_nGlowIndex );
  834. m_nGlowIndex = -1;
  835. }
  836. }
  837. m_pFPSViewAngles->update( &m_pACD->controllers[m_nLeftIndex], &m_pACD->controllers[m_nRightIndex] );
  838. }
  839. bool SixenseInput::IsHoldingObject()
  840. {
  841. if( GetHeldObject() )
  842. {
  843. return true;
  844. }
  845. else
  846. {
  847. return false;
  848. }
  849. }
  850. C_BaseEntity *SixenseInput::GetHeldObject()
  851. {
  852. C_BasePlayer* pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  853. if ( pLocalPlayer )
  854. {
  855. return GetPlayerHeldEntity( pLocalPlayer );
  856. }
  857. return NULL;
  858. }
  859. bool SixenseInput::IsInOneToOneMode()
  860. {
  861. // We're never in one to one if sixense features aren't turned on
  862. if ( sixense_features_enabled.GetInt() == 0 )
  863. {
  864. return false;
  865. }
  866. // We're in 1 to one mode if the object is being held and the view is locked.
  867. return m_bIsIn1to1Mode;
  868. }
  869. bool SixenseInput::IsInAlwaysOneToOneMode()
  870. {
  871. // We're never in one to one if sixense features aren't turned on
  872. if ( sixense_features_enabled.GetInt() == 0 )
  873. {
  874. return false;
  875. }
  876. return ( C_BasePlayer::GetLocalPlayer()->GetSixenseFlags() & CBasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_ALWAYS_ONE_TO_ONE ) ? true : false;
  877. }
  878. #endif
  879. void SixenseInput::BlendView()
  880. {
  881. // blend in view
  882. sixenseUtils::IFPSViewAngles::fps_mode cur_mode = m_pFPSViewAngles->getMode();
  883. m_pFPSViewAngles->setMode( sixenseUtils::IFPSViewAngles::DUAL_ANALOG );
  884. m_pFPSViewAngles->setMode( cur_mode );
  885. }
  886. // We don't seem to have an event that is fired on map load or level change
  887. void SixenseInput::PlayerSpawn()
  888. {
  889. #ifdef PORTAL2
  890. // Hide any hints that were there from a previous level if left on
  891. hide_video_hint();
  892. #endif
  893. // Reset the sensitiviy settings
  894. LoadDefaultSettings( sixense_sensitivity_level.GetInt() );
  895. m_nGesturesDisabled = 0;
  896. m_nFreeaimSpinDisabled = 0;
  897. #ifdef PORTAL2
  898. sixense_disable_scale_reset_lesson.Revert();
  899. sixense_disable_ratchet_lesson.Revert();
  900. sixense_enable_tutorial_ratchet_lesson.Revert();
  901. #endif
  902. m_bPlayerValid = true;
  903. }
  904. // Turns sixense support on and off. Note this is different than m_bIsActive, which gets
  905. // set when the controllers are not in the dock.
  906. void SixenseInput::SetEnabled( bool bEnabled )
  907. {
  908. if ( !m_bIsEnabled && bEnabled )
  909. {
  910. // Just turned on...
  911. // Make sure the modules are either loaded or loaded previously
  912. if( !LoadModules() )
  913. {
  914. // Modules failed to load, disable
  915. sixense_enabled.SetValue( 0 );
  916. m_bIsEnabled = false;
  917. return;
  918. }
  919. }
  920. else if ( m_bIsEnabled && !bEnabled )
  921. {
  922. // Just turned off...
  923. if ( m_bPlayerValid )
  924. {
  925. C_BasePlayer * pPlayer = C_BasePlayer::GetLocalPlayer();
  926. if ( pPlayer )
  927. {
  928. // We are just switching off...
  929. QAngle ident;
  930. ident.Init();
  931. pPlayer->SetEyeAngleOffset( ident ); // This is the way the player is looking, and the orientation of the weapon model
  932. }
  933. }
  934. // UnloadModules(); // fix crash on unload in sixense_utils
  935. }
  936. #ifdef PORTAL2
  937. if ( m_bPlayerValid )
  938. {
  939. C_BasePlayer * pPlayer = C_BasePlayer::GetLocalPlayer();
  940. if ( pPlayer )
  941. {
  942. GetGameInstructor().ForceStopAllLessons();
  943. }
  944. }
  945. #endif
  946. m_bIsEnabled = bEnabled;
  947. }
  948. void SixenseInput::ResetView( QAngle SpawnAngles )
  949. {
  950. m_pFPSViewAngles->reset();
  951. Vector3 ss_spawn_angles( SpawnAngles[YAW], SpawnAngles[PITCH], SpawnAngles[ROLL] );
  952. m_pFPSViewAngles->forceViewAngles( m_pFPSViewAngles->getMode(), ss_spawn_angles );
  953. }
  954. void SixenseInput::Init()
  955. {
  956. m_pSixenseAPI->sixenseInit();
  957. if( !m_pACD )
  958. {
  959. m_pACD = new sixenseAllControllerData;
  960. }
  961. // init the sixense controller manager
  962. m_pControllerManager->setGameType( sixenseUtils::IControllerManager::ONE_PLAYER_TWO_CONTROLLER );
  963. m_pControllerManager->registerSetupCallback( controller_manager_setup_callback );
  964. #ifdef PORTAL2
  965. m_pFPSViewAngles->setGame( "portal" );
  966. m_pFPSEvents->setGame( "portal" );
  967. #else
  968. m_pFPSViewAngles->setGame( "cstrike15" );
  969. m_pFPSEvents->setGame( "cstrike15" );
  970. #endif
  971. }
  972. void SixenseInput::PostInit()
  973. {
  974. #ifdef PORTAL2
  975. ListenForGameEvent( "sixense_player_teleported" );
  976. ListenForGameEvent( "player_drop" );
  977. ListenForGameEvent( "player_use" );
  978. #endif
  979. ListenForGameEvent( "player_spawn" );
  980. if( sixense_sensitivity_level.GetInt() == -1 )
  981. {
  982. LoadDefaultSettings( 2 );
  983. }
  984. engine->ExecuteClientCmd( "exec sixense_bindings.cfg" );
  985. if( m_pGestureBindings->GetNumBindings() == 0 )
  986. {
  987. // Try to create the default sixense bindings file if it doesn't already exist\n");
  988. m_pGestureBindings->CreateDefaultBindings();
  989. m_pGestureBindings->WriteBindings( "" );
  990. }
  991. }
  992. void SixenseInput::Shutdown()
  993. {
  994. // Clear out pointers fetched from factories
  995. m_pFPSViewAngles = NULL;
  996. m_pFPSPlayerMovement = NULL;
  997. m_pFPSEvents = NULL;
  998. m_pLaserPointer = NULL;
  999. m_pLeftDeriv = NULL;
  1000. m_pRightDeriv = NULL;
  1001. m_pLeftButtonStates = NULL;
  1002. m_pRightButtonStates = NULL;
  1003. m_pControllerManager = NULL;
  1004. if( m_pACD )
  1005. {
  1006. delete m_pACD;
  1007. }
  1008. if ( m_SixenseFrame )
  1009. {
  1010. if ( !m_SixenseFrame->IsAutoDeleteSet() )
  1011. {
  1012. m_SixenseFrame->SetParent( (vgui::Panel*)NULL );
  1013. delete m_SixenseFrame;
  1014. m_SixenseFrame = NULL;
  1015. }
  1016. }
  1017. if( m_pGestureBindings )
  1018. {
  1019. delete m_pGestureBindings;
  1020. m_pGestureBindings = NULL;
  1021. }
  1022. if( m_pSixenseAPI )
  1023. {
  1024. m_pSixenseAPI->sixenseExit();
  1025. }
  1026. }
  1027. bool SixenseInput::IsEnabled()
  1028. {
  1029. return m_bIsEnabled && m_bIsActive;
  1030. }
  1031. bool SixenseInput::IsLeftHanded()
  1032. {
  1033. return sixense_left_handed.GetInt()==0?false:true;
  1034. }
  1035. void SixenseInput::SetBaseOffset()
  1036. {
  1037. m_bShouldSetBaseOffset = true;
  1038. }
  1039. void SixenseInput::GetFOV( float *hfov, float *vfov )
  1040. {
  1041. #if ( defined( HL2_CLIENT_DLL ) || defined( TF_CLIENT_DLL ) || defined( CSTRIKE_DLL ) ) && !defined( CSTRIKE15 ) && !defined( TERROR )
  1042. float engineAspectRatio = engine->GetScreenAspectRatio();
  1043. #else
  1044. // avoid GetLocalPlayer() assert...
  1045. if( !engine->IsLocalPlayerResolvable() ) {
  1046. // defaults?
  1047. *hfov = 90.0f;
  1048. *vfov = 50.0f;
  1049. return;
  1050. }
  1051. float engineAspectRatio = engine->GetScreenAspectRatio( ScreenWidth(), ScreenHeight() );
  1052. #endif
  1053. C_BasePlayer * pPlayer = C_BasePlayer::GetLocalPlayer();
  1054. if( pPlayer )
  1055. {
  1056. *hfov = pPlayer->GetFOV();
  1057. *vfov = *hfov / engineAspectRatio;
  1058. }
  1059. else
  1060. {
  1061. // defaults?
  1062. *hfov = 90.0f;
  1063. *vfov = 50.0f;
  1064. }
  1065. }
  1066. void SixenseInput::SetMode( int nNewMode )
  1067. {
  1068. // The command id's don't match with the enum, so map it here.
  1069. sixenseUtils::IFPSViewAngles::fps_mode mode = sixenseUtils::IFPSViewAngles::FREE_AIM_TWO_CONTROLLER;
  1070. switch ( nNewMode )
  1071. {
  1072. case 0:
  1073. mode = sixenseUtils::IFPSViewAngles::FREE_AIM_TWO_CONTROLLER;
  1074. break;
  1075. case 1:
  1076. mode = sixenseUtils::IFPSViewAngles::MOUSELOOK;
  1077. break;
  1078. case 2:
  1079. mode = sixenseUtils::IFPSViewAngles::DUAL_ANALOG;
  1080. break;
  1081. }
  1082. if ( m_pFPSViewAngles && (m_pFPSViewAngles->getMode() != mode) )
  1083. {
  1084. m_pFPSViewAngles->setMode( mode );
  1085. m_LastViewMode = m_pFPSViewAngles->getMode();
  1086. }
  1087. }
  1088. bool SixenseInput::InMenuMode()
  1089. {
  1090. #if defined( CSTRIKE_DLL ) && !defined( TERROR )
  1091. bool cstrike_panel_visible = false;
  1092. #if defined( CSTRIKE15 ) // csgo
  1093. const int num_panels = 16;
  1094. char *panel_names[] = {
  1095. PANEL_OVERVIEW,
  1096. PANEL_CLASS,
  1097. PANEL_TEAM,
  1098. PANEL_SPECMENU,
  1099. PANEL_INFO,
  1100. PANEL_BUY,
  1101. PANEL_BUY_CT,
  1102. PANEL_BUY_TER,
  1103. PANEL_BUY_EQUIP_CT,
  1104. PANEL_BUY_EQUIP_TER,
  1105. PANEL_NAV_PROGRESS,
  1106. PANEL_BUYPRESET_MAIN,
  1107. PANEL_BUYPRESET_EDIT,
  1108. PANEL_INTRO,
  1109. PANEL_COMMENTARY_MODELVIEWER,
  1110. PANEL_SURVEY
  1111. };
  1112. #else // css
  1113. const int num_panels = 15;
  1114. char *panel_names[] = {
  1115. PANEL_OVERVIEW,
  1116. PANEL_CLASS,
  1117. PANEL_TEAM,
  1118. PANEL_SPECMENU,
  1119. PANEL_INFO,
  1120. PANEL_BUY,
  1121. PANEL_BUY_CT,
  1122. PANEL_BUY_TER,
  1123. PANEL_BUY_EQUIP_CT,
  1124. PANEL_BUY_EQUIP_TER,
  1125. PANEL_NAV_PROGRESS,
  1126. PANEL_BUYPRESET_MAIN,
  1127. PANEL_BUYPRESET_EDIT,
  1128. PANEL_INTRO,
  1129. PANEL_COMMENTARY_MODELVIEWER
  1130. };
  1131. #endif
  1132. for( int i=0; i<num_panels; i++ )
  1133. {
  1134. #ifdef CSTRIKE15
  1135. IViewPortPanel *panel = GetViewPortInterface()->FindPanelByName( panel_names[i] );
  1136. #else
  1137. IViewPortPanel *panel = gViewPortInterface->FindPanelByName( panel_names[i] );
  1138. #endif
  1139. if( panel )
  1140. {
  1141. if( panel->IsVisible() )
  1142. {
  1143. cstrike_panel_visible = true;
  1144. //Msg("Menu visible %s\n", panel_names[i] );
  1145. }
  1146. }
  1147. }
  1148. #endif
  1149. #if defined( TF_CLIENT_DLL )
  1150. CTFPlayer *pTFPlayer = dynamic_cast<CTFPlayer *>(C_BasePlayer::GetLocalPlayer());
  1151. if( pTFPlayer && pTFPlayer->m_Shared.GetState() == TF_STATE_DYING )
  1152. {
  1153. return true;
  1154. }
  1155. #endif
  1156. if(
  1157. #ifdef PORTAL2
  1158. ( pPlayer && pPlayer->IsTaunting() ) ||
  1159. ( engine->IsLocalPlayerResolvable() && IsRadialMenuOpen() ) ||
  1160. #endif
  1161. #if defined( CSTRIKE_DLL ) && !defined( TERROR )
  1162. #ifdef CSTRIKE15
  1163. BasePanel()->IsScaleformPauseMenuVisible() ||
  1164. #endif
  1165. cstrike_panel_visible ||
  1166. #endif
  1167. (SixenseInput::m_SixenseFrame && SixenseInput::m_SixenseFrame->IsVisible() ) ||
  1168. engine->IsPaused() ||
  1169. ( enginevgui && enginevgui->IsGameUIVisible() ) ||
  1170. vgui::surface()->IsCursorVisible() ||
  1171. ( m_pControllerManager && m_pControllerManager->isMenuVisible() ) )
  1172. {
  1173. return true;
  1174. }
  1175. return false;
  1176. }
  1177. bool SixenseInput::SixenseFrame( float flFrametime, CUserCmd *pCmd )
  1178. {
  1179. if ( sixense_enabled.GetInt() && !m_bIsEnabled )
  1180. {
  1181. SetEnabled( true );
  1182. }
  1183. else if ( !sixense_enabled.GetInt() && m_bIsEnabled )
  1184. {
  1185. SetEnabled( false );
  1186. }
  1187. #ifdef SIXENSE_PLAYER_DATA
  1188. C_BasePlayer * pLocalPlayer = C_BasePlayer::GetLocalPlayer();
  1189. // If sixense is disabled, hide the controller manager screens and return
  1190. if ( pLocalPlayer )
  1191. {
  1192. if ( !m_bIsEnabled )
  1193. {
  1194. pCmd->sixense_flags &= ~CBasePlayer::PLAYER_SIXENSE_ENABLED;
  1195. pLocalPlayer->SetSixenseFlags( pLocalPlayer->GetSixenseFlags() & ~CBasePlayer::PLAYER_SIXENSE_ENABLED );
  1196. return false;
  1197. }
  1198. else
  1199. {
  1200. pCmd->sixense_flags |= CBasePlayer::PLAYER_SIXENSE_ENABLED;
  1201. pLocalPlayer->SetSixenseFlags( pLocalPlayer->GetSixenseFlags() | CBasePlayer::PLAYER_SIXENSE_ENABLED );
  1202. }
  1203. }
  1204. #endif
  1205. // If sixense isn't enabled just return
  1206. if( !m_bIsEnabled )
  1207. {
  1208. return false;
  1209. }
  1210. if( m_bConvarChanged )
  1211. {
  1212. m_bConvarChanged = false;
  1213. UpdateValuesFromConvars();
  1214. }
  1215. m_pSixenseAPI->sixenseGetAllNewestData( m_pACD );
  1216. if( m_pACD->controllers[0].enabled && m_pACD->controllers[1].enabled )
  1217. {
  1218. // Disable sixense when both controllers are docked.
  1219. bool controllers_docked = m_pACD->controllers[0].is_docked || m_pACD->controllers[1].is_docked || !m_pSixenseAPI->sixenseIsBaseConnected(0);
  1220. if( controllers_docked && m_bIsActive ) {
  1221. m_bIsActive = false;
  1222. QAngle engine_angles;
  1223. engine->GetViewAngles( engine_angles );
  1224. QAngle new_engine_angles = engine_angles + GetViewAngleOffset();
  1225. engine->SetViewAngles( new_engine_angles );
  1226. } else if( !controllers_docked && !m_bIsActive ) {
  1227. m_bIsActive = true;
  1228. // Reset the view next time through
  1229. m_bJustSpawned = true;
  1230. // If we're unpausing, flip the mode around so the metroid rotation is blended
  1231. sixenseUtils::IFPSViewAngles::fps_mode cur_mode = m_pFPSViewAngles->getMode();
  1232. m_pFPSViewAngles->setMode( sixenseUtils::IFPSViewAngles::DUAL_ANALOG );
  1233. m_pFPSViewAngles->setMode( cur_mode );
  1234. }
  1235. }
  1236. SixenseUpdateControllerManager();
  1237. if( !sixense_left_handed.GetInt() ) {
  1238. m_nLeftIndex = m_pControllerManager->getIndex( sixenseUtils::IControllerManager::P1L );
  1239. m_nRightIndex = m_pControllerManager->getIndex( sixenseUtils::IControllerManager::P1R );
  1240. } else {
  1241. m_nLeftIndex = m_pControllerManager->getIndex( sixenseUtils::IControllerManager::P1R );
  1242. m_nRightIndex = m_pControllerManager->getIndex( sixenseUtils::IControllerManager::P1L );
  1243. }
  1244. if( m_nLeftIndex < 0 || m_nRightIndex < 0 ) return false;
  1245. // If the controllers are docked we are inactive, return until they are picked up
  1246. if( !m_bIsActive )
  1247. return false;
  1248. m_pLeftButtonStates->update( &m_pACD->controllers[m_nLeftIndex] );
  1249. m_pRightButtonStates->update( &m_pACD->controllers[m_nRightIndex] );
  1250. m_pGestureBindings->UpdateBindings( m_pLeftButtonStates, m_pRightButtonStates, AreBindingsDisabled() );
  1251. SixenseUpdateKeys( flFrametime, pCmd );
  1252. SixenseUpdateMouseCursor();
  1253. #ifdef SIXENSE_PLAYER_DATA
  1254. if ( !engine->IsPaused() && !( enginevgui && enginevgui->IsGameUIVisible() ) && sixense_features_enabled.GetInt() )
  1255. SetPlayerHandPositions( pCmd, flFrametime );
  1256. #endif
  1257. static unsigned char last_seq = 0;
  1258. // Same data as last time, just return
  1259. if ( m_pACD->controllers[0].sequence_number == last_seq )
  1260. {
  1261. return false;
  1262. }
  1263. #ifdef PORTAL2
  1264. C_Portal_Player *pPlayer = GetPortalPlayer();
  1265. #endif
  1266. // If the controller manager is up or the game is paused, don't do anything.
  1267. if ( InMenuMode() )
  1268. {
  1269. m_bWasInMenuMode = true;
  1270. return false;
  1271. }
  1272. // If the menu just hid, blend the view back in
  1273. if( m_bWasInMenuMode )
  1274. {
  1275. m_bWasInMenuMode = false;
  1276. BlendView();
  1277. }
  1278. #ifdef PORTAL2
  1279. // Fail if the video hint is up. Trigger should skip, probably.
  1280. if (_video_hint_panel && _video_hint_panel->IsVisible())
  1281. {
  1282. return false;
  1283. }
  1284. #endif
  1285. last_seq = m_pACD->controllers[0].sequence_number;
  1286. float freeAimSpinSpeed = sixense_aim_freeaim_max_speed.GetFloat();
  1287. if ( m_nFreeaimSpinDisabled > 0 )
  1288. {
  1289. float fCurrentSpeed = m_pFPSViewAngles->getParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_MAX_SPEED );
  1290. freeAimSpinSpeed = fCurrentSpeed *= 0.95;
  1291. }
  1292. else
  1293. {
  1294. #ifdef PORTAL2
  1295. CPropWeightedCube* pScaledCube = UTIL_GetAsScaledCube( GetHeldObject() );
  1296. if ( pScaledCube )
  1297. {
  1298. Vector vecScale = pScaledCube->GetScale();
  1299. float fMaxScale = vecScale[0];
  1300. if( vecScale[1] > fMaxScale ) fMaxScale = vecScale[1];
  1301. if( vecScale[2] > fMaxScale ) fMaxScale = vecScale[2];
  1302. float fSpinMult = 1.0 - sqrt( clamp( ( fMaxScale-1.0f ) / ( sixense_scaling_max.GetFloat() - 1.0f ), 0.0f, 1.0f ) );
  1303. freeAimSpinSpeed = MAX( freeAimSpinSpeed * fSpinMult, sixense_hold_spin_speed.GetFloat() );
  1304. }
  1305. #endif
  1306. }
  1307. static int last_mode = 0;
  1308. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_MAX_SPEED, freeAimSpinSpeed );//sixense_aim_freeaim_max_speed.GetFloat() );
  1309. if ( m_fTeleportWaitToBlendTime - gpGlobals->curtime <= 0.0f )
  1310. {
  1311. // teleport delay complete, blend in the view
  1312. if ( m_fTeleportWaitToBlendTime > 0.0f )
  1313. {
  1314. BlendView();
  1315. m_fTeleportWaitToBlendTime = 0.0f;
  1316. }
  1317. else
  1318. {
  1319. float fBlendTime = clamp( freeAimSpinSpeed * 0.16f * sixense_aim_freeaim_switch_blend_time_enter.GetFloat(), 0.1f, 2.0f);
  1320. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_SWITCH_BLEND_TIME_ENTER, fBlendTime );
  1321. }
  1322. }
  1323. else
  1324. {
  1325. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_MAX_SPEED, 0.0f );
  1326. }
  1327. m_pFPSViewAngles->setParameter( sixenseUtils::IFPSViewAngles::AIM_METROID_MAX_SPEED, freeAimSpinSpeed );//sixense_aim_freeaim_max_speed.GetFloat() );
  1328. // Keep the fov up to date
  1329. float hfov, vfov;
  1330. SixenseInput::GetFOV( &hfov, &vfov );
  1331. m_pFPSViewAngles->setFov( hfov, vfov );
  1332. m_pLeftDeriv->update( &m_pACD->controllers[m_nLeftIndex] );
  1333. m_pRightDeriv->update( &m_pACD->controllers[m_nRightIndex] );
  1334. // Update returns false if there aren't enough controllers to play, so disable all the sixense stuff
  1335. if ( m_pFPSViewAngles->update( &m_pACD->controllers[m_nLeftIndex], &m_pACD->controllers[m_nRightIndex], flFrametime*1000.0f ) == SIXENSE_FAILURE ||
  1336. m_pControllerManager->isMenuVisible() ||
  1337. vgui::surface()->IsCursorVisible() )
  1338. {
  1339. return false;
  1340. }
  1341. static float filtered_frametime = 0.0f;
  1342. const float frametime_filt_param = 0.99f;
  1343. filtered_frametime = filtered_frametime * frametime_filt_param + flFrametime * 1000.0f * ( 1.0f - frametime_filt_param );
  1344. m_pFPSPlayerMovement->update( &m_pACD->controllers[m_nLeftIndex], &m_pACD->controllers[m_nRightIndex], filtered_frametime );
  1345. m_pFPSEvents->update( &m_pACD->controllers[m_nLeftIndex], &m_pACD->controllers[m_nRightIndex], filtered_frametime );
  1346. CheckWeaponForScope();
  1347. return true;
  1348. }
  1349. void SixenseInput::CheckWeaponForScope()
  1350. {
  1351. bool zoomed = false;
  1352. #if defined( TERROR ) || defined (CSTRIKE15) || defined (CSTRIKE_DLL)
  1353. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  1354. if ( pPlayer && (pPlayer->GetFOV() != pPlayer->GetDefaultFOV()) )
  1355. {
  1356. zoomed = true;
  1357. }
  1358. #endif
  1359. #if defined( HL2_CLIENT_DLL )
  1360. C_BaseHLPlayer *hlPlayer = dynamic_cast<C_BaseHLPlayer *>(C_BasePlayer::GetLocalPlayer());
  1361. if ( hlPlayer && hlPlayer->m_HL2Local.m_bZooming )
  1362. {
  1363. zoomed = true;
  1364. }
  1365. #endif
  1366. #if defined( TF_CLIENT_DLL)
  1367. CTFPlayer *ctfPlayer = dynamic_cast<CTFPlayer *>(C_BasePlayer::GetLocalPlayer());
  1368. if ( ctfPlayer && ctfPlayer->m_Shared.InCond( TF_COND_ZOOMED ) )
  1369. {
  1370. zoomed = true;
  1371. }
  1372. #endif
  1373. #if !defined( HL2_CLIENT_DLL ) && !defined( CSTRIKE_DLL ) && !defined( TF_CLIENT_DLL)
  1374. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  1375. if( pPlayer )
  1376. {
  1377. C_BaseCombatWeapon *pWeapon = pPlayer->GetActiveWeapon();
  1378. if( pWeapon )
  1379. {
  1380. CWeaponCSBase *pCSWeapon = dynamic_cast< CWeaponCSBase * >( pWeapon );
  1381. if( pCSWeapon )
  1382. {
  1383. const float min_fov = 45.0f;
  1384. if ( pCSWeapon->HasScope() && (pPlayer->GetFOV() < min_fov) )
  1385. {
  1386. zoomed = true;
  1387. }
  1388. }
  1389. }
  1390. }
  1391. #endif
  1392. if( zoomed && !m_bScopeSwitchedMode )
  1393. {
  1394. // we have a cs weapon that has a scope and we are zoomed.
  1395. // Remember the state of some stuff we set
  1396. m_nScopeSwitchedPrevMode = m_pFPSViewAngles->getMode();
  1397. m_nScopeSwitchedPrevSpringViewEnabled = sixense_spring_view_enabled.GetInt();
  1398. m_bScopeSwitchedMode = true;
  1399. m_pFPSViewAngles->setMode( sixenseUtils::IFPSViewAngles::MOUSELOOK );
  1400. }
  1401. else if( !zoomed && m_bScopeSwitchedMode )
  1402. {
  1403. #if defined( TF_CLIENT_DLL)
  1404. // In TF2 wait until we're done reloading before switching back to metroid mode
  1405. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  1406. if( pPlayer )
  1407. {
  1408. CTFSniperRifle *tfSniperRifle = dynamic_cast<CTFSniperRifle *>(pPlayer->GetActiveWeapon());
  1409. if( tfSniperRifle && (tfSniperRifle->GetRezoomTime() != -1.0f) )
  1410. {
  1411. return;
  1412. }
  1413. }
  1414. #endif
  1415. #if defined( CSTRIKE15 ) || defined (CSTRIKE_DLL)
  1416. C_CSPlayer *csPlayer = dynamic_cast<C_CSPlayer *>(C_BasePlayer::GetLocalPlayer());
  1417. if( csPlayer && csPlayer->m_bResumeZoom )
  1418. {
  1419. return;
  1420. }
  1421. #endif
  1422. // not zoomed anymore, put the old mode back
  1423. if( m_bScopeSwitchedMode ) {
  1424. m_bScopeSwitchedMode = false;
  1425. sixense_spring_view_enabled.SetValue( m_nScopeSwitchedPrevSpringViewEnabled );
  1426. m_pFPSViewAngles->setMode( m_nScopeSwitchedPrevMode );
  1427. }
  1428. }
  1429. }
  1430. void SixenseInput::SwitchViewModes( CUserCmd *pCmd )
  1431. {
  1432. #ifdef PORTAL2
  1433. if( sixense_large_objects_lock_one_to_one.GetInt() )
  1434. {
  1435. C_BaseEntity *held = GetHeldObject();
  1436. if( held )
  1437. {
  1438. C_PropWeightedCube *scaled_cube = UTIL_GetAsScaledCube( held );
  1439. if( scaled_cube )
  1440. {
  1441. Vector scale = scaled_cube->GetScale();
  1442. float max_scale = scale[0];
  1443. if( scale[1] > max_scale ) max_scale = scale[1];
  1444. if( scale[2] > max_scale ) max_scale = scale[2];
  1445. const float scale_force_1to1 = sixense_large_objects_lock_one_to_one_size.GetFloat();
  1446. if( max_scale > scale_force_1to1 )
  1447. {
  1448. // Lock one to one mode on
  1449. m_bScalingLockedOneToOne = true;
  1450. if( !m_bIsIn1to1Mode )
  1451. {
  1452. SetOneToOneMode( true );
  1453. }
  1454. } else {
  1455. m_bScalingLockedOneToOne = false;
  1456. }
  1457. }
  1458. }
  1459. }
  1460. unsigned char lock_button;
  1461. lock_button = SIXENSE_BUTTON_1;
  1462. //lock_button = SIXENSE_BUTTON_4;
  1463. if ( sixense_auto_one_to_one_enabled.GetInt() )
  1464. {
  1465. lock_button = 0;
  1466. }
  1467. C_Portal_Player *pPortalPlayer = C_Portal_Player::GetLocalPortalPlayer();
  1468. // Whenever we scale, lock into one to one mode until the next drop (block dist one to one from exiting)
  1469. //if( pPortalPlayer->IsScalingUseItem() ) {
  1470. // m_bScalingLockedOneToOne = true;
  1471. //}
  1472. // This was old code for controlling 1to1 with a button, but this code was getting hit on drop.
  1473. // Go into 1-to-1 when the button is pressed (and we're holding an object, and we're not scaling)
  1474. //if ( !m_bIs1to1ModeLocked &&
  1475. // !m_bIs1to1ModeScaling &&
  1476. // IsHoldingObject() &&
  1477. // ( lock_button && m_pRightButtonStates->justPressed( lock_button ) ) &&
  1478. // ( pPortalPlayer && !pPortalPlayer->IsScalingUseItem() && !pPortalPlayer->IsScalingUseItemTurret() ) )
  1479. //{
  1480. // SetOneToOneMode( true );
  1481. //}
  1482. // exit 1-to-1 if we dropped the object we were holding, or if the lock button was pressed again
  1483. if ( ( !IsHoldingObject() && m_bIsIn1to1Mode && !m_bExitOneWhenAimingForwards ) ||
  1484. ( m_bIs1to1ModeLocked &&
  1485. !m_bIs1to1ModeScaling &&
  1486. m_pRightButtonStates->justPressed( lock_button ) &&
  1487. ( pPortalPlayer && !pPortalPlayer->IsScalingUseItem() && !pPortalPlayer->IsScalingUseItemTurret() ) ) )
  1488. {
  1489. m_bExitOneWhenAimingForwards = true;
  1490. }
  1491. // Object was dropped while in 1-to-1, don't leave one-to-1 mode until the hand comes back a bit
  1492. if( m_bExitOneWhenAimingForwards ) {
  1493. if( IsAimingForwards() )
  1494. {
  1495. m_bIs1to1ModeScaling = false;
  1496. m_bIs1to1ModeRatcheting = false;
  1497. m_pFPSViewAngles->setRatcheting( false );
  1498. SetOneToOneMode( false );
  1499. m_bExitOneWhenAimingForwards = false;
  1500. }
  1501. }
  1502. // if we just started scaling go into 1-to-1
  1503. else if ( !m_bIs1to1ModeLocked &&
  1504. !m_bIs1to1ModeScaling &&
  1505. IsHoldingObject() &&
  1506. ( pPortalPlayer && ( pPortalPlayer->IsScalingUseItem() || pPortalPlayer->IsScalingUseItemTurret() ) ) )
  1507. {
  1508. m_bIs1to1ModeScaling = true;
  1509. SetOneToOneMode( true );
  1510. }
  1511. // if we just stopped scaling exit 1-to-1
  1512. else if (
  1513. ( !IsHoldingObject() && m_bIsIn1to1Mode ) ||
  1514. ( m_bIs1to1ModeLocked &&
  1515. m_bIs1to1ModeScaling &&
  1516. ( pPortalPlayer && !pPortalPlayer->IsScalingUseItem() && !pPortalPlayer->IsScalingUseItemTurret() ) ) )
  1517. {
  1518. m_bIs1to1ModeScaling = false;
  1519. m_bIs1to1ModeRatcheting = false;
  1520. m_pFPSViewAngles->setRatcheting( false );
  1521. if( !m_bScalingLockedOneToOne ) {
  1522. SetOneToOneMode( false );
  1523. }
  1524. }
  1525. #endif
  1526. }
  1527. bool SixenseInput::IsAimingForwards()
  1528. {
  1529. // Wait until controller is facing forwards again
  1530. Quat rot_quat( m_pACD->controllers[m_nRightIndex].rot_quat );
  1531. Vector3 forwards = rot_quat * Vector3( 0, 0, -1 );
  1532. float dot = forwards * Vector3(0, 0, -1);
  1533. if( dot > sixense_exit_one_to_one_dot.GetFloat() ) {
  1534. return true;
  1535. }
  1536. else
  1537. {
  1538. return false;
  1539. }
  1540. }
  1541. #ifdef SIXENSE_PLAYER_DATA
  1542. void SixenseInput::SetPlayerHandPositions( CUserCmd *pCmd, float flFrametime )
  1543. {
  1544. if ( m_bShouldSetBaseOffset )
  1545. {
  1546. m_bShouldSetBaseOffset = false;
  1547. float base_offset_z_bias = sixense_auto_one_to_one_center_z_bias.GetFloat();
  1548. if ( sixense_dist_one_to_one_enabled.GetInt() )
  1549. {
  1550. base_offset_z_bias = 0.0f;
  1551. }
  1552. sixense_base_offset_x.SetValue( - m_pACD->controllers[m_nRightIndex].pos[0] );
  1553. sixense_base_offset_y.SetValue( - m_pACD->controllers[m_nRightIndex].pos[1] );
  1554. sixense_base_offset_z.SetValue( - m_pACD->controllers[m_nRightIndex].pos[2] - base_offset_z_bias );
  1555. }
  1556. sixenseMath::Vector3 pos;
  1557. sixenseMath::Vector3 base_offset( sixense_base_offset_x.GetFloat(), sixense_base_offset_y.GetFloat(), sixense_base_offset_z.GetFloat() );
  1558. // Tell the client player about the hand positions. This will get sent to the server player as part of the usercmd
  1559. C_BasePlayer *player = C_BasePlayer::GetLocalPlayer();
  1560. // Maintain the player and command one-to-one flags
  1561. if ( m_bIsIn1to1Mode && IsHoldingObject() )
  1562. {
  1563. pCmd->sixense_flags |= C_BasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT;
  1564. player->SetSixenseFlags( player->GetSixenseFlags() | CBasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT );
  1565. if ( m_bIs1to1ModeRatcheting )
  1566. {
  1567. pCmd->sixense_flags |= C_BasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_RATCHETING;
  1568. player->SetSixenseFlags( player->GetSixenseFlags() | CBasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_RATCHETING );
  1569. }
  1570. else
  1571. {
  1572. pCmd->sixense_flags &= ~C_BasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_RATCHETING;
  1573. player->SetSixenseFlags( player->GetSixenseFlags() & ~CBasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_RATCHETING );
  1574. }
  1575. }
  1576. else
  1577. {
  1578. pCmd->sixense_flags &= ~C_BasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT;
  1579. pCmd->sixense_flags &= ~C_BasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_RATCHETING;
  1580. player->SetSixenseFlags( player->GetSixenseFlags() & ~CBasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT );
  1581. player->SetSixenseFlags( player->GetSixenseFlags() & ~CBasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_RATCHETING );
  1582. }
  1583. if ( sixense_dist_one_to_one_enabled.GetInt() )
  1584. {
  1585. pCmd->sixense_flags |= C_BasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_ALWAYS_ONE_TO_ONE;
  1586. player->SetSixenseFlags( player->GetSixenseFlags() | CBasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_ALWAYS_ONE_TO_ONE );
  1587. }
  1588. else
  1589. {
  1590. pCmd->sixense_flags &= ~C_BasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_ALWAYS_ONE_TO_ONE;
  1591. player->SetSixenseFlags( player->GetSixenseFlags() & ~CBasePlayer::PLAYER_SIXENSE_HOLDING_OBJECT_ALWAYS_ONE_TO_ONE );
  1592. }
  1593. // Get the angle mode from the fps angles so we can remove it from the hand orientations
  1594. float angle_mode_angle = m_pFPSViewAngles->getParameter( sixenseUtils::IFPSViewAngles::CONTROLLER_ANGLE_MODE );
  1595. unsigned char left_sequence, right_sequence;
  1596. left_sequence = m_pACD->controllers[m_nLeftIndex].sequence_number;
  1597. right_sequence = m_pACD->controllers[m_nRightIndex].sequence_number;
  1598. sixenseMath::Matrix4 left_mat;
  1599. // Set rotation first
  1600. left_mat = sixenseMath::Matrix4::rotation( sixenseMath::Quat( m_pACD->controllers[m_nLeftIndex].rot_quat[0], m_pACD->controllers[m_nLeftIndex].rot_quat[1], m_pACD->controllers[m_nLeftIndex].rot_quat[2], m_pACD->controllers[m_nLeftIndex].rot_quat[3] ) );
  1601. // Correct for controller angle mode
  1602. left_mat = sixenseMath::Matrix4::rotation( -angle_mode_angle, sixenseMath::Vector3( 1.0f, 0.0f, 0.0f ) ) * left_mat;
  1603. // Fill in translation
  1604. Vector3 ss_left_pos = sixenseMath::Vector3( m_pACD->controllers[m_nLeftIndex].pos[0], m_pACD->controllers[m_nLeftIndex].pos[1], m_pACD->controllers[m_nLeftIndex].pos[2] ) + base_offset;
  1605. left_mat.set_col( 3, sixenseMath::Vector4( ss_left_pos, 1.0f ) );
  1606. // This converts between sixense and source coord sys
  1607. matrix3x4_t left_mat_source = ConvertMatrix( left_mat );
  1608. player->SetSixenseSequence( m_pACD->controllers[0].sequence_number );
  1609. // Set the translations
  1610. Vector left_pos;
  1611. MatrixPosition( left_mat_source, left_pos );
  1612. pCmd->hand_pos_left = left_pos;
  1613. player->SetHandPosLeft( left_pos );
  1614. // Rotations
  1615. QAngle left_rot;
  1616. MatrixAngles( left_mat_source, left_rot );
  1617. pCmd->hand_rot_left = left_rot;
  1618. player->SetHandRotLeft( left_rot );
  1619. if ( left_sequence != m_nLastLeftSequence )
  1620. {
  1621. pCmd->left_hand_pos_new = 1;
  1622. player->SetLeftHandDataNew( true );
  1623. }
  1624. else
  1625. {
  1626. pCmd->left_hand_pos_new = 0;
  1627. player->SetLeftHandDataNew( false );
  1628. }
  1629. m_nLastLeftSequence = left_sequence;
  1630. pCmd->sixense_seq = left_sequence;
  1631. sixenseMath::Matrix4 right_mat;
  1632. // Set rotation first
  1633. right_mat = sixenseMath::Matrix4::rotation( sixenseMath::Quat( m_pACD->controllers[m_nRightIndex].rot_quat[0], m_pACD->controllers[m_nRightIndex].rot_quat[1], m_pACD->controllers[m_nRightIndex].rot_quat[2], m_pACD->controllers[m_nRightIndex].rot_quat[3] ) );
  1634. // Correct for controller angle mode
  1635. right_mat = sixenseMath::Matrix4::rotation( -angle_mode_angle, sixenseMath::Vector3( 1.0f, 0.0f, 0.0f ) ) * right_mat;
  1636. // Fill in translation
  1637. Vector3 ss_right_pos = sixenseMath::Vector3( m_pACD->controllers[m_nRightIndex].pos[0], m_pACD->controllers[m_nRightIndex].pos[1], m_pACD->controllers[m_nRightIndex].pos[2] ) + base_offset;
  1638. // This 'slides' the hold origin if you pull the object back into the player
  1639. float min_z_dist = sixense_hold_slide_z_min_dist.GetFloat();
  1640. float xy_radius = sixense_hold_slide_xy_radius.GetFloat();
  1641. if ( !m_bScalingLockedOneToOne && (Vector3( ss_right_pos[0], ss_right_pos[1], 0.0f ).length() < xy_radius) && (ss_right_pos[2] > min_z_dist) )
  1642. {
  1643. sixense_base_offset_z.SetValue( sixense_base_offset_z.GetFloat() - ( ss_right_pos[2] - min_z_dist ) );
  1644. // Also adjust the position at which the object was grabbed so that the dist one to one slides also
  1645. m_GrabPos[2] += ( ss_right_pos[2] - min_z_dist );
  1646. ss_right_pos[2] = min_z_dist;
  1647. }
  1648. right_mat.set_col( 3, sixenseMath::Vector4( ss_right_pos, 1.0f ) );
  1649. // This converts between sixense and source coord sys
  1650. matrix3x4_t right_mat_source = ConvertMatrix( right_mat );
  1651. // Set the translations
  1652. Vector right_pos;
  1653. MatrixPosition( right_mat_source, right_pos );
  1654. pCmd->hand_pos_right = right_pos;
  1655. player->SetHandPosRight( right_pos );
  1656. // Rotations
  1657. QAngle right_rot;
  1658. MatrixAngles( right_mat_source, right_rot );
  1659. pCmd->hand_rot_right = right_rot;
  1660. player->SetHandRotRight( right_rot );
  1661. if ( right_sequence != m_nLastRightSequence )
  1662. {
  1663. pCmd->right_hand_pos_new = 1;
  1664. player->SetRightHandDataNew( true );
  1665. }
  1666. else
  1667. {
  1668. player->SetRightHandDataNew( false );
  1669. pCmd->right_hand_pos_new = 0;
  1670. }
  1671. m_nLastRightSequence = right_sequence;
  1672. // set controller positions for object scaling
  1673. pCmd->controller_pos_left.Init( ss_left_pos[0], ss_left_pos[1], ss_left_pos[2] );
  1674. pCmd->controller_pos_right.Init( ss_right_pos[0], ss_right_pos[1], ss_right_pos[2] );
  1675. player->SetControllerPosLeft( pCmd->controller_pos_left );
  1676. player->SetControllerPosRight( pCmd->controller_pos_right );
  1677. // set controller rotations for portal tweaking, fix roll so that it goes from (-180 to 180) instead of (-90 to 90)
  1678. sixenseMath::Vector3 left_contoller_angles = left_mat.getEulerAngles();
  1679. sixenseMath::Vector3 right_contoller_angles = right_mat.getEulerAngles();
  1680. QAngle controller_rot_left = QAngle( RAD2DEG( left_contoller_angles[2] ), RAD2DEG( left_contoller_angles[0] ), RAD2DEG( left_contoller_angles[1] ) );
  1681. QAngle controller_rot_right = QAngle( RAD2DEG( right_contoller_angles[2] ), RAD2DEG( right_contoller_angles[0] ), RAD2DEG( right_contoller_angles[1] ) );
  1682. // QAngle controller_rot_left = left_rot;
  1683. // QAngle controller_rot_right = right_rot;
  1684. // if( left_mat_source[2][2] < 0.0f ) {
  1685. // controller_rot_left.x = (controller_rot_left.x > 0.0f) ? (180.0f - controller_rot_left.x) : (-180.0f + controller_rot_left.x);
  1686. // }
  1687. // if( right_mat_source[2][2] < 0.0f ) {
  1688. // controller_rot_right.x = (controller_rot_right.x > 0.0f) ? (180.0f - controller_rot_right.x) : (-180.0f + controller_rot_right.x);
  1689. // }
  1690. pCmd->controller_rot_left.Init( controller_rot_left.x, controller_rot_left.y, controller_rot_left.z );
  1691. pCmd->controller_rot_right.Init( controller_rot_right.x, controller_rot_right.y, controller_rot_right.z );
  1692. player->SetControllerRotLeft( controller_rot_left );
  1693. player->SetControllerRotRight( controller_rot_right );
  1694. // Set some sixense flags...
  1695. if ( m_bIsIn1to1Mode && !m_nFreeaimSpinDisabled )
  1696. {
  1697. // pan the camera to keep the held object on screen
  1698. C_BaseEntity *pHeldObject = GetHeldObject();
  1699. if ( pHeldObject )
  1700. {
  1701. float hold_spin_start_screen_ratio = sixense_hold_spin_start_screen_ratio.GetFloat();
  1702. float hold_spin_speed = sixense_hold_spin_speed.GetFloat();
  1703. float hold_spin_speed_bias = sixense_hold_spin_speed_bias.GetFloat();
  1704. float hold_spin_fade_min_dist = sixense_hold_spin_fade_min_dist.GetFloat();
  1705. float hold_spin_fade_max_dist = sixense_hold_spin_fade_max_dist.GetFloat();
  1706. float hold_spin_max_angle = sixense_hold_spin_max_angle.GetFloat();
  1707. C_Portal_Player *pPlayer = GetPortalPlayer();
  1708. // where is the held object in world coordinates
  1709. Vector objectLocation = pHeldObject->GetAbsOrigin();
  1710. // where the player is
  1711. Vector playerLocation = pPlayer->GetAbsOrigin();
  1712. float dist_from_player = ( objectLocation - playerLocation ).Length();
  1713. // check to see if object is on other side of portal
  1714. if ( pPlayer->IsHeldObjectOnOppositeSideOfPortal() )
  1715. {
  1716. objectLocation = pPlayer->GetGrabLocation();
  1717. }
  1718. // Don't pan if player is reaching behind, he's probably trying to wind up for a throw
  1719. QAngle eyeAngles = pPlayer->EyeAngles();
  1720. Vector vForward;
  1721. AngleVectors( eyeAngles, &vForward );
  1722. float horiz_speed_mult = 0.0f;
  1723. float vert_speed_mult = 0.0f;
  1724. float angle = acos( ( objectLocation - pPlayer->EyePosition() ).Normalized().Dot( vForward ) ) * 180 / M_PI;
  1725. //engine->Con_NPrintf( 1, "angle: %f\n", angle );
  1726. if ( angle < hold_spin_max_angle )
  1727. {
  1728. // world to screen
  1729. Vector screen;
  1730. ScreenTransform( objectLocation, screen );
  1731. screen.x = clamp( screen.x, -1.0f, 1.0f );
  1732. screen.y = clamp( screen.y, -1.0f, 1.0f );
  1733. // horizontal
  1734. if ( abs( screen.x ) > 1.0 - hold_spin_start_screen_ratio )
  1735. {
  1736. horiz_speed_mult = ( ( abs( screen.x ) - ( 1.0 - hold_spin_start_screen_ratio ) ) / hold_spin_start_screen_ratio );
  1737. horiz_speed_mult = Bias( horiz_speed_mult, hold_spin_speed_bias );
  1738. if ( screen.x > 0 ) horiz_speed_mult *= -1;
  1739. }
  1740. // vertical
  1741. if ( abs( screen.y ) > 1.0 - hold_spin_start_screen_ratio )
  1742. {
  1743. vert_speed_mult = ( ( abs( screen.y ) - ( 1.0 - hold_spin_start_screen_ratio ) ) / hold_spin_start_screen_ratio );
  1744. vert_speed_mult = Bias( vert_speed_mult, hold_spin_speed_bias );
  1745. if ( screen.y > 0 ) vert_speed_mult *= -1;
  1746. }
  1747. //engine->Con_NPrintf( 1, "x: %f y:%f\n", screen.x, screen.y );
  1748. //engine->Con_NPrintf( 2, "horiz_speed: %f\n", horiz_speed);
  1749. //engine->Con_NPrintf( 3, "vert_speed: %f\n", vert_speed);
  1750. if ( hold_spin_fade_max_dist != 0.0f && hold_spin_fade_max_dist != 0.0f )
  1751. {
  1752. float spin_fade = ( dist_from_player - hold_spin_fade_min_dist ) / ( hold_spin_fade_max_dist - hold_spin_fade_min_dist );
  1753. spin_fade = clamp( spin_fade, 0.0f, 1.0f );
  1754. horiz_speed_mult *= spin_fade;
  1755. vert_speed_mult *= spin_fade;
  1756. }
  1757. }
  1758. // dampen the camera tracking
  1759. float spin_damp = sixense_hold_spin_damp.GetFloat();
  1760. horiz_speed_mult = horiz_speed_mult * ( 1.0f - spin_damp ) + m_fLastHorizSpeedMult * spin_damp;
  1761. vert_speed_mult = vert_speed_mult * ( 1.0f - spin_damp ) + m_fLastVertSpeedMult * spin_damp;
  1762. m_fLastHorizSpeedMult = horiz_speed_mult;
  1763. m_fLastVertSpeedMult = vert_speed_mult;
  1764. m_pFPSViewAngles->setHoldingTurnSpeed( horiz_speed_mult * hold_spin_speed, vert_speed_mult * hold_spin_speed );
  1765. }
  1766. }
  1767. else
  1768. {
  1769. m_pFPSViewAngles->setHoldingTurnSpeed( 0.0f, 0.0f );
  1770. }
  1771. // Compute the angles that point from the player to the hand positions. This can be used to aim the weapon model at the object being moved.
  1772. // The goofy offsets are because the gun doesn't rotate around the right position, so they fudge it so it looks like it's pointing correctly
  1773. VectorAngles( right_pos + Vector( 250, 0, -25 ), m_AnglesToRightHand );
  1774. VectorAngles( left_pos + Vector( 250, 0, -25 ), m_AnglesToLeftHand );
  1775. }
  1776. #endif
  1777. void SixenseInput::SixenseUpdateControllerManager()
  1778. {
  1779. if( !m_bIsEnabled )
  1780. return;
  1781. m_pControllerManager->update( m_pACD );
  1782. #if 0
  1783. update_controller_manager_visibility( &acd );
  1784. #endif
  1785. }
  1786. void SixenseInput::SetFilter( float f )
  1787. {
  1788. if( f < 0.25f )
  1789. {
  1790. m_pSixenseAPI->sixenseSetFilterParams( 500.0f, 0.5f, 1600.0f, 0.75f );
  1791. Msg("SixenseInput::SetFilter: low\n");
  1792. }
  1793. else if( f < 0.75f )
  1794. {
  1795. m_pSixenseAPI->sixenseSetFilterParams( 500.0f, 0.85f, 1600.0f, 0.95f );
  1796. Msg("SixenseInput::SetFilter: med\n");
  1797. }
  1798. else
  1799. {
  1800. m_pSixenseAPI->sixenseSetFilterParams( 500.0f, 0.96f, 1600.0f, 0.98f );
  1801. Msg("SixenseInput::SetFilter: high\n");
  1802. }
  1803. sixense_filter_level.SetValue( f );
  1804. }
  1805. void SixenseInput::ForceViewAngles( QAngle angles )
  1806. {
  1807. Vector3 ssangles( angles[YAW], angles[PITCH], angles[ROLL] );
  1808. m_pFPSViewAngles->forceViewAngles( m_pFPSViewAngles->getMode(), ssangles );
  1809. }
  1810. static QAngle FixAngles( sixenseMath::Vector3 ss_angles )
  1811. {
  1812. QAngle qa;
  1813. qa[YAW] = ss_angles[0];
  1814. qa[PITCH] = ss_angles[1];
  1815. qa[ROLL] = ss_angles[2];
  1816. return qa;
  1817. }
  1818. sixenseMath::Vector3 FixAngles( QAngle qa )
  1819. {
  1820. sixenseMath::Vector3 ss_angles;
  1821. ss_angles[0] = qa[YAW];
  1822. ss_angles[1] = qa[PITCH];
  1823. ss_angles[2] = qa[ROLL];
  1824. return ss_angles;
  1825. }
  1826. #if defined( TF_CLIENT_DLL )
  1827. static float g_fDemoChargeViewOffsetScale = 1.0f;
  1828. #endif
  1829. void SixenseInput::SetView( float flInputSampleFrametime, CUserCmd *pCmd )
  1830. {
  1831. if ( InMenuMode() )
  1832. {
  1833. return;
  1834. }
  1835. // Sample the axes, apply the input, and consume sample time.
  1836. if ( m_fRemainingFrameTime > 0 )
  1837. {
  1838. flInputSampleFrametime = MIN( m_fRemainingFrameTime, flInputSampleFrametime );
  1839. m_fRemainingFrameTime -= flInputSampleFrametime;
  1840. }
  1841. // Set the new engine angles. This is the direction the player is really aiming, and the only direction the
  1842. // server really cares about.
  1843. QAngle spin_speed = -1.0f * FixAngles( m_pFPSViewAngles->getSpinSpeed() );
  1844. if( UseVR() )
  1845. {
  1846. spin_speed[PITCH] = 0.f;
  1847. spin_speed[ROLL] = 0.f;
  1848. }
  1849. #if defined( TF_CLIENT_DLL )
  1850. static bool last_charge = false, charging = false;
  1851. bool charge_started=false, charge_stopped=false;
  1852. CTFPlayer *pPlayer = ToTFPlayer( C_BasePlayer::GetLocalPlayer() );
  1853. if ( pPlayer )
  1854. {
  1855. charging = pPlayer->m_Shared.InCond( TF_COND_SHIELD_CHARGE );
  1856. if ( charging )
  1857. {
  1858. if( !last_charge )
  1859. {
  1860. charge_started = true;
  1861. }
  1862. }
  1863. else
  1864. {
  1865. if( last_charge )
  1866. {
  1867. charge_stopped = true;
  1868. }
  1869. }
  1870. }
  1871. last_charge = charging;
  1872. if( charging )
  1873. {
  1874. g_fDemoChargeViewOffsetScale *= 0.9f;
  1875. }
  1876. else
  1877. {
  1878. g_fDemoChargeViewOffsetScale = g_fDemoChargeViewOffsetScale * 0.9f + 0.1f;
  1879. }
  1880. #endif
  1881. // Keep track of the total accumulated spin angle. This accumulation is done outisde of sixenseUtils because we need to
  1882. // keep a close look on the engine time to do proper time sync.
  1883. QAngle accumulated_spin_angles;
  1884. accumulated_spin_angles = FixAngles( m_pFPSViewAngles->getFeetAnglesMetroid() ) + ( spin_speed * flInputSampleFrametime * 30.0f );
  1885. // Clamp it +/- 90
  1886. if ( accumulated_spin_angles[PITCH] > 89.0f )
  1887. {
  1888. accumulated_spin_angles[PITCH] = 89.0f;
  1889. }
  1890. else if ( accumulated_spin_angles[PITCH] < -89.0f )
  1891. {
  1892. accumulated_spin_angles[PITCH] = -89.0f;
  1893. }
  1894. // Tell the view angle system about the total angle so GetViewAngleOffset can compute the player camera angle
  1895. m_pFPSViewAngles->setFeetAnglesMetroid( FixAngles( accumulated_spin_angles ) );
  1896. if( m_bJustSpawned )
  1897. {
  1898. m_bJustSpawned = false;
  1899. QAngle engine_angles;
  1900. engine->GetViewAngles( engine_angles );
  1901. ResetView( engine_angles );
  1902. return;
  1903. }
  1904. QAngle new_viewangles = FixAngles( m_pFPSViewAngles->getViewAngles() );
  1905. #if defined( TF_CLIENT_DLL )
  1906. // Dont turn when charging
  1907. if( !charging )
  1908. {
  1909. engine->SetViewAngles( new_viewangles );
  1910. }
  1911. if( charge_stopped )
  1912. {
  1913. QAngle engine_angles;
  1914. engine->GetViewAngles( engine_angles );
  1915. ForceViewAngles( engine_angles );
  1916. Msg("charge stopped\n");
  1917. }
  1918. #else
  1919. // Set the engine's aim direction
  1920. engine->SetViewAngles( new_viewangles );
  1921. #endif
  1922. if ( pCmd )
  1923. {
  1924. pCmd->mousedx = spin_speed[YAW];
  1925. pCmd->mousedy = spin_speed[PITCH];
  1926. }
  1927. // Also set the player direction, this is the view frustum direction, which in metroid mode counter-rotates
  1928. // from the aim direction engine angles.
  1929. C_BasePlayer::GetLocalPlayer()->SetEyeAngleOffset( GetViewAngleOffset() ); // This is the way the player is looking, and the orientation of the weapon model
  1930. //C_BaseEntity *pEntOrg = C_BasePlayer::GetLocalPlayer()->GetViewEntity();
  1931. #ifdef SIXENSE_PLAYER_DATA
  1932. // Set the eye offset angles in the ucmd so thay get sent to the server
  1933. pCmd->view_angle_offset = GetViewAngleOffset();
  1934. #endif
  1935. }
  1936. void SixenseInput::SixenseUpdateKeys( float flFrametime, CUserCmd *pCmd )
  1937. {
  1938. static int new_buttons = 0;
  1939. // Sometimes we get called but Sixense isn't ready to produce any new data yet. We want to preseve whatever we were doing before,
  1940. // ie walking, so keep track of the last state we used.
  1941. static int last_buttons = 0;
  1942. static float last_forwardmove = 0.0f;
  1943. static float last_sidemove = 0.0f;
  1944. static int last_sixense_flags = 0;
  1945. // If the controller manager is up or the game is paused, don't do anything.
  1946. if ( InMenuMode() ||
  1947. (C_BasePlayer::GetLocalPlayer() && C_BasePlayer::GetLocalPlayer()->IsObserver()) ||
  1948. ( m_nLeftIndex == -1 ) ||
  1949. ( m_nRightIndex == -1 ) ||
  1950. ( m_nGesturesDisabled == 1 ) )
  1951. {
  1952. // No new data, set the keys to what they were last time we did have new data
  1953. #ifdef PORTAL2
  1954. // Unduck here too so if gestures are disabled like in the tutorial we're not stuck ducking
  1955. if ( m_pFPSEvents->eventStopped( sixenseUtils::IFPSEvents::CROUCH ) )
  1956. {
  1957. last_buttons &= ~IN_DUCK;
  1958. new_buttons &= ~IN_DUCK;
  1959. //engine->ClientCmd( "-duck" );
  1960. }
  1961. #endif
  1962. if( pCmd )
  1963. {
  1964. // Sometimes we get called but Sixense isn't ready to produce any new data yet. We want to preseve whatever we were doing before,
  1965. // ie walking, so keep track of the last state we used.
  1966. pCmd->buttons = last_buttons;
  1967. #ifdef SIXENSE_PLAYER_DATA
  1968. pCmd->sixense_flags = last_sixense_flags;
  1969. #endif
  1970. pCmd->mousedx = 0;
  1971. pCmd->mousedy = 0;
  1972. //pCmd->forwardmove = last_forwardmove;
  1973. //pCmd->sidemove = last_sidemove;
  1974. if( InMenuMode() )
  1975. {
  1976. // Force walking to stop when menus are up
  1977. pCmd->forwardmove = 0.0f;
  1978. pCmd->sidemove = 0.0f;
  1979. }
  1980. }
  1981. // hard code some commands for when we're observing
  1982. C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();
  1983. if( pPlayer && pPlayer->IsObserver() )
  1984. {
  1985. if( m_pLeftButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_RIGHT ) )
  1986. {
  1987. engine->ExecuteClientCmd( "spec_next" );
  1988. }
  1989. if( m_pLeftButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_LEFT ) )
  1990. {
  1991. engine->ExecuteClientCmd( "spec_prev" );
  1992. }
  1993. if( m_pLeftButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_UP ) )
  1994. {
  1995. engine->ExecuteClientCmd( "spec_mode" );
  1996. }
  1997. if( m_pLeftButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_DOWN ) )
  1998. {
  1999. engine->ExecuteClientCmd( "spec_mode" );
  2000. }
  2001. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_RIGHT ) )
  2002. {
  2003. engine->ExecuteClientCmd( "spec_next" );
  2004. }
  2005. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_LEFT ) )
  2006. {
  2007. engine->ExecuteClientCmd( "spec_prev" );
  2008. }
  2009. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_UP ) )
  2010. {
  2011. engine->ExecuteClientCmd( "spec_mode" );
  2012. }
  2013. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_DOWN ) )
  2014. {
  2015. engine->ExecuteClientCmd( "spec_mode" );
  2016. }
  2017. }
  2018. #ifdef TF_CLIENT_DLL
  2019. // certain tf menus want '0' to cancel, not escape.
  2020. if( gViewPortInterface )
  2021. {
  2022. IViewPortPanel *panel = gViewPortInterface->GetActivePanel();
  2023. if( panel )
  2024. {
  2025. // if the class or team menus are up hide it with start
  2026. if( ( Q_strcmp( panel->GetName(), "class_blue" ) == 0 ) ||
  2027. ( Q_strcmp( panel->GetName(), "class_red" ) == 0 ) ||
  2028. ( Q_strcmp( panel->GetName(), "team" ) == 0 ) )
  2029. {
  2030. if ( m_pLeftButtonStates->buttonJustPressed( SIXENSE_BUTTON_START ) )
  2031. {
  2032. panel->ShowPanel( false );
  2033. }
  2034. }
  2035. else
  2036. {
  2037. // otherwise just do esc like normal
  2038. if ( m_pLeftButtonStates->buttonJustPressed( SIXENSE_BUTTON_START ) )
  2039. {
  2040. ::sendKeyState( 0x01, 1, 0); // 0x01 == esc
  2041. }
  2042. if ( m_pLeftButtonStates->buttonJustReleased( SIXENSE_BUTTON_START ) )
  2043. {
  2044. ::sendKeyState( 0x01, 0, 1); // 0x01 == esc
  2045. }
  2046. }
  2047. }
  2048. }
  2049. #else
  2050. // Press escape when the menu is up as well so we can exit
  2051. if ( m_pLeftButtonStates->buttonJustPressed( SIXENSE_BUTTON_START ) )
  2052. {
  2053. ::sendKeyState( 0x01, 1, 0); // 0x01 == esc
  2054. }
  2055. if ( m_pLeftButtonStates->buttonJustReleased( SIXENSE_BUTTON_START ) )
  2056. {
  2057. ::sendKeyState( 0x01, 0, 1); // 0x01 == esc
  2058. }
  2059. #endif
  2060. return;
  2061. }
  2062. #ifdef PORTAL2
  2063. if ( sixense_features_enabled.GetInt() )
  2064. {
  2065. SwitchViewModes( pCmd );
  2066. }
  2067. // If the radial menu is open, all we care about is the release of the radial menu buttons.
  2068. if ( engine->IsLocalPlayerResolvable() && IsRadialMenuOpen() )
  2069. {
  2070. if ( m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_2 ) || m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_4 ) )
  2071. {
  2072. engine->ClientCmd_Unrestricted( "-mouse_menu" );
  2073. }
  2074. if ( m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_1 ) || m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_3 ) )
  2075. {
  2076. engine->ClientCmd_Unrestricted( "-mouse_menu_taunt" );
  2077. }
  2078. pCmd->buttons = last_buttons;
  2079. pCmd->forwardmove = last_forwardmove;
  2080. pCmd->sidemove = last_sidemove;
  2081. pCmd->sixense_flags = last_sixense_flags;
  2082. return;
  2083. }
  2084. #endif
  2085. if( pCmd )
  2086. {
  2087. float forward = m_pFPSPlayerMovement->getWalkDir()[1] * cl_forwardspeed.GetFloat();
  2088. float side = m_pFPSPlayerMovement->getWalkDir()[0] * cl_sidespeed.GetFloat();
  2089. float angle = -GetViewAngleOffset()[YAW] * M_PI / 180.0f;
  2090. pCmd->forwardmove = forward * cosf( angle ) - side * sinf( angle );
  2091. pCmd->sidemove = forward * sinf( angle ) + side * cosf( angle );
  2092. }
  2093. #ifdef CSTRIKE15
  2094. if ( m_pLeftButtonStates->buttonJustPressed( SIXENSE_BUTTON_START ) )
  2095. {
  2096. BasePanel()->ShowScaleformPauseMenu( true );
  2097. }
  2098. #else
  2099. if ( m_pLeftButtonStates->buttonJustPressed( SIXENSE_BUTTON_START ) )
  2100. {
  2101. ::sendKeyState( 0x01, 1, 0); // 0x01 == esc scancode
  2102. }
  2103. if ( m_pLeftButtonStates->buttonJustReleased( SIXENSE_BUTTON_START ) )
  2104. {
  2105. ::sendKeyState( 0x01, 0, 1); // 0x01 == esc scancode
  2106. }
  2107. #endif
  2108. #ifdef TF_CLIENT_DLL
  2109. CHudMenuSpyDisguise *pSpyMenu = ( CHudMenuSpyDisguise * )GET_HUDELEMENT( CHudMenuSpyDisguise );
  2110. if( pSpyMenu->IsVisible() )
  2111. {
  2112. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_LEFT ) )
  2113. {
  2114. pSpyMenu->HudElementKeyInput( 1, KEY_1, "slot1" );
  2115. }
  2116. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_UP ) )
  2117. {
  2118. pSpyMenu->HudElementKeyInput( 1, KEY_2, "slot2" );
  2119. }
  2120. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_RIGHT ) )
  2121. {
  2122. pSpyMenu->HudElementKeyInput( 1, KEY_3, "slot3" );
  2123. }
  2124. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_DOWN ) )
  2125. {
  2126. engine->ExecuteClientCmd( "lastinv" );
  2127. }
  2128. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_JOYSTICK ) )
  2129. {
  2130. pSpyMenu->HudElementKeyInput( 1, KEY_3, "disguiseteam" );
  2131. }
  2132. }
  2133. CHudMenuEngyBuild *pEngBuildMenu = ( CHudMenuEngyBuild * )GET_HUDELEMENT( CHudMenuEngyBuild );
  2134. if( pEngBuildMenu->IsVisible() )
  2135. {
  2136. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_3 ) )
  2137. {
  2138. pEngBuildMenu->HudElementKeyInput( 1, KEY_1, "slot1" );
  2139. }
  2140. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_1 ) )
  2141. {
  2142. pEngBuildMenu->HudElementKeyInput( 1, KEY_2, "slot2" );
  2143. }
  2144. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_2 ) )
  2145. {
  2146. pEngBuildMenu->HudElementKeyInput( 1, KEY_3, "slot3" );
  2147. }
  2148. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_4 ) )
  2149. {
  2150. pEngBuildMenu->HudElementKeyInput( 1, KEY_4, "slot4" );
  2151. }
  2152. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_DOWN ) )
  2153. {
  2154. engine->ExecuteClientCmd( "lastinv" );
  2155. }
  2156. }
  2157. CHudMenuEngyDestroy *pEngDestroyMenu = ( CHudMenuEngyDestroy * )GET_HUDELEMENT( CHudMenuEngyDestroy );
  2158. if( pEngDestroyMenu->IsVisible() )
  2159. {
  2160. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_3 ) )
  2161. {
  2162. pEngDestroyMenu->HudElementKeyInput( 1, KEY_1, "slot1" );
  2163. }
  2164. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_1 ) )
  2165. {
  2166. pEngDestroyMenu->HudElementKeyInput( 1, KEY_2, "slot2" );
  2167. }
  2168. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_2 ) )
  2169. {
  2170. pEngDestroyMenu->HudElementKeyInput( 1, KEY_3, "slot3" );
  2171. }
  2172. if( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_4 ) )
  2173. {
  2174. pEngDestroyMenu->HudElementKeyInput( 1, KEY_4, "slot4" );
  2175. }
  2176. if( m_pRightButtonStates->stickJustPressed( sixenseUtils::IButtonStates::DIR_DOWN ) )
  2177. {
  2178. engine->ExecuteClientCmd( "lastinv" );
  2179. }
  2180. }
  2181. if ( TFGameRules() && TFGameRules()->IsInTraining() )
  2182. {
  2183. if( m_pLeftButtonStates->absoluteTiltJustStarted( sixenseUtils::IButtonStates::DIR_UP ) )
  2184. {
  2185. engine->ClientCmd_Unrestricted( "training_continue" );
  2186. }
  2187. }
  2188. #endif
  2189. #ifdef PORTAL2
  2190. // coop ping
  2191. if ( m_pLeftButtonStates->justPressed( SIXENSE_BUTTON_1 ) || m_pLeftButtonStates->justPressed( SIXENSE_BUTTON_2 ) )
  2192. {
  2193. engine->ClientCmd_Unrestricted( "+mouse_menu" );
  2194. }
  2195. if ( m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_1 ) || m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_2 ) )
  2196. {
  2197. engine->ClientCmd_Unrestricted( "-mouse_menu" );
  2198. }
  2199. // coop remote view "tab"
  2200. if ( m_pRightButtonStates->justPressed( SIXENSE_BUTTON_START ) )
  2201. {
  2202. engine->ClientCmd_Unrestricted( "+remote_view" );
  2203. new_buttons |= IN_REMOTE_VIEW;
  2204. }
  2205. if ( m_pRightButtonStates->justReleased( SIXENSE_BUTTON_START ) )
  2206. {
  2207. engine->ClientCmd_Unrestricted( "-remote_view" );
  2208. new_buttons &= ~IN_REMOTE_VIEW;
  2209. }
  2210. // walk
  2211. //if ( m_pLeftButtonStates->justPressed( SIXENSE_BUTTON_2 ) )
  2212. //{
  2213. // new_buttons |= IN_WALK;
  2214. //}
  2215. //if ( m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_2 ) )
  2216. //{
  2217. // new_buttons &= ~IN_WALK;
  2218. //}
  2219. // coop gesture
  2220. if ( m_pLeftButtonStates->justPressed( SIXENSE_BUTTON_3 ) || m_pLeftButtonStates->justPressed( SIXENSE_BUTTON_4 ) )
  2221. {
  2222. engine->ClientCmd_Unrestricted( "+mouse_menu_taunt" );
  2223. }
  2224. if ( m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_3 ) || m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_4 ) )
  2225. {
  2226. engine->ClientCmd_Unrestricted( "-mouse_menu_taunt" );
  2227. }
  2228. // zooom
  2229. {
  2230. static bool momentary_zoom = false;
  2231. static int momentary_zoom_release_count = 0;
  2232. static double zoom_button_press_time = 0.0;
  2233. // button just pressed and we're not already zooming, start zoom
  2234. if ( m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_JOYSTICK ) )
  2235. {
  2236. new_buttons |= IN_ZOOM;
  2237. momentary_zoom_release_count = 30;
  2238. momentary_zoom = false;
  2239. zoom_button_press_time = sixenseUtils::Time::getTimeInMilliseconds();
  2240. }
  2241. // check to see how long the zoom button was pressed. If it was really short, we should lock the zoom
  2242. if ( ( m_pACD->controllers[m_nRightIndex].buttons & SIXENSE_BUTTON_JOYSTICK ) &&
  2243. !momentary_zoom &&
  2244. ( C_BasePlayer::GetLocalPlayer() && C_BasePlayer::GetLocalPlayer()->IsZoomed() ) )
  2245. {
  2246. double current_time = sixenseUtils::Time::getTimeInMilliseconds();
  2247. double button_held_time = current_time - zoom_button_press_time;
  2248. const double momentary_thresh_time = sixense_zoom_momentary_time.GetFloat();
  2249. if ( button_held_time > momentary_thresh_time )
  2250. {
  2251. momentary_zoom = true;
  2252. }
  2253. }
  2254. // button released and we're zooming
  2255. if ( momentary_zoom && m_pRightButtonStates->buttonJustReleased( SIXENSE_BUTTON_JOYSTICK ) )
  2256. {
  2257. new_buttons |= IN_ZOOM;
  2258. momentary_zoom_release_count = 30;
  2259. }
  2260. // delay release
  2261. if ( momentary_zoom_release_count )
  2262. {
  2263. momentary_zoom_release_count--;
  2264. if ( momentary_zoom_release_count == 0 )
  2265. {
  2266. new_buttons &= ~IN_ZOOM;
  2267. }
  2268. }
  2269. }
  2270. if ( sixense_features_enabled.GetInt() )
  2271. {
  2272. // 1d cube scaling on L4 button, use IN_SCALE1D for button mapping
  2273. if ( m_pACD->controllers[m_nLeftIndex].buttons & SIXENSE_BUTTON_BUMPER )
  2274. {
  2275. new_buttons |= IN_SCALE1D;
  2276. }
  2277. else
  2278. {
  2279. new_buttons &= ~IN_SCALE1D;
  2280. }
  2281. // Button one-to-one
  2282. if ( !sixense_dist_one_to_one_enabled.GetInt() && sixense_auto_one_to_one_enabled.GetInt() &&
  2283. IsHoldingObject() &&
  2284. !m_bIs1to1ModeScaling &&
  2285. ( C_Portal_Player::GetLocalPortalPlayer() &&
  2286. !C_Portal_Player::GetLocalPortalPlayer()->IsScalingUseItem() &&
  2287. !C_Portal_Player::GetLocalPortalPlayer()->IsScalingUseItemTurret() ) )
  2288. {
  2289. // one to one
  2290. if ( m_pFPSEvents->eventStarted( sixenseUtils::IFPSEvents::ONE_TO_ONE_CARRY ) )
  2291. {
  2292. SetOneToOneMode( true );
  2293. }
  2294. if ( m_pFPSEvents->eventStopped( sixenseUtils::IFPSEvents::ONE_TO_ONE_CARRY ) )
  2295. {
  2296. SetOneToOneMode( false );
  2297. }
  2298. }
  2299. // dist one-to-one
  2300. if ( sixense_dist_one_to_one_enabled.GetInt() &&
  2301. IsHoldingObject() &&
  2302. !m_bIs1to1ModeScaling &&
  2303. !m_bScalingLockedOneToOne &&
  2304. ( C_Portal_Player::GetLocalPortalPlayer() &&
  2305. !C_Portal_Player::GetLocalPortalPlayer()->IsScalingUseItem() &&
  2306. !C_Portal_Player::GetLocalPortalPlayer()->IsScalingUseItemTurret() ) )
  2307. {
  2308. Vector3 cur_pos = Vector3( m_pACD->controllers[m_nRightIndex].pos );
  2309. Vector3 delta_vec = cur_pos - m_GrabPos;
  2310. static float fEndOneToOneRatchetDelayTime = 0.0f;
  2311. if ( !IsInOneToOneMode() &&
  2312. ( C_Portal_Player::GetLocalPortalPlayer() && C_Portal_Player::GetLocalPortalPlayer()->GetActiveWeapon() ) &&
  2313. ( ( delta_vec[2] < -sixense_dist_one_to_one_dist.GetFloat() ) || // start one to one if you reach forwards
  2314. ( delta_vec[1] > 1.5f * sixense_dist_one_to_one_dist.GetFloat() ) ) ) // start one to one if you raise up 1.5 times the dist too...
  2315. {
  2316. SetOneToOneMode( true );
  2317. fEndOneToOneRatchetDelayTime = 0.0f;
  2318. }
  2319. else if ( IsInOneToOneMode() &&
  2320. ( delta_vec[2] > -sixense_dist_one_to_one_dist.GetFloat() ) &&
  2321. ( delta_vec[1] < 1.5f * sixense_dist_one_to_one_dist.GetFloat() ) &&
  2322. ( delta_vec.length() < 2.0f*sixense_dist_one_to_one_dist.GetFloat() ) &&
  2323. IsAimingForwards() )
  2324. {
  2325. // if ratcheting when ending 1to1 mode, first end ratchet, then end 1to1 after a short delay so end ratchet can propogate to server
  2326. if ( m_bIs1to1ModeRatcheting )
  2327. {
  2328. m_pFPSViewAngles->setRatcheting( false );
  2329. m_bIs1to1ModeRatcheting = false;
  2330. fEndOneToOneRatchetDelayTime = gpGlobals->curtime;
  2331. }
  2332. else if ( ( fEndOneToOneRatchetDelayTime == 0.0f ) ||
  2333. ( ( gpGlobals->curtime - fEndOneToOneRatchetDelayTime ) > sixense_dist_one_to_one_end_ratchet_delay.GetFloat() ) )
  2334. {
  2335. SetOneToOneMode( false );
  2336. fEndOneToOneRatchetDelayTime = 0.0f;
  2337. }
  2338. }
  2339. else
  2340. {
  2341. fEndOneToOneRatchetDelayTime = 0.0f;
  2342. }
  2343. }
  2344. // portal tweaking
  2345. if ( sixense_portal_tweaking_enabled.GetInt() )
  2346. {
  2347. // portal 1 tweaking on left trigger
  2348. if ( m_bIsLeftTriggerDown )
  2349. {
  2350. new_buttons |= IN_TWEAK2;
  2351. }
  2352. else
  2353. {
  2354. new_buttons &= ~IN_TWEAK2;
  2355. }
  2356. // portal 2 tweaking on right trigger
  2357. if ( m_bIsRightTriggerDown )
  2358. {
  2359. new_buttons |= IN_TWEAK1;
  2360. }
  2361. else
  2362. {
  2363. new_buttons &= ~IN_TWEAK1;
  2364. }
  2365. }
  2366. }
  2367. bool jump_disabled = false;
  2368. if ( m_pLeftButtonStates->justReleased( SIXENSE_BUTTON_BUMPER ) )
  2369. {
  2370. m_fDisableJumpUntil = ( sixenseUtils::Time::getTimeInMilliseconds() ) + sixense_scale_disables_jump_timer.GetFloat() * 1000.0f;
  2371. }
  2372. // If the disable jump timer is set
  2373. if ( m_fDisableJumpUntil != 0.0 && ( m_fDisableJumpUntil > ( sixenseUtils::Time::getTimeInMilliseconds() ) ) )
  2374. {
  2375. jump_disabled = true;
  2376. }
  2377. // Or if we're actively scaling
  2378. if ( new_buttons & IN_SCALE1D )
  2379. {
  2380. jump_disabled = true;
  2381. }
  2382. // jump
  2383. if ( !jump_disabled &&
  2384. ( m_pFPSEvents->eventStarted( sixenseUtils::IFPSEvents::JUMP ) ||
  2385. ( m_pRightButtonStates->justPressed( SIXENSE_BUTTON_3 ) || m_pRightButtonStates->justPressed( SIXENSE_BUTTON_4 ) ) ) )
  2386. {
  2387. new_buttons |= IN_JUMP;
  2388. }
  2389. if ( m_pFPSEvents->eventStopped( sixenseUtils::IFPSEvents::JUMP ) ||
  2390. ( m_pRightButtonStates->justReleased( SIXENSE_BUTTON_3 ) || m_pRightButtonStates->justReleased( SIXENSE_BUTTON_4 ) ) )
  2391. {
  2392. new_buttons &= ~IN_JUMP;
  2393. }
  2394. {
  2395. static bool momentary_hold = false;
  2396. static bool holding_object = false;
  2397. static int momentary_hold_release_count = 0;
  2398. static double hold_button_press_time = 0.0;
  2399. if( m_pRightButtonStates->justPressed( SIXENSE_BUTTON_1 ) )
  2400. {
  2401. // button just pressed and we're not already holding, start holding
  2402. // This is a hack to center wheatley. Basically recenter whenever the 1 button is pressed. It's ok to recenter on drop.
  2403. SetBaseOffset();
  2404. m_GrabPos = Vector3( m_pACD->controllers[m_nRightIndex].pos );
  2405. }
  2406. if ( ( m_pRightButtonStates->justPressed( SIXENSE_BUTTON_1 ) || m_pRightButtonStates->justPressed( SIXENSE_BUTTON_2 ) ) && !( last_buttons & IN_USE ) )
  2407. {
  2408. new_buttons |= IN_USE;
  2409. momentary_hold_release_count = 30;
  2410. momentary_hold = false;
  2411. hold_button_press_time = sixenseUtils::Time::getTimeInMilliseconds();
  2412. if( !IsHoldingObject() ) {
  2413. // If distance one to one is enabled, reset the hold offset on pickup
  2414. if ( sixense_dist_one_to_one_enabled.GetInt() )
  2415. {
  2416. SetBaseOffset();
  2417. }
  2418. m_GrabPos = Vector3( m_pACD->controllers[m_nRightIndex].pos );
  2419. }
  2420. }
  2421. if ( ( ( m_pACD->controllers[m_nRightIndex].buttons & SIXENSE_BUTTON_1 ) || ( m_pACD->controllers[m_nRightIndex].buttons & SIXENSE_BUTTON_2 ) ) && !momentary_hold )
  2422. {
  2423. // Check to see how long the hold button was pressed. If it was really short, we should
  2424. // lock the hold
  2425. double current_time = sixenseUtils::Time::getTimeInMilliseconds();
  2426. double button_held_time = current_time - hold_button_press_time;
  2427. const double momentary_thresh_time = sixense_pickup_momentary_time.GetFloat();
  2428. if ( button_held_time > momentary_thresh_time )
  2429. {
  2430. momentary_hold = true;
  2431. }
  2432. }
  2433. // button released and we're holding, drop it
  2434. if ( momentary_hold && ( m_pRightButtonStates->justReleased( SIXENSE_BUTTON_1 ) || m_pRightButtonStates->justReleased( SIXENSE_BUTTON_2 ) ) && IsHoldingObject() )
  2435. {
  2436. new_buttons |= IN_USE;
  2437. momentary_hold_release_count = 30;
  2438. }
  2439. if ( momentary_hold_release_count )
  2440. {
  2441. momentary_hold_release_count--;
  2442. if ( momentary_hold_release_count == 0 )
  2443. {
  2444. new_buttons &= ~IN_USE;
  2445. }
  2446. }
  2447. }
  2448. unsigned char ratchet_button = SIXENSE_BUTTON_BUMPER;
  2449. if ( m_pRightButtonStates->buttonJustPressed( ratchet_button ) )
  2450. {
  2451. m_pFPSViewAngles->setRatcheting( true );
  2452. if ( m_bIsIn1to1Mode )
  2453. {
  2454. m_bIs1to1ModeRatcheting = true;
  2455. }
  2456. }
  2457. if ( m_pRightButtonStates->buttonJustReleased( ratchet_button ) )
  2458. {
  2459. m_pFPSViewAngles->setRatcheting( false );
  2460. m_bIs1to1ModeRatcheting = false;
  2461. }
  2462. #endif
  2463. if( pCmd )
  2464. {
  2465. pCmd->buttons = new_buttons;
  2466. last_forwardmove = pCmd->forwardmove;
  2467. last_sidemove = pCmd->sidemove;
  2468. }
  2469. last_buttons = new_buttons;
  2470. #ifdef SIXENSE_PLAYER_DATA
  2471. last_sixense_flags = pCmd->sixense_flags;
  2472. #endif
  2473. }
  2474. #ifdef PORTAL2
  2475. bool SixenseInput::SendKeyToActiveWindow(ButtonCode_t key)
  2476. {
  2477. KeyValues *kv = new KeyValues( "KeyCodePressed", "code", key );
  2478. vgui::ivgui()->PostMessage(vgui::input()->GetFocus(), kv, NULL);
  2479. return true;
  2480. }
  2481. #endif
  2482. void SixenseInput::SixenseUpdateMouseCursor()
  2483. {
  2484. #if defined( HL2_CLIENT_DLL ) || defined( TF_CLIENT_DLL )
  2485. // If there's no mouse cursor visible, don't ever move the mouse or click here.
  2486. // Gesture bindings can still call 'sixense_left_click' for times when a click is
  2487. // necessary but no mouse cursor.
  2488. if( vgui::surface() && !vgui::surface()->IsCursorVisible() )
  2489. {
  2490. return;
  2491. }
  2492. #endif
  2493. if( !sixense_left_handed.GetInt() ) {
  2494. m_nLeftIndex = m_pControllerManager->getIndex( sixenseUtils::IControllerManager::P1L );
  2495. m_nRightIndex = m_pControllerManager->getIndex( sixenseUtils::IControllerManager::P1R );
  2496. } else {
  2497. m_nLeftIndex = m_pControllerManager->getIndex( sixenseUtils::IControllerManager::P1R );
  2498. m_nRightIndex = m_pControllerManager->getIndex( sixenseUtils::IControllerManager::P1L );
  2499. }
  2500. #if 0
  2501. sixenseUtils::mouseAndKeyboardWin32::processQueue();
  2502. #endif
  2503. // Keep track of when the left button is down so we can turn it off if we leave mouse mode
  2504. static bool left_clicked = false;
  2505. if ( m_nRightIndex == -1 ) return;
  2506. m_pSixenseAPI->sixenseGetAllNewestData( m_pACD );
  2507. static unsigned char last_seq = 0;
  2508. unsigned char seq = m_pACD->controllers[m_nRightIndex].sequence_number;
  2509. if ( last_seq == seq )
  2510. {
  2511. return;
  2512. }
  2513. last_seq = seq;
  2514. if ( !InMenuMode() )
  2515. {
  2516. // If we're not in mouse mode, check to see if we just entered it and need to switch out.
  2517. if ( left_clicked )
  2518. {
  2519. ::sendMouseClick( 0, 1 );
  2520. left_clicked = false;
  2521. }
  2522. return;
  2523. }
  2524. //m_pLeftButtonStates->update( &m_pACD->controllers[m_nLeftIndex] );
  2525. //m_pRightButtonStates->update( &m_pACD->controllers[m_nRightIndex] );
  2526. if ( m_pLeftButtonStates->buttonJustPressed( SIXENSE_BUTTON_START ) )
  2527. {
  2528. ::sendKeyState( 0x01, 1, 0); // 0x01 == esc scancode
  2529. }
  2530. if ( m_pLeftButtonStates->buttonJustReleased( SIXENSE_BUTTON_START ) )
  2531. {
  2532. ::sendKeyState( 0x01, 0, 1); // 0x01 == esc scancode
  2533. }
  2534. if( m_pRightButtonStates->triggerJustPressed() || m_pRightButtonStates->buttonJustPressed( SIXENSE_BUTTON_1 ) )
  2535. {
  2536. ::sendMouseClick( 1, 0 );
  2537. left_clicked = true;
  2538. }
  2539. else if( m_pRightButtonStates->triggerJustReleased() || m_pRightButtonStates->buttonJustReleased( SIXENSE_BUTTON_1 ) )
  2540. {
  2541. ::sendMouseClick( 0, 1 );
  2542. left_clicked = false;
  2543. }
  2544. #ifdef WIN32
  2545. #ifdef PORTAL2
  2546. const char *window_name = "Portal 2 Sixense MotionPack";
  2547. #endif
  2548. #ifdef CSTRIKE15
  2549. const char *window_name = "Counter-Strike Source";
  2550. #endif
  2551. #ifdef HL2_CLIENT_DLL
  2552. const char *window_name = "Half-Life 2";
  2553. #endif
  2554. #ifdef TF_CLIENT_DLL
  2555. const int str_len = 128;
  2556. static char window_name[str_len] = "\0";
  2557. if( window_name[0] == '\0' )
  2558. {
  2559. const char *pGameDir = COM_GetModDirectory();
  2560. if ( FStrEq( pGameDir, "tf_beta" ) )
  2561. {
  2562. Q_strncpy( window_name, "Team Fortress 2 Beta", str_len );
  2563. }
  2564. else
  2565. {
  2566. Q_strncpy( window_name, "Team Fortress 2", str_len );
  2567. }
  2568. }
  2569. #endif
  2570. #ifdef TERROR
  2571. const char *window_name = "Left 4 Dead 2";
  2572. #endif
  2573. #if defined( CSTRIKE_DLL ) && !defined( CSTRIKE15 ) && !defined( TERROR )
  2574. const char *window_name = "Counter-Strike Source";
  2575. #endif
  2576. // Right now you can't move the mouse if the video hint panel is up.
  2577. if ( sixense_mouse_enabled.GetInt() && InMenuMode() && ( GetActiveWindow() == FindWindow( NULL, window_name ) ) )
  2578. #else
  2579. if ( sixense_mouse_enabled.GetInt() && InMenuMode() )
  2580. #endif
  2581. {
  2582. if ( m_pLaserPointer )
  2583. {
  2584. static Vector2 filtered_pixel_pos( -999, -999 );
  2585. int hand_index;
  2586. #ifdef PORTAL2
  2587. float pixel_scale = 0.6f;
  2588. if ( engine->IsLocalPlayerResolvable() && IsRadialMenuOpen() )
  2589. {
  2590. hand_index = m_nLeftIndex;
  2591. pixel_scale = 0.5f;
  2592. }
  2593. else
  2594. {
  2595. #else
  2596. {
  2597. #endif
  2598. hand_index = m_nRightIndex;
  2599. }
  2600. static bool radial_menu_up_last_frame = false;
  2601. #ifdef PORTAL2
  2602. if ( engine->IsLocalPlayerResolvable() && ( IsRadialMenuOpen() != radial_menu_up_last_frame ) )
  2603. {
  2604. // Switched modes, reset the filters...
  2605. filtered_pixel_pos = Vector2( -999, -999 ); // reset the filter
  2606. }
  2607. if ( engine->IsLocalPlayerResolvable() ) radial_menu_up_last_frame = IsRadialMenuOpen();
  2608. #endif
  2609. Vector3 view_angles;
  2610. sixenseMath::Matrix3 mat( m_pACD->controllers[hand_index].rot_mat );
  2611. Vector3 forwards;
  2612. Vector3 controller_forwards( 0, 0, -1 ), controller_up( 0, 1, 0 );
  2613. controller_forwards = mat * controller_forwards;
  2614. sixenseMath::Vector3 xz_projection( controller_forwards[0], 0.0f, controller_forwards[2] );
  2615. xz_projection.normalize();
  2616. // Compute the heading angle
  2617. float heading_dot = xz_projection * sixenseMath::Vector3( 0, 0, -1 );
  2618. float heading_angle = -acosf(heading_dot) * 180.0f/3.1415926f;
  2619. sixenseMath::Vector3 cross = xz_projection ^ sixenseMath::Vector3( 0, 0, -1 );
  2620. if( cross[1] > 0.0f ) {
  2621. heading_angle *= -1.0f;
  2622. }
  2623. // Round to +/- 180
  2624. if( heading_angle > 360.0f ) heading_angle -= 360.0f;
  2625. if( heading_angle < 0.0f ) heading_angle += 360.0f;
  2626. if( heading_angle > 180.0f ) heading_angle -= 360.0f;
  2627. // Compute the pitch
  2628. float pitch_angle = asin( controller_forwards[1] ) * 180.0f/3.1415926f;
  2629. float hfov, vfov;
  2630. GetFOV( &hfov, &vfov );
  2631. heading_angle *= sixense_mouse_sensitivity.GetFloat();
  2632. pitch_angle *= sixense_mouse_sensitivity.GetFloat();
  2633. Vector2 norm_coord( heading_angle/hfov + 0.5f, pitch_angle/vfov + 0.5f );
  2634. norm_coord[0] = clamp<float>( norm_coord[0], 0.0f, 1.0f );
  2635. norm_coord[1] = clamp<float>( norm_coord[1], 0.0f, 1.0f );
  2636. #ifdef WIN32
  2637. RECT win_rect;
  2638. GetWindowRect( GetActiveWindow(), &win_rect );
  2639. RECT desktop_rect;
  2640. GetWindowRect( GetDesktopWindow(), &desktop_rect );
  2641. // make top actually reference the top of the screen (windows has y=0 at the top)
  2642. win_rect.top = desktop_rect.bottom - win_rect.top;
  2643. win_rect.bottom = desktop_rect.bottom - win_rect.bottom;
  2644. int title_bar_height = GetSystemMetrics( SM_CYCAPTION ) + 2; // fudge these a little bit so we can't click on the borders
  2645. int border_size = GetSystemMetrics( SM_CYBORDER ) + 2;
  2646. win_rect.left += border_size;
  2647. win_rect.right -= border_size;
  2648. win_rect.bottom += border_size;
  2649. win_rect.top -= border_size + title_bar_height;
  2650. float desktop_width = (float)desktop_rect.right - (float)desktop_rect.left;
  2651. float desktop_height = (float)desktop_rect.bottom - (float)desktop_rect.top;
  2652. float win_norm_left = (float)win_rect.left/desktop_width, win_norm_right = (float)win_rect.right/desktop_width;
  2653. float win_norm_top = (float)win_rect.top/desktop_height, win_norm_bottom = (float)win_rect.bottom/desktop_height;
  2654. Vector2 abs_mouse_pos( win_norm_left + norm_coord[0] * (win_norm_right-win_norm_left), win_norm_bottom + norm_coord[1] * (win_norm_top-win_norm_bottom) );
  2655. static Vector2 last_pixel_pos;
  2656. const float mouse_filter_val = 0.8f;
  2657. if ( filtered_pixel_pos == Vector2( -999, -999 ) )
  2658. {
  2659. filtered_pixel_pos = abs_mouse_pos;
  2660. last_pixel_pos = abs_mouse_pos;
  2661. }
  2662. else
  2663. {
  2664. filtered_pixel_pos = filtered_pixel_pos * mouse_filter_val + abs_mouse_pos * ( 1.0f - mouse_filter_val );
  2665. }
  2666. ::sendAbsoluteMouseMove( filtered_pixel_pos[0], filtered_pixel_pos[1] );
  2667. #endif
  2668. }
  2669. }
  2670. }
  2671. QAngle SixenseInput::GetViewAngles()
  2672. {
  2673. if ( m_pSixenseAPI->sixenseIsControllerEnabled( 0 ) )
  2674. {
  2675. if ( m_pFPSViewAngles )
  2676. {
  2677. QAngle sixense_aim_angle;
  2678. sixenseMath::Vector3 vec = m_pFPSViewAngles->getViewAngles();
  2679. sixense_aim_angle[YAW] = vec[0];
  2680. sixense_aim_angle[PITCH] = vec[1];
  2681. sixense_aim_angle[ROLL] = vec[2];
  2682. return sixense_aim_angle;
  2683. }
  2684. }
  2685. return QAngle();
  2686. }
  2687. QAngle SixenseInput::GetViewAngleOffset()
  2688. {
  2689. if ( m_pSixenseAPI->sixenseIsControllerEnabled( 0 ) && !UseVR() )
  2690. {
  2691. if ( m_pFPSViewAngles )
  2692. {
  2693. QAngle sixense_aim_angle;
  2694. sixenseMath::Vector3 vec = m_pFPSViewAngles->getViewAngleOffset();
  2695. sixense_aim_angle[YAW] = vec[0];
  2696. sixense_aim_angle[PITCH] = vec[1];
  2697. sixense_aim_angle[ROLL] = vec[2];
  2698. #if defined( TF_CLIENT_DLL )
  2699. sixense_aim_angle *= g_fDemoChargeViewOffsetScale;
  2700. #endif
  2701. return sixense_aim_angle;
  2702. }
  2703. }
  2704. return QAngle(0.f, 0.f, 0.f );
  2705. }
  2706. #if 0
  2707. static void printmat( std::string name, sixenseMath::Matrix4 mat )
  2708. {
  2709. Msg( "%s\n", name.c_str() );
  2710. Msg( "[0][0]=%f [1][0]=%f [2][0]=%f [3][0]=%f \n", mat[0][0], mat[1][0], mat[2][0], mat[3][0] );
  2711. Msg( "[0][1]=%f [1][1]=%f [2][1]=%f [3][1]=%f \n", mat[0][1], mat[1][1], mat[2][1], mat[3][1] );
  2712. Msg( "[0][2]=%f [1][2]=%f [2][2]=%f [3][2]=%f \n", mat[0][2], mat[1][2], mat[2][2], mat[3][2] );
  2713. Msg( "[0][3]=%f [1][3]=%f [2][3]=%f [3][3]=%f \n\n", mat[0][3], mat[1][3], mat[2][3], mat[3][3] );
  2714. }
  2715. #endif
  2716. matrix3x4_t ConvertMatrix( sixenseMath::Matrix4 ss_mat )
  2717. {
  2718. sixenseMath::Matrix4 tmp_mat( ss_mat );
  2719. tmp_mat = tmp_mat * sixenseMath::Matrix4::rotation( -3.1415926f / 2.0f, Vector3( 1, 0, 0 ) );
  2720. tmp_mat = tmp_mat * sixenseMath::Matrix4::rotation( -3.1415926f / 2.0f, Vector3( 0, 0, 1 ) );
  2721. tmp_mat = tmp_mat * sixenseMath::Matrix4::rotation( 3.1415926f, Vector3( 0, 1, 0 ) );
  2722. tmp_mat = sixenseMath::Matrix4::rotation( -3.1415926f / 2.0f, Vector3( 1, 0, 0 ) ) * tmp_mat;
  2723. matrix3x4_t retmat;
  2724. MatrixInitialize( retmat, Vector( tmp_mat[3][0], tmp_mat[3][1], tmp_mat[3][2] ),
  2725. Vector( tmp_mat[0][0], tmp_mat[0][1], tmp_mat[0][2] ),
  2726. Vector( tmp_mat[1][0], tmp_mat[1][1], tmp_mat[1][2] ),
  2727. Vector( tmp_mat[2][0], tmp_mat[2][1], tmp_mat[2][2] ) );
  2728. return retmat;
  2729. }
  2730. void SixenseInput::Rumble( unsigned char index, unsigned char rumbleData, unsigned char rumbleFlags )
  2731. {
  2732. m_pSixenseAPI->sixenseTriggerVibration( 0, 10, 0 );
  2733. m_pSixenseAPI->sixenseTriggerVibration( 1, 10, 0 );
  2734. }
  2735. void SixenseInput::Rumble( unsigned char playerIndex, unsigned char handIndex, unsigned char rumbleData, unsigned char rumbleFlags )
  2736. {
  2737. // find controller index based on player and hand indexes
  2738. int controller_index = -1;
  2739. switch ( playerIndex )
  2740. {
  2741. case 0:
  2742. controller_index = m_pControllerManager->getIndex( ( 0 == handIndex ) ?
  2743. sixenseUtils::IControllerManager::P1L :
  2744. sixenseUtils::IControllerManager::P1R );
  2745. break;
  2746. case 1:
  2747. controller_index = m_pControllerManager->getIndex( ( 0 == handIndex ) ?
  2748. sixenseUtils::IControllerManager::P2L :
  2749. sixenseUtils::IControllerManager::P2R );
  2750. break;
  2751. case 2:
  2752. controller_index = m_pControllerManager->getIndex( ( 0 == handIndex ) ?
  2753. sixenseUtils::IControllerManager::P3L :
  2754. sixenseUtils::IControllerManager::P3R );
  2755. break;
  2756. case 3:
  2757. controller_index = m_pControllerManager->getIndex( ( 0 == handIndex ) ?
  2758. sixenseUtils::IControllerManager::P4L :
  2759. sixenseUtils::IControllerManager::P4R );
  2760. break;
  2761. default:
  2762. break;
  2763. }
  2764. // if valid controller index and rumble data, set vibration
  2765. if ( ( controller_index >= 0 ) && ( controller_index <= 3 ) )
  2766. {
  2767. m_pSixenseAPI->sixenseTriggerVibration( controller_index, rumbleData, 0 );
  2768. }
  2769. }
  2770. void SixenseInput::CreateGUI( vgui::VPANEL parent )
  2771. {
  2772. parent = vgui::ipanel()->GetParent( parent );
  2773. m_SixenseFrame = new SixenseGUIFrame( enginevgui->GetPanel( PANEL_ROOT ), "SixenseGUIFrame" );
  2774. m_SixenseFrame->SetVisible( false );
  2775. m_SixenseFrame->MoveToFront();
  2776. }
  2777. void SixenseInput::LoadDefaultSettings( int level )
  2778. {
  2779. if ( level == 0 )
  2780. {
  2781. Msg( "Loading default settings for low sensitivity\n" );
  2782. sixense_sensitivity_level.SetValue( 0 );
  2783. sixense_aim_freeaim_accel_band_exponent.SetValue( 1.0f );
  2784. sixense_aim_freeaim_auto_level_rate.SetValue( 1.0f );
  2785. sixense_aim_freeaim_accel_band_size.SetValue( 30 );
  2786. sixense_aim_freeaim_max_speed.SetValue( 5.0f );
  2787. sixense_aim_freeaim_dead_zone_radius.SetValue( 1.0f );
  2788. sixense_aim_freeaim_heading_multiplier.SetValue( 1.0f );
  2789. sixense_aim_freeaim_pitch_multiplier.SetValue( 1.0f );
  2790. sixense_exit_metroid_blend.SetValue( 0.9f );
  2791. //sixense_aim_freeaim_switch_blend_time_enter.SetValue( 0.8f );
  2792. sixense_aim_1to1_heading_multiplier.SetValue( 2.0f );
  2793. sixense_aim_1to1_pitch_multiplier.SetValue( 2.0f );
  2794. // dual analog (1.0 - 5.0)
  2795. sixense_feet_angles_offset_stick_spin_horiz_multiplier.SetValue( 2.5f );
  2796. sixense_feet_angles_offset_stick_spin_vert_multiplier.SetValue( 1.5f );
  2797. sixense_feet_angles_offset_stick_spin_exponent.SetValue( 1.0f );
  2798. }
  2799. else if ( level == 1 )
  2800. {
  2801. Msg( "Loading default settings for medium sensitivity\n" );
  2802. sixense_sensitivity_level.SetValue( 1 );
  2803. sixense_aim_freeaim_accel_band_exponent.SetValue( 1.0f );
  2804. sixense_aim_freeaim_auto_level_rate.SetValue( 1.0f );
  2805. sixense_aim_freeaim_accel_band_size.SetValue( 20 );
  2806. sixense_aim_freeaim_max_speed.SetValue( 7.0f );
  2807. sixense_aim_freeaim_dead_zone_radius.SetValue( 0.25f );
  2808. sixense_aim_freeaim_heading_multiplier.SetValue( 1.5f );
  2809. sixense_aim_freeaim_pitch_multiplier.SetValue( 1.5f );
  2810. //sixense_aim_freeaim_switch_blend_time_enter.SetValue( 1.5f );
  2811. sixense_exit_metroid_blend.SetValue( 0.925f );
  2812. sixense_aim_1to1_heading_multiplier.SetValue( 2.5f );
  2813. sixense_aim_1to1_pitch_multiplier.SetValue( 2.5f );
  2814. // dual analog (1.0 - 5.0)
  2815. sixense_feet_angles_offset_stick_spin_horiz_multiplier.SetValue( 5.0f );
  2816. sixense_feet_angles_offset_stick_spin_vert_multiplier.SetValue( 3.0f );
  2817. sixense_feet_angles_offset_stick_spin_exponent.SetValue( 1.0f );
  2818. }
  2819. else if ( level == 2 )
  2820. {
  2821. Msg( "Loading default settings for high sensitivity\n" );
  2822. sixense_sensitivity_level.SetValue( 2 );
  2823. sixense_aim_freeaim_accel_band_exponent.SetValue( 1.0f );
  2824. sixense_aim_freeaim_auto_level_rate.SetValue( 1.0f );
  2825. sixense_aim_freeaim_accel_band_size.SetValue( 15 );
  2826. sixense_aim_freeaim_max_speed.SetValue( 12.0f );
  2827. sixense_aim_freeaim_dead_zone_radius.SetValue( 0.0f );
  2828. sixense_aim_freeaim_heading_multiplier.SetValue( 1.75f );
  2829. sixense_aim_freeaim_pitch_multiplier.SetValue( 1.75f );
  2830. //sixense_aim_freeaim_switch_blend_time_enter.SetValue( 2.0f );
  2831. sixense_exit_metroid_blend.SetValue( 0.95f );
  2832. sixense_aim_1to1_heading_multiplier.SetValue( 3.0f );
  2833. sixense_aim_1to1_pitch_multiplier.SetValue( 3.0f );
  2834. // dual analog (1.0 - 5.0)
  2835. sixense_feet_angles_offset_stick_spin_horiz_multiplier.SetValue( 7.5f );
  2836. sixense_feet_angles_offset_stick_spin_vert_multiplier.SetValue( 4.5f );
  2837. sixense_feet_angles_offset_stick_spin_exponent.SetValue( 1.0f );
  2838. }
  2839. else if ( level == 3 )
  2840. {
  2841. Msg( "Loading default settings for custom sensitivity\n" );
  2842. sixense_sensitivity_level.SetValue( 3 );
  2843. }
  2844. else if ( level == 4 )
  2845. {
  2846. Msg( "Loading default settings for \"static xhair\" sensitivity\n" );
  2847. sixense_sensitivity_level.SetValue( 4 );
  2848. sixense_aim_freeaim_accel_band_exponent.SetValue( 1.0f );
  2849. sixense_aim_freeaim_auto_level_rate.SetValue( 1.0f );
  2850. sixense_aim_freeaim_accel_band_size.SetValue( 20 );
  2851. sixense_aim_freeaim_max_speed.SetValue( 30.0f );
  2852. sixense_aim_freeaim_dead_zone_radius.SetValue( 0.0f );
  2853. sixense_aim_freeaim_heading_multiplier.SetValue( 0.0f );
  2854. sixense_aim_freeaim_pitch_multiplier.SetValue( 0.0f );
  2855. //sixense_aim_freeaim_switch_blend_time_enter.SetValue( 2.0f );
  2856. sixense_exit_metroid_blend.SetValue( 0.95f );
  2857. sixense_aim_1to1_heading_multiplier.SetValue( 3.0f );
  2858. sixense_aim_1to1_pitch_multiplier.SetValue( 3.0f );
  2859. }
  2860. else if ( level == 5 )
  2861. {
  2862. Msg( "Loading default settings for \"quick turn\" sensitivity\n" );
  2863. sixense_sensitivity_level.SetValue( 5 );
  2864. sixense_aim_freeaim_accel_band_exponent.SetValue( 1.5f );
  2865. sixense_aim_freeaim_auto_level_rate.SetValue( 1.0f );
  2866. sixense_aim_freeaim_accel_band_size.SetValue( 20 );
  2867. sixense_aim_freeaim_max_speed.SetValue( 30.0f );
  2868. sixense_aim_freeaim_dead_zone_radius.SetValue( 0.0f );
  2869. sixense_aim_freeaim_heading_multiplier.SetValue( 1.75f );
  2870. sixense_aim_freeaim_pitch_multiplier.SetValue( 1.75f );
  2871. //sixense_aim_freeaim_switch_blend_time_enter.SetValue( 2.0f );
  2872. sixense_exit_metroid_blend.SetValue( 0.95f );
  2873. sixense_aim_1to1_heading_multiplier.SetValue( 3.0f );
  2874. sixense_aim_1to1_pitch_multiplier.SetValue( 3.0f );
  2875. }
  2876. }
  2877. SixenseGUIFrame::SixenseGUIFrame( vgui::VPANEL parent, char const *panelName ) :
  2878. BaseClass( NULL, panelName )
  2879. {
  2880. SetMoveable( false );
  2881. SetSizeable( false );
  2882. SetCloseButtonVisible( false );
  2883. SetParent( parent );
  2884. SetAutoDelete( false );
  2885. SetBgColor( Color( 100, 100, 100, 255 ) );
  2886. SetFgColor( Color( 100, 100, 100, 255 ) );
  2887. SetAlpha( 255 );
  2888. vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );
  2889. int img_x = 985, img_y = 565;
  2890. int frame_x = 1000, frame_y = 580;
  2891. SetSize( frame_x, frame_y );
  2892. m_ImagePanel = new vgui::ImagePanel( this, "SixenseControllerManagerImage" );
  2893. m_ImagePanel->SetDrawColor( Color( 255, 255, 255, 255 ) );
  2894. m_ImagePanel->SetShouldScaleImage( true );
  2895. m_ImagePanel->SetSize( img_x, img_y );
  2896. m_ImagePanel->SetPos( ( frame_x - img_x ) / 2, ( frame_y - img_y ) / 2 );
  2897. // Clear the title bar
  2898. SetTitle( "", false );
  2899. SetVisible( false );
  2900. MoveToCenterOfScreen();
  2901. }
  2902. void SixenseGUIFrame::SetVisible( bool state )
  2903. {
  2904. vgui::Frame::SetVisible( state );
  2905. m_ImagePanel->SetVisible( state );
  2906. // Make this panel modal while it's visible.
  2907. vgui::input()->SetAppModalSurface( state ? GetVPanel() : NULL );
  2908. }
  2909. SixenseGUIFrame::~SixenseGUIFrame()
  2910. {
  2911. if ( m_ImagePanel && !m_ImagePanel->IsAutoDeleteSet() )
  2912. {
  2913. delete m_ImagePanel;
  2914. m_ImagePanel = NULL;
  2915. }
  2916. }
  2917. void SixenseGUIFrame::setImage( CUtlString img_name )
  2918. {
  2919. m_ImagePanel->SetImage( img_name.String() );
  2920. SixenseInput::m_SixenseFrame->MoveToCenterOfScreen();
  2921. }
  2922. void SixenseInput::SetFilterLevel( float near_range, float near_val, float far_range, float far_val )
  2923. {
  2924. if ( near_range == 0.0f && far_range == 0.0f )
  2925. {
  2926. m_pSixenseAPI->sixenseSetFilterEnabled( 0 );
  2927. }
  2928. else
  2929. {
  2930. m_pSixenseAPI->sixenseSetFilterEnabled( 1 );
  2931. m_pSixenseAPI->sixenseSetFilterParams( near_range, near_val, far_range, far_val );
  2932. }
  2933. }
  2934. void SixenseInput::DisableGestures( int disable )
  2935. {
  2936. m_nGesturesDisabled = disable;
  2937. // if the player is ducking when we disable gestures do one last unduck to make sure they don't get stuck ducking
  2938. m_nShouldUnduck = true;
  2939. }
  2940. void SixenseInput::DisableFreeAimSpin( int disable )
  2941. {
  2942. m_nFreeaimSpinDisabled = disable;
  2943. if ( disable == 0 )
  2944. {
  2945. BlendView();
  2946. }
  2947. }
  2948. #ifdef PORTAL2
  2949. SixenseBaseWarning::SixenseBaseWarning(vgui::Panel *parent, const char *panelName) :
  2950. BaseClass(parent, panelName)
  2951. {
  2952. SetTitleBarVisible(false);
  2953. SetDeleteSelfOnClose(true);
  2954. SetProportional(true);
  2955. SetKeyBoardInputEnabled(false);
  2956. SetMouseInputEnabled(false);
  2957. SetMenuButtonVisible(false);
  2958. SetCloseButtonVisible(false);
  2959. SetMoveable(false);
  2960. SetSizeable(false);
  2961. SetVisible(true);
  2962. }
  2963. void SixenseBaseWarning::ApplySchemeSettings(vgui::IScheme *pScheme)
  2964. {
  2965. BaseClass::ApplySchemeSettings(pScheme);
  2966. LoadControlSettings("resource/UI/basemodui/SixenseBaseWarning.res");
  2967. }
  2968. #endif
  2969. //////
  2970. static void ToggleFrame()
  2971. {
  2972. g_pSixenseInput->CreateGUI( enginevgui->GetPanel( PANEL_TOOLS ) );
  2973. }
  2974. static ConCommand sixense_show_frame( "sixense_show_frame", ToggleFrame, "Show/hide Sixense UI." );
  2975. //////
  2976. static void SetBaseOffset()
  2977. {
  2978. g_pSixenseInput->SetBaseOffset();
  2979. }
  2980. ConCommand sixense_set_base_offset( "sixense_set_base_offset", SetBaseOffset );
  2981. //////
  2982. static void DisableGestures( const CCommand &args )
  2983. {
  2984. if ( args.ArgC() > 1 )
  2985. g_pSixenseInput->DisableGestures( atoi( args[1] ) );
  2986. }
  2987. ConCommand sixense_disable_gestures( "sixense_disable_gestures", DisableGestures );
  2988. //////
  2989. static void DisableFreeAimSpin( const CCommand &args )
  2990. {
  2991. if ( args.ArgC() > 1 )
  2992. g_pSixenseInput->DisableFreeAimSpin( atoi( args[1] ) );
  2993. }
  2994. ConCommand sixense_aim_freeaim_spin_disabled( "sixense_aim_freeaim_spin_disabled", DisableFreeAimSpin );
  2995. //////
  2996. void set_filter_params( const CCommand &args )
  2997. {
  2998. if ( args.ArgC() < 5 )
  2999. {
  3000. Msg( "Usage: set_filter_params <near_range> <near_val> <far_range> <far_val>\n" );
  3001. return;
  3002. }
  3003. g_pSixenseInput->SetFilterLevel( atof( args[1] ), atof( args[2] ), atof( args[3] ), atof( args[4] ) );
  3004. }
  3005. static ConCommand sixense_set_filter_params( "sixense_set_filter_params", set_filter_params );
  3006. //////
  3007. void SixenseSensitivityLevelChanged( IConVar *var, const char *pOldValue, float flOldValue )
  3008. {
  3009. g_pSixenseInput->LoadDefaultSettings( sixense_sensitivity_level.GetInt() );
  3010. }
  3011. //////
  3012. bool directionFromString( CUtlString dir_str, sixenseUtils::IButtonStates::Direction *dir ) {
  3013. if( dir_str == "up" ) {
  3014. *dir = sixenseUtils::IButtonStates::DIR_UP;
  3015. }
  3016. else if( dir_str == "down" )
  3017. {
  3018. *dir = sixenseUtils::IButtonStates::DIR_DOWN;
  3019. }
  3020. else if( dir_str == "left" )
  3021. {
  3022. *dir = sixenseUtils::IButtonStates::DIR_LEFT;
  3023. }
  3024. else if( dir_str == "right" )
  3025. {
  3026. *dir = sixenseUtils::IButtonStates::DIR_RIGHT;
  3027. }
  3028. else if( dir_str == "cw" )
  3029. {
  3030. *dir = sixenseUtils::IButtonStates::DIR_CW;
  3031. }
  3032. else if( dir_str == "ccw" )
  3033. {
  3034. *dir = sixenseUtils::IButtonStates::DIR_CCW;
  3035. }
  3036. else
  3037. {
  3038. Msg( "Unknown direction %s, shoud be 'up' 'down' 'left' 'right' 'cw' or 'ccw'\n", dir_str.String() );
  3039. return false;
  3040. }
  3041. return true;
  3042. }
  3043. bool buttonMaskFromString( CUtlString button, unsigned short *button_token ) {
  3044. if ( button == "1" )
  3045. {
  3046. *button_token = SIXENSE_BUTTON_1;
  3047. }
  3048. else if ( button == "2" )
  3049. {
  3050. *button_token = SIXENSE_BUTTON_2;
  3051. }
  3052. else if ( button == "3" )
  3053. {
  3054. *button_token = SIXENSE_BUTTON_3;
  3055. }
  3056. else if ( button == "4" )
  3057. {
  3058. *button_token = SIXENSE_BUTTON_4;
  3059. }
  3060. else if ( button == "start" )
  3061. {
  3062. *button_token = SIXENSE_BUTTON_START;
  3063. }
  3064. else if ( button == "bumper" )
  3065. {
  3066. *button_token = SIXENSE_BUTTON_BUMPER;
  3067. }
  3068. else if ( button == "joystick" )
  3069. {
  3070. *button_token = SIXENSE_BUTTON_JOYSTICK;
  3071. }
  3072. else
  3073. {
  3074. Msg( "Unknown button %s, shoud be '1' '2' '3' '4' 'start' 'trigger' or 'joystick'\n", button.String() );
  3075. return false;
  3076. }
  3077. return true;
  3078. }
  3079. bool actionFromString( CUtlString action_str, sixenseUtils::IButtonStates::ActionType *action ) {
  3080. if( action_str == "button_press" ) {
  3081. *action = sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS;
  3082. return true;
  3083. } else if( action_str == "trigger_press" ) {
  3084. *action = sixenseUtils::IButtonStates::ACTION_TRIGGER_PRESS;
  3085. return true;
  3086. } else if( action_str == "tilt_gesture" ) {
  3087. *action = sixenseUtils::IButtonStates::ACTION_TILT_GESTURE;
  3088. return true;
  3089. } else if( action_str == "point_gesture" ) {
  3090. *action = sixenseUtils::IButtonStates::ACTION_POINT_GESTURE;
  3091. return true;
  3092. } else if( action_str == "velocity_gesture" ) {
  3093. *action = sixenseUtils::IButtonStates::ACTION_VELOCITY_GESTURE;
  3094. return true;
  3095. } else if( action_str == "joystick_move" ) {
  3096. *action = sixenseUtils::IButtonStates::ACTION_JOYSTICK_MOVE;
  3097. return true;
  3098. } else {
  3099. Msg( "Unknown action %s, shoud be 'button_press' 'trigger_press' 'tilt_gesture' 'point_gesture' 'velocity_gesture' or 'joystick_move'\n", action_str.String() );
  3100. *action = sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS;
  3101. return false;
  3102. }
  3103. }
  3104. bool handFromString( CUtlString hand_str, int *hand ) {
  3105. if( hand_str == "left" ) {
  3106. *hand = 0;
  3107. } else if( hand_str == "right" ) {
  3108. *hand = 1;
  3109. } else {
  3110. Msg( "Unknown controller %s, should be 'left' or 'right'\n", hand_str.String() );
  3111. return false;
  3112. }
  3113. return true;
  3114. }
  3115. bool SixenseInput::AreBindingsDisabled()
  3116. {
  3117. if( InMenuMode() )
  3118. {
  3119. return true;
  3120. }
  3121. #ifdef TF_CLIENT_DLL
  3122. CHudMenuSpyDisguise *pSpyMenu = ( CHudMenuSpyDisguise * )GET_HUDELEMENT( CHudMenuSpyDisguise );
  3123. if( pSpyMenu->IsVisible() )
  3124. {
  3125. return true;
  3126. }
  3127. CHudMenuEngyBuild *pEngBuildMenu = ( CHudMenuEngyBuild * )GET_HUDELEMENT( CHudMenuEngyBuild );
  3128. if( pEngBuildMenu->IsVisible() )
  3129. {
  3130. return true;
  3131. }
  3132. CHudMenuEngyDestroy *pEngDestroyMenu = ( CHudMenuEngyDestroy * )GET_HUDELEMENT( CHudMenuEngyDestroy );
  3133. if( pEngDestroyMenu->IsVisible() )
  3134. {
  3135. return true;
  3136. }
  3137. #endif
  3138. return false;
  3139. }
  3140. // Console commands for controlling sixense_binds
  3141. static void SixenseBind( const CCommand &args )
  3142. {
  3143. if ( args.ArgC() != 5 && args.ArgC() != 6 )
  3144. {
  3145. Msg( "Usage: sixense_bind <hand_left_or_right> <action> <argument> <on_press_command> [<on_release_command>]\n" );
  3146. return;
  3147. }
  3148. CUtlString hand_str( args[1] ), action_str( args[2] ), argument_str( args[3] ), press_command( args[4] ), release_command;
  3149. if( args.ArgC() == 6 )
  3150. {
  3151. release_command = args[5];
  3152. }
  3153. if( g_pSixenseInput->GetGestureBindings() )
  3154. {
  3155. g_pSixenseInput->GetGestureBindings()->AddBinding( hand_str, action_str, argument_str, press_command, release_command );
  3156. }
  3157. }
  3158. static void SixenseListBindings( const CCommand &args )
  3159. {
  3160. if ( args.ArgC() != 1 )
  3161. {
  3162. Msg( "Usage: sixense_list_bindings\n" );
  3163. return;
  3164. }
  3165. if( g_pSixenseInput->GetGestureBindings() )
  3166. {
  3167. g_pSixenseInput->GetGestureBindings()->ListBindings();
  3168. }
  3169. }
  3170. static void SixenseWriteBindings( const CCommand &args )
  3171. {
  3172. if ( args.ArgC() != 1 && args.ArgC() != 2 )
  3173. {
  3174. Msg( "Usage: sixense_write_bindings [<filename>]\n" );
  3175. return;
  3176. }
  3177. CUtlString filename;
  3178. if( args.ArgC() == 2 )
  3179. {
  3180. filename = args[1];
  3181. }
  3182. if( g_pSixenseInput->GetGestureBindings() )
  3183. {
  3184. g_pSixenseInput->GetGestureBindings()->WriteBindings( filename );
  3185. }
  3186. }
  3187. static void SixenseClearBindings( const CCommand &args )
  3188. {
  3189. if( g_pSixenseInput->GetGestureBindings() )
  3190. {
  3191. g_pSixenseInput->GetGestureBindings()->ClearBindings();
  3192. }
  3193. }
  3194. static void SixenseCreateDefaultBindings( const CCommand &args )
  3195. {
  3196. if( g_pSixenseInput->GetGestureBindings() )
  3197. {
  3198. g_pSixenseInput->GetGestureBindings()->CreateDefaultBindings();
  3199. }
  3200. }
  3201. static void SixenseDeleteBinding( const CCommand &args )
  3202. {
  3203. if ( args.ArgC() != 2 )
  3204. {
  3205. Msg( "Usage: sixense_delete_binding <binding_number>\n" );
  3206. return;
  3207. }
  3208. int num = atoi( args[1] );
  3209. if( g_pSixenseInput->GetGestureBindings() )
  3210. {
  3211. g_pSixenseInput->GetGestureBindings()->DeleteBinding( num );
  3212. }
  3213. }
  3214. static ConCommand sixense_bind_command( "sixense_bind", SixenseBind, "Bind a concommand to a button." );
  3215. static ConCommand sixense_list_bindings_cc( "sixense_list_bindings", SixenseListBindings, "List the sixense bindings." );
  3216. static ConCommand sixense_write_bindings_cc( "sixense_write_bindings", SixenseWriteBindings, "Save the sixense bindings to a file." );
  3217. static ConCommand sixense_clear_bindings_cc( "sixense_clear_bindings", SixenseClearBindings, "Clear all sixense bindings." );
  3218. static ConCommand sixense_delete_binding_cc( "sixense_delete_binding", SixenseDeleteBinding, "Delete a single binding by index." );
  3219. static ConCommand sixense_create_default_binding_cc( "sixense_create_default_bindings", SixenseCreateDefaultBindings, "Erase all current bindings and load the default bindings for this game." );
  3220. //////
  3221. void SelectMachinegun()
  3222. {
  3223. GetHudWeaponSelection()->SelectSlot(2);
  3224. }
  3225. ConCommand sixense_select_machinegun( "sixense_select_machinegun", SelectMachinegun );
  3226. //////
  3227. void SixenseInput::StartRatchet()
  3228. {
  3229. if( m_pFPSViewAngles )
  3230. {
  3231. m_pFPSViewAngles->setRatcheting( true );
  3232. }
  3233. }
  3234. void StartRatchet()
  3235. {
  3236. g_pSixenseInput->StartRatchet();
  3237. }
  3238. ConCommand sixense_start_ratchet( "+sixense_ratchet", StartRatchet );
  3239. //////
  3240. void SixenseInput::StopRatchet()
  3241. {
  3242. if( m_pFPSViewAngles )
  3243. {
  3244. m_pFPSViewAngles->setRatcheting( false );
  3245. }
  3246. }
  3247. void StopRatchet()
  3248. {
  3249. g_pSixenseInput->StopRatchet();
  3250. }
  3251. ConCommand sixense_stop_ratchet( "-sixense_ratchet", StopRatchet );
  3252. //////
  3253. void SelectPistol()
  3254. {
  3255. GetHudWeaponSelection()->SelectSlot(1);
  3256. }
  3257. ConCommand sixense_select_pistol( "sixense_select_pistol", SelectPistol );
  3258. //////
  3259. void SelectGrenade()
  3260. {
  3261. #ifdef CSTRIKE15
  3262. GetHudWeaponSelection()->CycleToNextGrenadeOrBomb();
  3263. #endif
  3264. }
  3265. ConCommand sixense_select_grenade( "sixense_select_grenade", SelectGrenade );
  3266. //////
  3267. void SelectMelee()
  3268. {
  3269. GetHudWeaponSelection()->SelectSlot(3);
  3270. }
  3271. ConCommand sixense_select_melee( "sixense_select_melee", SelectMelee );
  3272. //////
  3273. void SixenseInput::LeftPointGesture( bool start )
  3274. {
  3275. if( start )
  3276. m_pLeftButtonStates->startPointGesture();
  3277. else
  3278. m_pLeftButtonStates->stopPointGesture();
  3279. }
  3280. //////
  3281. void SixenseInput::RightPointGesture( bool start )
  3282. {
  3283. if( start )
  3284. m_pRightButtonStates->startPointGesture();
  3285. else
  3286. m_pRightButtonStates->stopPointGesture();
  3287. }
  3288. //////
  3289. void StartLeftPointGesture()
  3290. {
  3291. g_pSixenseInput->LeftPointGesture( true );
  3292. }
  3293. ConCommand sixense_start_left_point_gesture( "+sixense_left_point_gesture", StartLeftPointGesture );
  3294. //////
  3295. void StopLeftPointGesture()
  3296. {
  3297. g_pSixenseInput->LeftPointGesture( false );
  3298. }
  3299. ConCommand sixense_stop_left_point_gesture( "-sixense_left_point_gesture", StopLeftPointGesture );
  3300. //////
  3301. void StartRightPointGesture()
  3302. {
  3303. g_pSixenseInput->RightPointGesture( true );
  3304. }
  3305. ConCommand sixense_start_right_point_gesture( "+sixense_right_point_gesture", StartRightPointGesture );
  3306. //////
  3307. void StopRightPointGesture()
  3308. {
  3309. g_pSixenseInput->RightPointGesture( false );
  3310. }
  3311. ConCommand sixense_stop_right_point_gesture( "-sixense_right_point_gesture", StopRightPointGesture );
  3312. #endif //SIXENSE