input.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  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. /*!
  95. @return state of support mouse and keyboard. If client playing on server
  96. where mouse and keyboard is disabled, then return false. (on consoles)
  97. */
  98. proto native bool IsEnabledMouseAndKeyboardEvenOnServer();
  99. /*!
  100. @return Console: Last state queried from the platform operating system for the active gamepad.
  101. PC: Always true.
  102. */
  103. proto native bool IsMouseConnected();
  104. proto native bool IsKeyboardConnected();
  105. //! gets currently selected profile
  106. proto native int GetCurrentProfile();
  107. // gets currently selected profile keys for action
  108. proto native void GetCurrentProfileActionKeys(int action_index, out TIntArray keys);
  109. //! gets profile by index
  110. proto int GetProfileName(int profile_index, out string name);
  111. //! gets profile by name
  112. proto native int GetProfilesCount();
  113. //! setting active profile
  114. proto native int SetProfile(int index);
  115. // devices - joystick only!
  116. proto native int GetDevicesCount();
  117. proto int GetDeviceName(int device_index, out string name);
  118. proto native int IsDeviceXInput(int device_index);
  119. proto native int IsDeviceEnabled(int device_index);
  120. proto native void SetDeviceEnabled(int device_index, bool enabled);
  121. //! return true if was deflected button.
  122. proto bool GetGamepadThumbDirection(GamepadButton thumbButton, out float angle, out float value);
  123. //! clears active gamepad
  124. proto native void ResetActiveGamepad();
  125. proto native void SelectActiveGamepad(int gamepad);
  126. proto native void GetGamepadList(out array<int> gamepads);
  127. proto void GetGamepadUser(int gamepad, out BiosUser user);
  128. /**
  129. \brief the on OnGamepadIdentification callback will return the first gamepad where the button was pressed
  130. @param button the button that needs to be pressed for the identification
  131. */
  132. proto native void IdentifyGamepad(GamepadButton button);
  133. //! returns true if there is an active gamepad selected.
  134. proto native bool IsActiveGamepadSelected();
  135. //! returns true if 'Gamepad' or 'Mouse and Keyboard' is connected
  136. bool IsAnyInputDeviceActive()
  137. {
  138. return IsActiveGamepadSelected() || IsMouseConnected() || IsKeyboardConnected();
  139. }
  140. /**
  141. \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.
  142. @param unavailableDeviceList lists all devices that SHOULD be available, but aren't. Optional.
  143. */
  144. bool AreAllAllowedInputDevicesActive(out array<int> unavailableDeviceList = null)
  145. {
  146. bool passed = true;
  147. bool gamepad = IsActiveGamepadSelected();
  148. bool mouse = IsMouseConnected();
  149. bool keyboard = IsKeyboardConnected();
  150. bool MnKEnabled;
  151. if (g_Game.GetGameState() != DayZGameState.IN_GAME)
  152. {
  153. MnKEnabled = IsEnabledMouseAndKeyboard();
  154. }
  155. else if (g_Game.GetGameState() != DayZGameState.MAIN_MENU)
  156. {
  157. MnKEnabled = IsEnabledMouseAndKeyboardEvenOnServer();
  158. }
  159. else
  160. {
  161. return true;
  162. }
  163. if (!MnKEnabled)
  164. {
  165. if (!gamepad)
  166. {
  167. passed = false;
  168. FillUnavailableDeviceArray(EUAINPUT_DEVICE_CONTROLLER,unavailableDeviceList);
  169. }
  170. }
  171. else
  172. {
  173. if (!gamepad)
  174. {
  175. if (!mouse)
  176. {
  177. passed = false;
  178. FillUnavailableDeviceArray(EUAINPUT_DEVICE_MOUSE,unavailableDeviceList);
  179. }
  180. if (!keyboard)
  181. {
  182. passed = false;
  183. FillUnavailableDeviceArray(EUAINPUT_DEVICE_KEYBOARD,unavailableDeviceList);
  184. }
  185. if (!passed)
  186. {
  187. FillUnavailableDeviceArray(EUAINPUT_DEVICE_CONTROLLER,unavailableDeviceList);
  188. }
  189. }
  190. }
  191. return passed;
  192. }
  193. void FillUnavailableDeviceArray(int device, inout array<int> filler)
  194. {
  195. if (filler)
  196. {
  197. filler.Insert(device);
  198. }
  199. }
  200. //! currently lists only available Gamepad, Mouse, and Keyboard. Extendable as needed.
  201. void UpdateConnectedInputDeviceList()
  202. {
  203. g_Game.GetConnectedInputDeviceList().Clear();
  204. if (IsActiveGamepadSelected())
  205. g_Game.GetConnectedInputDeviceList().Insert(EUAINPUT_DEVICE_CONTROLLER);
  206. if (IsMouseConnected())
  207. g_Game.GetConnectedInputDeviceList().Insert(EUAINPUT_DEVICE_MOUSE);
  208. if (IsKeyboardConnected())
  209. g_Game.GetConnectedInputDeviceList().Insert(EUAINPUT_DEVICE_KEYBOARD);
  210. }
  211. /**
  212. @return Input device, with the last input event ('mouse and keyboard', 'controller' or
  213. 'unknown' if none input event was fired from the beginning).
  214. */
  215. proto native EInputDeviceType GetCurrentInputDevice();
  216. /**
  217. \note For PlayStation, Enter button in Asia territory is typically Circle button (B button),
  218. but in Europe and America it is Cross button (A button).
  219. \return Button, which represent Enter/Accept button.
  220. */
  221. proto native GamepadButton GetEnterButton();
  222. //! callback that is fired when a new gamepad is connected
  223. void OnGamepadConnected(int gamepad)
  224. {
  225. #ifdef PLATFORM_PS4
  226. BiosUser user;
  227. GetGamepadUser( gamepad, user );
  228. if (user && user == GetGame().GetUserManager().GetSelectedUser())
  229. {
  230. SelectActiveGamepad(gamepad);
  231. if (GetGame().GetMission())
  232. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_CONTROLLER); //only for PS, xbox handles it on identification
  233. }
  234. #endif
  235. #ifdef PLATFORM_XBOX
  236. if (gamepad == g_Game.GetPreviousGamepad())
  237. {
  238. SelectActiveGamepad(g_Game.GetPreviousGamepad());
  239. if (GetGame().GetMission())
  240. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_CONTROLLER); //only for PS, xbox handles it on identification
  241. }
  242. #endif
  243. }
  244. //! callback that is fired when gamepad is disconnected
  245. void OnGamepadDisconnected(int gamepad)
  246. {
  247. if (IsInactiveGamepadOrUserSelected(gamepad))
  248. {
  249. UpdateConnectedInputDeviceList();
  250. if (!g_Game.IsLoading())
  251. {
  252. DayZLoadState state = g_Game.GetLoadState();
  253. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  254. {
  255. if (GetGame().GetMission())
  256. GetGame().GetMission().GetOnInputDeviceDisconnected().Invoke(EUAINPUT_DEVICE_CONTROLLER);
  257. }
  258. }
  259. }
  260. }
  261. //! callback that is fired when identification was requested
  262. void OnGamepadIdentification(int gamepad)
  263. {
  264. if (gamepad > -1)
  265. {
  266. DayZLoadState state = g_Game.GetLoadState();
  267. UpdateConnectedInputDeviceList();
  268. SelectActiveGamepad(gamepad);
  269. g_Game.SelectUser(gamepad);
  270. g_Game.SetPreviousGamepad(gamepad);
  271. if (state == DayZLoadState.MAIN_MENU_START || state == DayZLoadState.MAIN_MENU_USER_SELECT)
  272. {
  273. if (GetGame().GetMission())
  274. GetGame().GetMission().Reset();
  275. }
  276. if (GetGame() && GetGame().GetMission() && GetGame().GetMission().GetOnInputDeviceConnected())
  277. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_CONTROLLER);
  278. }
  279. }
  280. int GetUserGamepad( BiosUser user )
  281. {
  282. array<int> gamepads = new array<int>;
  283. GetGamepadList( gamepads );
  284. for( int i = 0; i < gamepads.Count(); i++ )
  285. {
  286. BiosUser user2;
  287. GetGamepadUser( gamepads[i], user2 );
  288. if( user == user2 )
  289. return gamepads[i];
  290. }
  291. return -1;
  292. }
  293. bool IsInactiveGamepadOrUserSelected( int gamepad = -1 )
  294. {
  295. #ifdef PLATFORM_XBOX
  296. return !IsActiveGamepadSelected();
  297. #endif
  298. #ifdef PLATFORM_PS4
  299. BiosUser user;
  300. GetGamepadUser( gamepad, user );
  301. return (user == GetGame().GetUserManager().GetSelectedUser());
  302. #endif
  303. return false;
  304. }
  305. //! callback that is fired when mouse is connected (PS: and assigned to the user)
  306. //! does not fire on PC - mouse/keyboard assumed to always be connected
  307. void OnMouseConnected()
  308. {
  309. UpdateConnectedInputDeviceList();
  310. if (!g_Game.IsLoading() && GetGame().GetMission())
  311. {
  312. DayZLoadState state = g_Game.GetLoadState();
  313. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  314. {
  315. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_MOUSE);
  316. }
  317. }
  318. }
  319. //! callback that is fired when mouse is disconnected
  320. //! does not fire on PC - mouse/keyboard assumed to always be connected
  321. void OnMouseDisconnected()
  322. {
  323. UpdateConnectedInputDeviceList();
  324. if (!g_Game.IsLoading() && GetGame().GetMission())
  325. {
  326. DayZLoadState state = g_Game.GetLoadState();
  327. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  328. {
  329. GetGame().GetMission().GetOnInputDeviceDisconnected().Invoke(EUAINPUT_DEVICE_MOUSE);
  330. }
  331. }
  332. }
  333. //! callback that is fired when keyboard is connected (PS: and assigned to the user)
  334. //! does not fire on PC - mouse/keyboard assumed to always be connected
  335. void OnKeyboardConnected()
  336. {
  337. UpdateConnectedInputDeviceList();
  338. if (!g_Game.IsLoading() && GetGame().GetMission())
  339. {
  340. DayZLoadState state = g_Game.GetLoadState();
  341. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  342. {
  343. GetGame().GetMission().GetOnInputDeviceConnected().Invoke(EUAINPUT_DEVICE_KEYBOARD);
  344. }
  345. }
  346. }
  347. //! callback that is fired when keyboard is disconnected
  348. //! does not fire on PC - mouse/keyboard assumed to always be connected
  349. void OnKeyboardDisconnected()
  350. {
  351. UpdateConnectedInputDeviceList();
  352. if (!g_Game.IsLoading() && GetGame().GetMission())
  353. {
  354. DayZLoadState state = g_Game.GetLoadState();
  355. if (state != DayZLoadState.MAIN_MENU_START && state != DayZLoadState.MAIN_MENU_USER_SELECT)
  356. {
  357. GetGame().GetMission().GetOnInputDeviceDisconnected().Invoke(EUAINPUT_DEVICE_KEYBOARD);
  358. }
  359. }
  360. }
  361. //! called from code on different input device use
  362. void OnLastInputDeviceChanged(EInputDeviceType inputDevice)
  363. {
  364. if (GetGame().GetMission())
  365. {
  366. GetGame().GetMission().GetOnInputDeviceChanged().Invoke(inputDevice);
  367. }
  368. }
  369. };