input.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. enum EInputDeviceType
  2. {
  3. UNKNOWN,
  4. MOUSE_AND_KEYBOARD,
  5. CONTROLLER
  6. };
  7. //-----------------------------------------------------------------------------
  8. class Input
  9. {
  10. // input locking
  11. /**
  12. \brief Change game focus number
  13. @param add number to add to focus number
  14. @param input_device if equals -1, works globally on all devices, see INPUT_DEVICE_* values in constants.h
  15. @see HasGameFocus()
  16. */
  17. proto native void ChangeGameFocus(int add, int input_device = -1);
  18. /**
  19. \brief Reset game focus number (set to 0)
  20. @param input_device if equals -1, works globally on all devices, see INPUT_DEVICE_* values in constants.h
  21. @see HasGameFocus()
  22. */
  23. proto native void ResetGameFocus(int input_device = -1);
  24. /**
  25. \brief Check if game should have focus
  26. @param input_device if equals -1, checks all devices, see INPUT_DEVICE_* values in constants.h
  27. @return true if focus number == 0, false otherwise
  28. */
  29. proto native bool HasGameFocus(int input_device = -1);
  30. // actions
  31. proto native int GetActionGroupsCount();
  32. proto native int GetActionGroupSize(int group_index);
  33. proto int GetActionGroupName(int group_index, out string name);
  34. proto int GetActionDesc(int action_index, out string desc);
  35. // getting action state
  36. /**
  37. \brief Get action state
  38. @param action id of action, defined in \ref 4_World/Classes/UserActionsComponent/_constants.c
  39. @param check_focus if true and game is unfocused, returns 0; otherwise returns actual value
  40. @return actual action state as float, for regular two state buttons returns 0 or 1, for analog buttons/axes returns value in interval <0, 1> with consideration of defined deadzones
  41. @see LocalValue()
  42. */
  43. proto native float LocalValue_ID(int action, bool check_focus = true);
  44. proto native float LocalValue(string action, bool check_focus = true);
  45. /**
  46. \brief Returns true just in frame, when action was invoked (button was pressed)
  47. \note if the input is limited (click, hold, doubleclick), 'Press' event is limited as well, and reacts to the limiter only! Otherwise it registeres the first event, usually 'press' (change of value from 0)
  48. @param action id of action, defined in \ref 4_World/Classes/UserActionsComponent/_constants.c
  49. @param check_focus if true and game is unfocused, returns 0; otherwise returns actual value
  50. @return true if action was invoked in that frame, false otherwise
  51. @see LocalPress()
  52. */
  53. proto native bool LocalPress_ID(int action, bool check_focus = true);
  54. proto native bool LocalPress(string action, bool check_focus = true);
  55. /**
  56. \brief Returns true just in frame, when release action happened (button was released)
  57. @param action id of action, defined in \ref 4_World/Classes/UserActionsComponent/_constants.c
  58. @param check_focus if true and game is unfocused, returns 0; otherwise returns actual value
  59. @return true if action was released in that frame, false otherwise
  60. @see LocalRelease()
  61. */
  62. proto native bool LocalRelease_ID(int action, bool check_focus = true);
  63. proto native bool LocalRelease(string action, bool check_focus = true);
  64. /**
  65. \brief Returns true just in frame, when hold action invoked (button is hold)
  66. @param action id of action, defined in \ref 4_World/Classes/UserActionsComponent/_constants.c
  67. @param check_focus if true and game is unfocused, returns 0; otherwise returns actual value
  68. @return true if action was released in that frame, false otherwise
  69. @see LocalHold()
  70. */
  71. proto native bool LocalHold_ID(int action, bool check_focus = true);
  72. proto native bool LocalHold(string action, bool check_focus = true);
  73. /**
  74. \brief Returns true just in frame, when double click action invoked (button double clicked)
  75. @param action id of action, defined in \ref 4_World/Classes/UserActionsComponent/_constants.c
  76. @param check_focus if true and game is unfocused, returns 0; otherwise returns actual value
  77. @return true if action was released in that frame, false otherwise
  78. @see LocalDbl()
  79. */
  80. proto native bool LocalDbl_ID(int action, bool check_focus = true);
  81. proto native bool LocalDbl(string action, bool check_focus = true);
  82. /**
  83. \brief Disable key until end of frame
  84. @param key id of key, defined in \ref KeyCode
  85. \code
  86. GetGame().GetInput().DisableKey(KeyCode.KC_RETURN);
  87. \endcode
  88. */
  89. proto native void DisableKey(int key);
  90. //! Enable mouse and keyboard (on consoles)
  91. proto native void EnableMouseAndKeyboard(bool enable);
  92. //! @return state of support mouse and keyboard (on consoles)
  93. proto native bool IsEnabledMouseAndKeyboard();
  94. //! Enable gamepad (on PC)
  95. proto native void EnableGamepad(bool enable);
  96. //! @return state of support gamepad (on PC)
  97. // NOTE: not actually supported, just keeping naming consistent.
  98. // Required as we need to disable gamepad on windows when in the server browser to prevent
  99. // the client from freezing on gamepad queries while refreshing the server list .
  100. proto native bool IsEnabledGamepad();
  101. /*!
  102. @return state of support mouse and keyboard. If client playing on server
  103. where mouse and keyboard is disabled, then return false. (on consoles)
  104. */
  105. proto native bool IsEnabledMouseAndKeyboardEvenOnServer();
  106. /*!
  107. @return Console: Last state queried from the platform operating system for the active gamepad.
  108. PC: Always true.
  109. */
  110. proto native bool IsMouseConnected();
  111. proto native bool IsKeyboardConnected();
  112. //! gets currently selected profile
  113. proto native int GetCurrentProfile();
  114. // gets currently selected profile keys for action
  115. proto native void GetCurrentProfileActionKeys(int action_index, out TIntArray keys);
  116. //! gets profile by index
  117. proto int GetProfileName(int profile_index, out string name);
  118. //! gets profile by name
  119. proto native int GetProfilesCount();
  120. //! setting active profile
  121. proto native int SetProfile(int index);
  122. // devices - joystick only!
  123. proto native int GetDevicesCount();
  124. proto int GetDeviceName(int device_index, out string name);
  125. proto native int IsDeviceXInput(int device_index);
  126. proto native int IsDeviceEnabled(int device_index);
  127. proto native void SetDeviceEnabled(int device_index, bool enabled);
  128. //! return true if was deflected button.
  129. proto bool GetGamepadThumbDirection(GamepadButton thumbButton, out float angle, out float value);
  130. //! clears active gamepad
  131. proto native void ResetActiveGamepad();
  132. proto native void SelectActiveGamepad(int gamepad);
  133. proto native void GetGamepadList(out array<int> gamepads);
  134. proto void GetGamepadUser(int gamepad, out BiosUser user);
  135. /**
  136. \brief the on OnGamepadIdentification callback will return the first gamepad where the button was pressed
  137. @param button the button that needs to be pressed for the identification
  138. */
  139. proto native void IdentifyGamepad(GamepadButton button);
  140. //! returns true if there is an active gamepad selected.
  141. proto native bool IsActiveGamepadSelected();
  142. //! returns true if 'Gamepad' or 'Mouse and Keyboard' is connected
  143. bool IsAnyInputDeviceActive()
  144. {
  145. return IsActiveGamepadSelected() || IsMouseConnected() || IsKeyboardConnected();
  146. }
  147. /**
  148. \brief returns true if 'Gamepad' or if 'Mouse/Keyboard' control is allowed locally and on server, and the respective input devicse are connected. Gamepad takes priority.
  149. @param unavailableDeviceList lists all devices that SHOULD be available, but aren't. Optional.
  150. */
  151. bool AreAllAllowedInputDevicesActive(out array<int> unavailableDeviceList = null)
  152. {
  153. bool passed = true;
  154. bool gamepad = IsActiveGamepadSelected();
  155. bool mouse = IsMouseConnected();
  156. bool keyboard = IsKeyboardConnected();
  157. bool MnKEnabled;
  158. if (g_Game.GetGameState() != DayZGameState.IN_GAME)
  159. {
  160. MnKEnabled = IsEnabledMouseAndKeyboard();
  161. }
  162. else if (g_Game.GetGameState() != DayZGameState.MAIN_MENU)
  163. {
  164. MnKEnabled = IsEnabledMouseAndKeyboardEvenOnServer();
  165. }
  166. else
  167. {
  168. return true;
  169. }
  170. if (!MnKEnabled)
  171. {
  172. if (!gamepad)
  173. {
  174. passed = false;
  175. FillUnavailableDeviceArray(EUAINPUT_DEVICE_CONTROLLER,unavailableDeviceList);
  176. }
  177. }
  178. else
  179. {
  180. if (!gamepad)
  181. {
  182. if (!mouse)
  183. {
  184. passed = false;
  185. FillUnavailableDeviceArray(EUAINPUT_DEVICE_MOUSE,unavailableDeviceList);
  186. }
  187. if (!keyboard)
  188. {
  189. passed = false;
  190. FillUnavailableDeviceArray(EUAINPUT_DEVICE_KEYBOARD,unavailableDeviceList);
  191. }
  192. if (!passed)
  193. {
  194. FillUnavailableDeviceArray(EUAINPUT_DEVICE_CONTROLLER,unavailableDeviceList);
  195. }
  196. }
  197. }
  198. return passed;
  199. }
  200. void FillUnavailableDeviceArray(int device, inout array<int> filler)
  201. {
  202. if (filler)
  203. {
  204. filler.Insert(device);
  205. }
  206. }
  207. //! currently lists only available Gamepad, Mouse, and Keyboard. Extendable as needed.
  208. void UpdateConnectedInputDeviceList()
  209. {
  210. g_Game.GetConnectedInputDeviceList().Clear();
  211. if (IsActiveGamepadSelected())
  212. g_Game.GetConnectedInputDeviceList().Insert(EUAINPUT_DEVICE_CONTROLLER);
  213. if (IsMouseConnected())
  214. g_Game.GetConnectedInputDeviceList().Insert(EUAINPUT_DEVICE_MOUSE);
  215. if (IsKeyboardConnected())
  216. g_Game.GetConnectedInputDeviceList().Insert(EUAINPUT_DEVICE_KEYBOARD);
  217. }
  218. /**
  219. @return Input device, with the last input event ('mouse and keyboard', 'controller' or
  220. 'unknown' if none input event was fired from the beginning).
  221. */
  222. proto native EInputDeviceType GetCurrentInputDevice();
  223. /**
  224. \note For PlayStation, Enter button in Asia territory is typically Circle button (B button),
  225. but in Europe and America it is Cross button (A button).
  226. \return Button, which represent Enter/Accept button.
  227. */
  228. proto native GamepadButton GetEnterButton();
  229. //! callback that is fired when a new gamepad is connected
  230. void OnGamepadConnected(int gamepad)
  231. {
  232. if (!g_Game)
  233. return;
  234. #ifdef PLATFORM_PS4
  235. BiosUser user;
  236. GetGamepadUser( gamepad, user );
  237. if (user && user == GetGame().GetUserManager().GetSelectedUser())
  238. {
  239. SelectActiveGamepad(gamepad);
  240. if (GetGame().GetMission())
  241. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_CONTROLLER); //only for PS, xbox handles it on identification
  242. }
  243. #endif
  244. #ifdef PLATFORM_XBOX
  245. if (gamepad == g_Game.GetPreviousGamepad())
  246. {
  247. SelectActiveGamepad(g_Game.GetPreviousGamepad());
  248. if (GetGame().GetMission())
  249. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_CONTROLLER); //only for PS, xbox handles it on identification
  250. }
  251. #endif
  252. }
  253. //! callback that is fired when gamepad is disconnected
  254. void OnGamepadDisconnected(int gamepad)
  255. {
  256. if (!g_Game)
  257. return;
  258. if (IsInactiveGamepadOrUserSelected(gamepad))
  259. {
  260. UpdateConnectedInputDeviceList();
  261. if (!g_Game.IsLoading())
  262. {
  263. DayZLoadState state = g_Game.GetLoadState();
  264. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  265. {
  266. if (GetGame().GetMission())
  267. GetGame().GetMission().GetOnInputDeviceDisconnected().Invoke(EUAINPUT_DEVICE_CONTROLLER);
  268. }
  269. }
  270. }
  271. }
  272. //! callback that is fired when identification was requested
  273. void OnGamepadIdentification(int gamepad)
  274. {
  275. if (!g_Game)
  276. return;
  277. if (gamepad > -1)
  278. {
  279. DayZLoadState state = g_Game.GetLoadState();
  280. UpdateConnectedInputDeviceList();
  281. SelectActiveGamepad(gamepad);
  282. g_Game.SelectUser(gamepad);
  283. g_Game.SetPreviousGamepad(gamepad);
  284. if (state == DayZLoadState.MAIN_MENU_START || state == DayZLoadState.MAIN_MENU_USER_SELECT)
  285. {
  286. if (GetGame().GetMission())
  287. GetGame().GetMission().Reset();
  288. }
  289. if (GetGame() && GetGame().GetMission() && GetGame().GetMission().GetOnInputDeviceConnected())
  290. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_CONTROLLER);
  291. }
  292. }
  293. int GetUserGamepad( BiosUser user )
  294. {
  295. array<int> gamepads = new array<int>;
  296. GetGamepadList( gamepads );
  297. for( int i = 0; i < gamepads.Count(); i++ )
  298. {
  299. BiosUser user2;
  300. GetGamepadUser( gamepads[i], user2 );
  301. if( user == user2 )
  302. return gamepads[i];
  303. }
  304. return -1;
  305. }
  306. bool IsInactiveGamepadOrUserSelected( int gamepad = -1 )
  307. {
  308. if (!g_Game)
  309. return false;
  310. #ifdef PLATFORM_CONSOLE
  311. if (!GetGame().GetUserManager())
  312. return false;
  313. #ifdef PLATFORM_XBOX
  314. return !IsActiveGamepadSelected();
  315. #endif
  316. #ifdef PLATFORM_PS4
  317. BiosUser user;
  318. GetGamepadUser( gamepad, user );
  319. return (user == GetGame().GetUserManager().GetSelectedUser());
  320. #endif
  321. #endif
  322. return false;
  323. }
  324. //! callback that is fired when mouse is connected (PS: and assigned to the user)
  325. //! does not fire on PC - mouse/keyboard assumed to always be connected
  326. void OnMouseConnected()
  327. {
  328. if (!g_Game)
  329. return;
  330. UpdateConnectedInputDeviceList();
  331. if (!g_Game.IsLoading() && GetGame().GetMission())
  332. {
  333. DayZLoadState state = g_Game.GetLoadState();
  334. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  335. {
  336. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_MOUSE);
  337. }
  338. }
  339. }
  340. //! callback that is fired when mouse is disconnected
  341. //! does not fire on PC - mouse/keyboard assumed to always be connected
  342. void OnMouseDisconnected()
  343. {
  344. if (!g_Game)
  345. return;
  346. UpdateConnectedInputDeviceList();
  347. if (!g_Game.IsLoading() && GetGame().GetMission())
  348. {
  349. DayZLoadState state = g_Game.GetLoadState();
  350. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  351. {
  352. GetGame().GetMission().GetOnInputDeviceDisconnected().Invoke(EUAINPUT_DEVICE_MOUSE);
  353. }
  354. }
  355. }
  356. //! callback that is fired when keyboard is connected (PS: and assigned to the user)
  357. //! does not fire on PC - mouse/keyboard assumed to always be connected
  358. void OnKeyboardConnected()
  359. {
  360. if (!g_Game)
  361. return;
  362. UpdateConnectedInputDeviceList();
  363. if (!g_Game.IsLoading() && GetGame().GetMission())
  364. {
  365. DayZLoadState state = g_Game.GetLoadState();
  366. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  367. {
  368. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_KEYBOARD);
  369. }
  370. }
  371. }
  372. //! callback that is fired when keyboard is disconnected
  373. //! does not fire on PC - mouse/keyboard assumed to always be connected
  374. void OnKeyboardDisconnected()
  375. {
  376. if (!g_Game)
  377. return;
  378. UpdateConnectedInputDeviceList();
  379. if (!g_Game.IsLoading() && GetGame().GetMission())
  380. {
  381. DayZLoadState state = g_Game.GetLoadState();
  382. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  383. {
  384. GetGame().GetMission().GetOnInputDeviceDisconnected().Invoke(EUAINPUT_DEVICE_KEYBOARD);
  385. }
  386. }
  387. }
  388. //! called from code on different input device use
  389. void OnLastInputDeviceChanged(EInputDeviceType inputDevice)
  390. {
  391. if (!g_Game)
  392. return;
  393. if (GetGame().GetMission())
  394. {
  395. GetGame().GetMission().GetOnInputDeviceChanged().Invoke(inputDevice);
  396. }
  397. }
  398. };