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.

898 lines
27 KiB

  1. #include "cbase.h"
  2. #ifdef SIXENSE
  3. #include "in_sixense_gesture_bindings.h"
  4. #include "filesystem.h"
  5. #ifdef TF_CLIENT_DLL
  6. #include "tf_gamerules.h"
  7. #endif
  8. #include <isixense.h>
  9. #include <sixense_math.hpp>
  10. #include <sixense_utils/interfaces.hpp>
  11. SixenseGestureBindings::SixenseGestureBindings()
  12. {
  13. }
  14. // Help deallocate a binding
  15. void SixenseGestureBindings::FreeStrings( GestureBinding binding )
  16. {
  17. if( binding.m_pActivateCommand )
  18. {
  19. free( binding.m_pActivateCommand );
  20. }
  21. if( binding.m_pDeactivateCommand )
  22. {
  23. free( binding.m_pDeactivateCommand );
  24. }
  25. }
  26. // add a binding to the list. Calls should be in the form:
  27. // AddBinding( "left", "button_press", "start", "+dota_camera_follow", "" );
  28. //
  29. // args:
  30. // hand_str = "left" or "right"
  31. // action_str = 'button_press' 'trigger_press' 'tilt_gesture' 'point_gesture' 'velocity_gesture' or 'joystick_move'
  32. // argument_str depends on action_str, see below for details
  33. // press_command_str is the concommand executed on start of the action (ie button press) and release_command_str on stop (ie button release)
  34. // release_command_str can be the empty string if no stop action is desired
  35. // if the press_command_str begins with "+", an equivalent "-" is set to the release_command automatically
  36. void SixenseGestureBindings::AddBinding( CUtlString hand_str, CUtlString action_str, CUtlString argument_str, CUtlString press_command_str, CUtlString release_command_str )
  37. {
  38. GestureBinding binding;
  39. // Convert from strings to enums
  40. sixenseUtils::IButtonStates::ActionType action;
  41. if( !ActionFromString( action_str, &action ) )
  42. {
  43. return;
  44. }
  45. binding.m_Action = action;
  46. int hand;
  47. if( !HandFromString( hand_str, &hand ) ) {
  48. return;
  49. }
  50. binding.m_iHand = hand;
  51. // handle argument_str per-action type
  52. if( action == sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS )
  53. {
  54. // button_press takes a button argument
  55. unsigned short button_token;
  56. if( !ButtonMaskFromString( argument_str, &button_token ) )
  57. {
  58. return;
  59. }
  60. binding.m_iArgument = button_token;
  61. }
  62. else if( action == sixenseUtils::IButtonStates::ACTION_TRIGGER_PRESS )
  63. {
  64. // trigger press has no argument
  65. binding.m_iArgument = 0;
  66. }
  67. else
  68. {
  69. // all other actions take a direction
  70. sixenseUtils::IButtonStates::Direction dir;
  71. if( !DirectionFromString( argument_str, &dir ) )
  72. {
  73. return;
  74. }
  75. binding.m_iArgument = dir;
  76. }
  77. // copy the activate command
  78. binding.m_pActivateCommand = strdup( press_command_str.String() );
  79. binding.m_bAutoMirrored = false;
  80. // if there is an explicit release_command, use it
  81. if ( !release_command_str.IsEmpty() )
  82. {
  83. binding.m_pDeactivateCommand = strdup( release_command_str.String() );
  84. }
  85. else
  86. {
  87. // otherwise try to generate a release command
  88. // see if it starts with a +, if so, add an off command
  89. if( press_command_str[0] == '+' )
  90. {
  91. binding.m_pDeactivateCommand = strdup( press_command_str.String() );
  92. binding.m_pDeactivateCommand[0] = '-';
  93. binding.m_bAutoMirrored = true;
  94. }
  95. else
  96. {
  97. // Just leave release command null
  98. binding.m_pDeactivateCommand = NULL;
  99. }
  100. }
  101. // Try to keep a single binding per 'action' 'hand' 'arg' pair, ie one per button.
  102. // We may want to allow multiple if people think it would be useful...
  103. FOR_EACH_LL( m_GestureBindingList, it )
  104. {
  105. GestureBinding existing_binding = m_GestureBindingList[it];
  106. if( binding.m_Action == existing_binding.m_Action &&
  107. binding.m_iArgument == existing_binding.m_iArgument &&
  108. binding.m_iHand == existing_binding.m_iHand )
  109. {
  110. // Already the same binding active, delete it
  111. FreeStrings( existing_binding );
  112. m_GestureBindingList.Remove( it );
  113. break;
  114. }
  115. }
  116. // add to the list of bindings
  117. m_GestureBindingList.AddToTail( binding );
  118. }
  119. // just return the binding count
  120. int SixenseGestureBindings::GetNumBindings()
  121. {
  122. return m_GestureBindingList.Count();
  123. }
  124. // pretty print all the bindings to the console
  125. void SixenseGestureBindings::ListBindings()
  126. {
  127. const int strbuflen=256;
  128. char strbuf[strbuflen];
  129. // Just go through all the bindings, use helpers to convert from tokens to strings, and print.
  130. int i=0;
  131. FOR_EACH_LL( m_GestureBindingList, it )
  132. {
  133. GestureBinding binding = m_GestureBindingList[it];
  134. if( HandTokenToStr( binding.m_iHand, strbuf, strbuflen ) )
  135. {
  136. Msg("%d)\t%s", i, strbuf);
  137. }
  138. if( ActionTokenToStr( (sixenseUtils::IButtonStates::ActionType)binding.m_Action, strbuf, strbuflen ) )
  139. {
  140. Msg("\t%s", strbuf);
  141. }
  142. if( binding.m_Action == sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS )
  143. {
  144. if( ButtonTokenToStr( binding.m_iArgument, strbuf, strbuflen ) )
  145. {
  146. Msg("\t%s", strbuf);
  147. }
  148. }
  149. // these all have the same arguments (left, right, up...)
  150. else if( binding.m_Action == sixenseUtils::IButtonStates::ACTION_JOYSTICK_MOVE ||
  151. binding.m_Action == sixenseUtils::IButtonStates::ACTION_POINT_GESTURE ||
  152. binding.m_Action == sixenseUtils::IButtonStates::ACTION_VELOCITY_GESTURE ||
  153. binding.m_Action == sixenseUtils::IButtonStates::ACTION_TILT_GESTURE )
  154. {
  155. if( DirectionTokenToStr( binding.m_iArgument, strbuf, strbuflen ) )
  156. {
  157. Msg("\t%s", strbuf);
  158. }
  159. } else if( binding.m_Action == sixenseUtils::IButtonStates::ACTION_TRIGGER_PRESS )
  160. {
  161. Msg("\t"); // no argument
  162. }
  163. Msg("\t\"%s\"", binding.m_pActivateCommand);
  164. if( binding.m_pDeactivateCommand && !binding.m_bAutoMirrored ) // only print deactivated command if we didn't generate it.
  165. {
  166. Msg("\t\"%s\"", binding.m_pDeactivateCommand);
  167. }
  168. Msg("\n");
  169. i++;
  170. }
  171. }
  172. // Write the current set of bindings to a file, formatted so that the file can be 'exec'ed.
  173. void SixenseGestureBindings::WriteBindings( CUtlString filename_str )
  174. {
  175. FileHandle_t hFile;
  176. const int filenamelen = 1024;
  177. char filename[filenamelen];
  178. // If no filename was provided, use "cfg/sixense_bindings.cfg"
  179. if( !filename_str.IsEmpty() )
  180. {
  181. Q_snprintf( filename, filenamelen, "%s\\cfg\\%s", engine->GetGameDirectory(), filename_str.String() );
  182. }
  183. else
  184. {
  185. Q_snprintf( filename, filenamelen, "%s\\cfg\\sixense_bindings.cfg", engine->GetGameDirectory() );
  186. }
  187. Msg("writing bindings to %s\n", filename );
  188. hFile = filesystem->Open( filename, "wt" );
  189. if( !hFile )
  190. {
  191. return;
  192. }
  193. const int strbuflen=256;
  194. char strbuf[strbuflen];
  195. char writebuf[strbuflen];
  196. // Go through all the bindings, convert from tokens to strings, build up the command string and write it to the file
  197. FOR_EACH_LL( m_GestureBindingList, it )
  198. {
  199. GestureBinding binding = m_GestureBindingList[it];
  200. if( HandTokenToStr( binding.m_iHand, strbuf, strbuflen ) )
  201. {
  202. Q_snprintf( writebuf, strbuflen, "sixense_bind \"%s\"", strbuf);
  203. filesystem->Write( writebuf, strlen(writebuf), hFile );
  204. }
  205. if( ActionTokenToStr( (sixenseUtils::IButtonStates::ActionType)binding.m_Action, strbuf, strbuflen ) )
  206. {
  207. Q_snprintf( writebuf, strbuflen, " \"%s\"", strbuf);
  208. filesystem->Write( writebuf, strlen(writebuf), hFile );
  209. }
  210. if( binding.m_Action == sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS ) {
  211. if( ButtonTokenToStr( binding.m_iArgument, strbuf, strbuflen ) )
  212. {
  213. Q_snprintf( writebuf, strbuflen, " \"%s\"", strbuf);
  214. filesystem->Write( writebuf, strlen(writebuf), hFile );
  215. }
  216. }
  217. // these all have the same arguments (left, right, up...)
  218. else if( binding.m_Action == sixenseUtils::IButtonStates::ACTION_JOYSTICK_MOVE ||
  219. binding.m_Action == sixenseUtils::IButtonStates::ACTION_POINT_GESTURE ||
  220. binding.m_Action == sixenseUtils::IButtonStates::ACTION_VELOCITY_GESTURE ||
  221. binding.m_Action == sixenseUtils::IButtonStates::ACTION_TILT_GESTURE )
  222. {
  223. if( DirectionTokenToStr( binding.m_iArgument, strbuf, strbuflen ) )
  224. {
  225. Q_snprintf( writebuf, strbuflen, " \"%s\"", strbuf);
  226. filesystem->Write( writebuf, strlen(writebuf), hFile );
  227. }
  228. } else if( binding.m_Action == sixenseUtils::IButtonStates::ACTION_TRIGGER_PRESS )
  229. {
  230. Q_snprintf( writebuf, strbuflen, " \"\""); // no argument
  231. filesystem->Write( writebuf, strlen(writebuf), hFile );
  232. }
  233. Q_snprintf( writebuf, strbuflen, " \"%s\"", binding.m_pActivateCommand);
  234. filesystem->Write( writebuf, strlen(writebuf), hFile );
  235. if( binding.m_pDeactivateCommand && !binding.m_bAutoMirrored ) // only print deactivated command if we didn't generate it.
  236. {
  237. Q_snprintf( writebuf, strbuflen, " \"%s\"", binding.m_pDeactivateCommand);
  238. filesystem->Write( writebuf, strlen(writebuf), hFile );
  239. }
  240. Q_snprintf( writebuf, strbuflen, "\n");
  241. filesystem->Write( writebuf, strlen(writebuf), hFile );
  242. }
  243. filesystem->Close( hFile );
  244. }
  245. // Erase all the bindings. Right now this will cause code in in_sixense.cpp to detect the lack of bindings and immediately
  246. // create defaults. I think that's good.
  247. void SixenseGestureBindings::ClearBindings()
  248. {
  249. FOR_EACH_LL( m_GestureBindingList, it )
  250. {
  251. FreeStrings( m_GestureBindingList[it] );
  252. }
  253. m_GestureBindingList.RemoveAll();
  254. }
  255. // Delete a specific binding by index. 'sixense_list_bindings' prints the indicies that can be passed to delete.
  256. void SixenseGestureBindings::DeleteBinding( int num )
  257. {
  258. if( num < 0 || num > m_GestureBindingList.Count()-1 ) return;
  259. int count=0;
  260. FOR_EACH_LL( m_GestureBindingList, it )
  261. {
  262. if( count == num )
  263. {
  264. FreeStrings( m_GestureBindingList[it] );
  265. m_GestureBindingList.Remove(it);
  266. Msg("Removed %d\n", count );
  267. break;
  268. }
  269. count++;
  270. }
  271. }
  272. void SixenseGestureBindings::CreateDefaultBindings()
  273. {
  274. ClearBindings();
  275. #if defined ( CSTRIKE_DLL ) && !defined( TERROR )
  276. AddBinding( "left", "tilt_gesture", "ccw", "+reload", "" );
  277. AddBinding( "left", "tilt_gesture", "down", "+duck", "" );
  278. AddBinding( "left", "tilt_gesture", "up", "+jump", "" );
  279. AddBinding( "left", "trigger_press", "", "+attack2", "" );
  280. AddBinding( "left", "button_press", "start", "cancelselect", "" );
  281. AddBinding( "left", "button_press", "bumper", "+duck", "" );
  282. AddBinding( "left", "button_press", "joystick", "drop", "" );
  283. AddBinding( "left", "button_press", "1", "autobuy", "" );
  284. AddBinding( "left", "button_press", "2", "rebuy", "" );
  285. AddBinding( "left", "button_press", "3", "impulse 201", "" );
  286. AddBinding( "left", "button_press", "4", "chooseteam", "" );
  287. AddBinding( "left", "point_gesture", "up", "slot3", "" );
  288. AddBinding( "left", "point_gesture", "down", "slot4", "" );
  289. AddBinding( "right", "joystick_move", "up", "buymenu", "buymenu 0" );
  290. AddBinding( "right", "joystick_move", "left", "invprev", "" );
  291. AddBinding( "right", "joystick_move", "right", "invnext", "" );
  292. AddBinding( "right", "joystick_move", "down", "nightvision", "" );
  293. AddBinding( "right", "button_press", "1", "+sixense_ratchet", "" );
  294. AddBinding( "right", "button_press", "2", "+use", "" );
  295. AddBinding( "right", "button_press", "3", "+speed", "" );
  296. AddBinding( "right", "button_press", "4", "+voicerecord", "" );
  297. AddBinding( "right", "button_press", "joystick", "impulse 100", "" );
  298. AddBinding( "right", "button_press", "bumper", "+jump", "" );
  299. AddBinding( "right", "trigger_press", "", "+attack", "" );
  300. AddBinding( "right", "button_press", "start", "+showscores", "" );
  301. #elif defined( TERROR )
  302. AddBinding( "left", "tilt_gesture", "ccw", "+reload", "" );
  303. AddBinding( "left", "tilt_gesture", "down", "+duck", "" );
  304. AddBinding( "left", "tilt_gesture", "up", "+jump", "" );
  305. AddBinding( "left", "trigger_press", "", "+attack2", "" );
  306. AddBinding( "left", "button_press", "start", "cancelselect", "" );
  307. AddBinding( "left", "button_press", "bumper", "+sixense_left_point_gesture", "" );
  308. AddBinding( "left", "button_press", "joystick", "+use", "" );
  309. AddBinding( "left", "point_gesture", "left", "invprev", "" );
  310. AddBinding( "left", "point_gesture", "right", "invnext", "" );
  311. AddBinding( "left", "point_gesture", "up", "slot3", "" );
  312. AddBinding( "left", "point_gesture", "down", "slot4", "" );
  313. AddBinding( "left", "button_press", "2", "phys_swap", "" );
  314. AddBinding( "left", "button_press", "1", "+sixense_ratchet", "" );
  315. AddBinding( "left", "button_press", "3", "+speed", "" );
  316. AddBinding( "left", "button_press", "4", "+voicerecord", "" );
  317. AddBinding( "right", "joystick_move", "up", "+zoom", "" );
  318. AddBinding( "right", "joystick_move", "left", "invprev", "" );
  319. AddBinding( "right", "joystick_move", "right", "invnext", "" );
  320. AddBinding( "right", "joystick_move", "down", "lastinv", "" );
  321. AddBinding( "right", "button_press", "2", "Vote no", "" );
  322. AddBinding( "right", "button_press", "1", "Vote yes", "" );
  323. AddBinding( "right", "button_press", "3", "askconnect_accept", "" );
  324. AddBinding( "right", "button_press", "4", "jpeg", "" );
  325. AddBinding( "right", "button_press", "joystick", "impulse 100", "" );
  326. AddBinding( "right", "button_press", "bumper", "+duck", "" );
  327. AddBinding( "right", "trigger_press", "", "+attack", "" );
  328. AddBinding( "right", "button_press", "1", "+sixense_ratchet", "" );
  329. #elif defined( DOTA_DLL )
  330. AddBinding( "left", "button_press", "start", "+dota_camera_follow", "" );
  331. AddBinding( "left", "button_press", "3", "dota_ability_execute 0", "" );
  332. AddBinding( "left", "button_press", "1", "dota_ability_execute 1", "" );
  333. AddBinding( "left", "button_press", "2", "dota_ability_execute 2", "" );
  334. AddBinding( "left", "button_press", "4", "dota_ability_execute 5", "" );
  335. AddBinding( "left", "joystick_move", "left", "dota_ability_execute 3", "" );
  336. AddBinding( "left", "joystick_move", "right", "dota_ability_execute 4", "" );
  337. AddBinding( "left", "joystick_move", "up", "mc_attack", "" );
  338. AddBinding( "left", "joystick_move", "down", "+sixense_left_alt", "" ); // ping
  339. AddBinding( "left", "trigger_press", "", "+sixense_camera_pan", "" );
  340. AddBinding( "left", "button_press", "bumper", "+sixense_camera_drag", "" );
  341. AddBinding( "right", "button_press", "bumper", "+sixense_left_shift", "" ); // queue
  342. AddBinding( "right", "button_press", "joystick", "sixense_mouse_set_origin", "" );
  343. AddBinding( "right", "button_press", "start", "toggleshoppanel", "" );
  344. AddBinding( "right", "joystick_move", "down", "+sixense_left_ctrl", "" ); // ??
  345. AddBinding( "right", "joystick_move", "up", "+showscores", "" );
  346. AddBinding( "right", "button_press", "3", "+attack", "" );
  347. AddBinding( "right", "button_press", "1", "+attack2", "" );
  348. AddBinding( "right", "button_press", "4", "+voicerecord", "" );
  349. AddBinding( "right", "button_press", "3", "+sixense_left_click", "" );
  350. AddBinding( "right", "button_press", "1", "+sixense_right_click", "" );
  351. AddBinding( "right", "trigger_press", "", "+sixense_grid 0", "" );
  352. AddBinding( "right", "button_press", "2", "+sixense_grid 1", "" );
  353. #elif defined( TF_CLIENT_DLL )
  354. AddBinding( "left", "tilt_gesture", "ccw", "+reload", "" );
  355. AddBinding( "left", "tilt_gesture", "down", "+duck", "" );
  356. AddBinding( "left", "tilt_gesture", "up", "+jump", "" );
  357. AddBinding( "left", "tilt_gesture", "right", "impulse 201", "" );
  358. AddBinding( "left", "trigger_press", "", "+attack2", "" );
  359. AddBinding( "left", "button_press", "start", "cancelselect", "" );
  360. AddBinding( "left", "button_press", "bumper", "+duck", "" );
  361. AddBinding( "left", "point_gesture", "up", "slot3", "" );
  362. AddBinding( "left", "point_gesture", "down", "slot4", "" );
  363. AddBinding( "left", "button_press", "3", "open_charinfo_direct", "" );
  364. AddBinding( "left", "button_press", "1", "changeclass", "" );
  365. AddBinding( "left", "button_press", "2", "changeteam", "" );
  366. AddBinding( "left", "button_press", "4", "lastdisguise", "" );
  367. AddBinding( "left", "button_press", "joystick", "voicemenu 0 0", "" );
  368. AddBinding( "right", "joystick_move", "up", "use_action_slot_item", "" );
  369. AddBinding( "right", "joystick_move", "left", "invprev", "" );
  370. AddBinding( "right", "joystick_move", "right", "invnext", "" );
  371. AddBinding( "right", "joystick_move", "down", "lastinv", "" );
  372. AddBinding( "right", "button_press", "1", "+sixense_ratchet", "" );
  373. AddBinding( "right", "button_press", "2", "cl_decline_first_notification", "" );
  374. AddBinding( "right", "button_press", "3", "+voicerecord", "" );
  375. AddBinding( "right", "button_press", "4", "cl_trigger_first_notification", "" );
  376. AddBinding( "right", "button_press", "joystick", "dropitem", "" );
  377. AddBinding( "right", "button_press", "bumper", "taunt", "" );
  378. AddBinding( "right", "trigger_press", "", "+attack", "" );
  379. AddBinding( "right", "button_press", "start", "+showscores", "" );
  380. #else
  381. AddBinding( "left", "tilt_gesture", "ccw", "+reload", "" );
  382. AddBinding( "left", "tilt_gesture", "down", "+duck", "" );
  383. AddBinding( "left", "tilt_gesture", "up", "+jump", "" );
  384. AddBinding( "left", "trigger_press", "", "+attack2", "" );
  385. AddBinding( "left", "button_press", "start", "cancelselect", "" );
  386. AddBinding( "left", "button_press", "bumper", "+sixense_left_point_gesture", "" );
  387. AddBinding( "left", "button_press", "joystick", "+use", "" );
  388. AddBinding( "left", "point_gesture", "left", "invprev", "" );
  389. AddBinding( "left", "point_gesture", "right", "invnext", "" );
  390. AddBinding( "left", "point_gesture", "up", "slot3", "" );
  391. AddBinding( "left", "point_gesture", "down", "slot4", "" );
  392. AddBinding( "right", "joystick_move", "up", "+zoom", "" );
  393. AddBinding( "right", "joystick_move", "left", "invprev", "" );
  394. AddBinding( "right", "joystick_move", "right", "invnext", "" );
  395. AddBinding( "right", "joystick_move", "down", "lastinv", "" );
  396. AddBinding( "right", "button_press", "2", "phys_swap", "" );
  397. AddBinding( "right", "button_press", "1", "+sixense_ratchet", "" );
  398. AddBinding( "right", "button_press", "3", "+speed", "" );
  399. AddBinding( "right", "button_press", "4", "+voicerecord", "" );
  400. AddBinding( "right", "button_press", "joystick", "impulse 100", "" );
  401. AddBinding( "right", "button_press", "bumper", "+duck", "" );
  402. AddBinding( "right", "trigger_press", "", "+attack", "" );
  403. #endif
  404. }
  405. // Called each frame with the latest controller info. sixenseUtils::IButtonStates are sixenseUtils classes that look for various transitions of
  406. // controller state, whether it's 'buttonJustPressed', or analog joysticks 'joystickJustPushed(up)'. It now has support for motion triggers like
  407. // 'controllerJustTilted(left)'
  408. void SixenseGestureBindings::UpdateBindings( sixenseUtils::IButtonStates *pLeftButtonStates, sixenseUtils::IButtonStates *pRightButtonStates, bool bIsMenuVisible )
  409. {
  410. // go through all the bindings and see if any of the desired actions just transitioned on or off
  411. FOR_EACH_LL( m_GestureBindingList, it )
  412. {
  413. GestureBinding binding = m_GestureBindingList[it];
  414. if( binding.m_iHand == 0 )
  415. {
  416. // left hand
  417. // just started?
  418. if( pLeftButtonStates->justStarted( (sixenseUtils::IButtonStates::ActionType)binding.m_Action, binding.m_iArgument ) )
  419. {
  420. if( binding.m_pActivateCommand )
  421. {
  422. // Allow per-game authorization of commmands when the menu is up
  423. if( bIsMenuVisible && !AllowMenuCommand( binding.m_pActivateCommand ) )
  424. {
  425. continue;
  426. }
  427. // Allow per-game authorization of commmands
  428. if( !AllowCommand( binding.m_pActivateCommand ) )
  429. {
  430. continue;
  431. }
  432. engine->ClientCmd_Unrestricted( binding.m_pActivateCommand );
  433. //Msg("activate: %s\n", binding.m_pActivateCommand );
  434. }
  435. }
  436. // just stopped?
  437. if( pLeftButtonStates->justStopped( (sixenseUtils::IButtonStates::ActionType)binding.m_Action, binding.m_iArgument ) )
  438. {
  439. if( binding.m_pDeactivateCommand )
  440. {
  441. engine->ClientCmd_Unrestricted( binding.m_pDeactivateCommand );
  442. //Msg("deactivate: %s\n", binding.m_pDeactivateCommand );
  443. }
  444. }
  445. }
  446. else
  447. {
  448. // right hand
  449. // just started?
  450. if( pRightButtonStates->justStarted( (sixenseUtils::IButtonStates::ActionType)binding.m_Action, binding.m_iArgument ) )
  451. {
  452. if( binding.m_pActivateCommand )
  453. {
  454. // Allow per-game authorization of commmands when the menu is up
  455. if( bIsMenuVisible && !AllowMenuCommand( binding.m_pActivateCommand ) )
  456. {
  457. continue;
  458. }
  459. // Allow per-game authorization of commmands
  460. if( !AllowCommand( binding.m_pActivateCommand ) )
  461. {
  462. continue;
  463. }
  464. engine->ClientCmd_Unrestricted( binding.m_pActivateCommand );
  465. //Msg("activate: %s\n", binding.m_pActivateCommand );
  466. }
  467. }
  468. // just stopped?
  469. if( pRightButtonStates->justStopped( (sixenseUtils::IButtonStates::ActionType)binding.m_Action, binding.m_iArgument ) )
  470. {
  471. if( binding.m_pDeactivateCommand )
  472. {
  473. engine->ClientCmd_Unrestricted( binding.m_pDeactivateCommand );
  474. //Msg("deactivate: %s\n", binding.m_pDeactivateCommand );
  475. }
  476. }
  477. }
  478. }
  479. }
  480. // Give games an opportunity to block commands
  481. bool SixenseGestureBindings::AllowCommand( char *pActivateCommand )
  482. {
  483. #ifdef TF_CLIENT_DLL
  484. if ( TFGameRules() && TFGameRules()->IsInTraining() && TFGameRules()->IsWaitingForTrainingContinue() )
  485. {
  486. if( Q_strcmp( pActivateCommand, "+jump" ) == 0 )
  487. {
  488. return false;
  489. }
  490. }
  491. #endif
  492. return true;
  493. }
  494. // If the menu is up, most bindings are blocked. Allow some of them to be activated...
  495. bool SixenseGestureBindings::AllowMenuCommand( char *pActivateCommand )
  496. {
  497. #ifdef TF_CLIENT_DLL
  498. if( Q_strcmp( pActivateCommand, "+showscores" ) == 0 )
  499. {
  500. // Allow for showscores when in-menu
  501. return true;
  502. }
  503. #endif
  504. return false;
  505. }
  506. // from here down are just helper funcs to convert between enums and strings and back
  507. bool SixenseGestureBindings::DirectionFromString( CUtlString dir_str, sixenseUtils::IButtonStates::Direction *dir )
  508. {
  509. if( dir_str == "up" )
  510. {
  511. *dir = sixenseUtils::IButtonStates::DIR_UP;
  512. }
  513. else if( dir_str == "down" )
  514. {
  515. *dir = sixenseUtils::IButtonStates::DIR_DOWN;
  516. }
  517. else if( dir_str == "left" )
  518. {
  519. *dir = sixenseUtils::IButtonStates::DIR_LEFT;
  520. }
  521. else if( dir_str == "right" )
  522. {
  523. *dir = sixenseUtils::IButtonStates::DIR_RIGHT;
  524. }
  525. else if( dir_str == "cw" )
  526. {
  527. *dir = sixenseUtils::IButtonStates::DIR_CW;
  528. }
  529. else if( dir_str == "ccw" )
  530. {
  531. *dir = sixenseUtils::IButtonStates::DIR_CCW;
  532. }
  533. else
  534. {
  535. Msg( "Unknown direction %s, shoud be 'up' 'down' 'left' 'right' 'cw' or 'ccw'\n", dir_str.String() );
  536. return false;
  537. }
  538. return true;
  539. }
  540. bool SixenseGestureBindings::ButtonMaskFromString( CUtlString button, unsigned short *button_token )
  541. {
  542. if ( button == "1" )
  543. {
  544. *button_token = SIXENSE_BUTTON_1;
  545. }
  546. else if ( button == "2" )
  547. {
  548. *button_token = SIXENSE_BUTTON_2;
  549. }
  550. else if ( button == "3" )
  551. {
  552. *button_token = SIXENSE_BUTTON_3;
  553. }
  554. else if ( button == "4" )
  555. {
  556. *button_token = SIXENSE_BUTTON_4;
  557. }
  558. else if ( button == "start" )
  559. {
  560. *button_token = SIXENSE_BUTTON_START;
  561. }
  562. else if ( button == "bumper" )
  563. {
  564. *button_token = SIXENSE_BUTTON_BUMPER;
  565. }
  566. else if ( button == "joystick" )
  567. {
  568. *button_token = SIXENSE_BUTTON_JOYSTICK;
  569. }
  570. else
  571. {
  572. Msg( "Unknown button %s, shoud be '1' '2' '3' '4' 'start' 'trigger' or 'joystick'\n", button.String() );
  573. return false;
  574. }
  575. return true;
  576. }
  577. bool SixenseGestureBindings::ActionFromString( CUtlString action_str, sixenseUtils::IButtonStates::ActionType *action )
  578. {
  579. if( action_str == "button_press" )
  580. {
  581. *action = sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS;
  582. return true;
  583. }
  584. else if( action_str == "trigger_press" )
  585. {
  586. *action = sixenseUtils::IButtonStates::ACTION_TRIGGER_PRESS;
  587. return true;
  588. }
  589. else if( action_str == "tilt_gesture" )
  590. {
  591. *action = sixenseUtils::IButtonStates::ACTION_TILT_GESTURE;
  592. return true;
  593. }
  594. else if( action_str == "point_gesture" )
  595. {
  596. *action = sixenseUtils::IButtonStates::ACTION_POINT_GESTURE;
  597. return true;
  598. }
  599. else if( action_str == "velocity_gesture" )
  600. {
  601. *action = sixenseUtils::IButtonStates::ACTION_VELOCITY_GESTURE;
  602. return true;
  603. }
  604. else if( action_str == "joystick_move" )
  605. {
  606. *action = sixenseUtils::IButtonStates::ACTION_JOYSTICK_MOVE;
  607. return true;
  608. }
  609. else
  610. {
  611. Msg( "Unknown action %s, shoud be 'button_press' 'trigger_press' 'tilt_gesture' 'point_gesture' 'velocity_gesture' or 'joystick_move'\n", action_str.String() );
  612. *action = sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS;
  613. return false;
  614. }
  615. }
  616. bool SixenseGestureBindings::HandFromString( CUtlString hand_str, int *hand )
  617. {
  618. if( hand_str == "left" )
  619. {
  620. *hand = 0;
  621. }
  622. else if( hand_str == "right" )
  623. {
  624. *hand = 1;
  625. }
  626. else
  627. {
  628. Msg( "Unknown controller %s, should be 'left' or 'right'\n", hand_str.String() );
  629. return false;
  630. }
  631. return true;
  632. }
  633. bool SixenseGestureBindings::HandTokenToStr( int hand, char *buf, int buflen )
  634. {
  635. if( buflen < 10 ) return false;
  636. if( hand == 0 ) {
  637. Q_snprintf( buf, buflen, "left" );
  638. }
  639. else if( hand == 1 )
  640. {
  641. Q_snprintf( buf, buflen, "right" );
  642. }
  643. else
  644. {
  645. return false;
  646. }
  647. return true;
  648. }
  649. bool SixenseGestureBindings::ButtonTokenToStr( int arg, char *buf, int buflen )
  650. {
  651. if( buflen < 10 ) return false;
  652. if( arg == SIXENSE_BUTTON_1 )
  653. {
  654. Q_snprintf( buf, buflen, "1" );
  655. }
  656. else if( arg == SIXENSE_BUTTON_2 )
  657. {
  658. Q_snprintf( buf, buflen, "2" );
  659. }
  660. else if( arg == SIXENSE_BUTTON_3 )
  661. {
  662. Q_snprintf( buf, buflen, "3" );
  663. }
  664. else if( arg == SIXENSE_BUTTON_4 )
  665. {
  666. Q_snprintf( buf, buflen, "4" );
  667. }
  668. else if( arg == SIXENSE_BUTTON_START )
  669. {
  670. Q_snprintf( buf, buflen, "start" );
  671. }
  672. else if( arg == SIXENSE_BUTTON_BUMPER )
  673. {
  674. Q_snprintf( buf, buflen, "bumper" );
  675. }
  676. else if( arg == SIXENSE_BUTTON_JOYSTICK )
  677. {
  678. Q_snprintf( buf, buflen, "joystick" );
  679. }
  680. else
  681. {
  682. return false;
  683. }
  684. return true;
  685. }
  686. bool SixenseGestureBindings::DirectionTokenToStr( int arg, char *buf, int buflen )
  687. {
  688. if( buflen < 10 ) return false;
  689. if( arg == sixenseUtils::IButtonStates::DIR_LEFT )
  690. {
  691. Q_snprintf( buf, buflen, "left" );
  692. }
  693. else if( arg == sixenseUtils::IButtonStates::DIR_RIGHT )
  694. {
  695. Q_snprintf( buf, buflen, "right" );
  696. }
  697. else if( arg == sixenseUtils::IButtonStates::DIR_UP )
  698. {
  699. Q_snprintf( buf, buflen, "up" );
  700. }
  701. else if( arg == sixenseUtils::IButtonStates::DIR_DOWN )
  702. {
  703. Q_snprintf( buf, buflen, "down" );
  704. }
  705. else if( arg == sixenseUtils::IButtonStates::DIR_CW )
  706. {
  707. Q_snprintf( buf, buflen, "cw" );
  708. }
  709. else if( arg == sixenseUtils::IButtonStates::DIR_CCW )
  710. {
  711. Q_snprintf( buf, buflen, "ccw" );
  712. }
  713. else if( arg == sixenseUtils::IButtonStates::DIR_FORWARD )
  714. {
  715. Q_snprintf( buf, buflen, "forward" );
  716. }
  717. else if( arg == sixenseUtils::IButtonStates::DIR_BACKWARD )
  718. {
  719. Q_snprintf( buf, buflen, "backward" );
  720. }
  721. else
  722. {
  723. return false;
  724. }
  725. return true;
  726. }
  727. bool SixenseGestureBindings::ActionTokenToStr( sixenseUtils::IButtonStates::ActionType action, char *buf, int buflen )
  728. {
  729. if( buflen < 20 ) return false;
  730. if( action == sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS )
  731. {
  732. Q_snprintf( buf, buflen, "button_press" );
  733. }
  734. else if( action == sixenseUtils::IButtonStates::ACTION_JOYSTICK_MOVE )
  735. {
  736. Q_snprintf( buf, buflen, "joystick_move" );
  737. }
  738. else if( action == sixenseUtils::IButtonStates::ACTION_POINT_GESTURE )
  739. {
  740. Q_snprintf( buf, buflen, "point_gesture" );
  741. }
  742. else if( action == sixenseUtils::IButtonStates::ACTION_VELOCITY_GESTURE )
  743. {
  744. Q_snprintf( buf, buflen, "velocity_gesture" );
  745. }
  746. else if( action == sixenseUtils::IButtonStates::ACTION_TILT_GESTURE )
  747. {
  748. Q_snprintf( buf, buflen, "tilt_gesture" );
  749. }
  750. else if( action == sixenseUtils::IButtonStates::ACTION_BUTTON_PRESS )
  751. {
  752. Q_snprintf( buf, buflen, "button_press" );
  753. }
  754. else if( action == sixenseUtils::IButtonStates::ACTION_TRIGGER_PRESS )
  755. {
  756. Q_snprintf( buf, buflen, "trigger_press" );
  757. }
  758. else
  759. {
  760. return false;
  761. }
  762. return true;
  763. }
  764. #endif