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

4278 lines
122 KiB

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