Input.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. using Microsoft.Xna.Framework;
  2. using Microsoft.Xna.Framework.Input;
  3. using System;
  4. using System.Collections.Generic;
  5. namespace OpenVIII
  6. {
  7. [Obsolete("Input2 to replace input")]
  8. public partial class Input
  9. {
  10. #region Fields
  11. public static MouseLockMode CurrentMode;
  12. private static readonly int msDelayLimit = 100;
  13. private static bool bLimitInput;
  14. //store current input states;
  15. private static GamePadState m_gp_state = new GamePadState();
  16. private static KeyboardState m_kb_state = new KeyboardState();
  17. private static MouseState m_m_state = new MouseState();
  18. private static int msDelay = 0;
  19. #endregion Fields
  20. #region Properties
  21. public static Dictionary<Button_Flags, Buttons> Convert_Button { get; private set; }
  22. public static Point MouseLocation => new Point(CurrentMState.X, CurrentMState.Y);
  23. public static bool OverrideLockMouse { get; set; } = false;
  24. //properties to assign current input states and back up last input states on the fly.
  25. protected static GamePadState CurrentGPState { get => m_gp_state; set { LastGPState = m_gp_state; m_gp_state = value; } }
  26. protected static KeyboardState CurrentKBState { get => m_kb_state; set { LastKBState = m_kb_state; m_kb_state = value; } }
  27. protected static MouseState CurrentMState { get => m_m_state; set { LastMState = m_m_state; m_m_state = value; } }
  28. //last states
  29. protected static GamePadState LastGPState { get; private set; } = new GamePadState();
  30. protected static KeyboardState LastKBState { get; private set; } = new KeyboardState();
  31. protected static MouseState LastMState { get; private set; }
  32. #endregion Properties
  33. #region Methods
  34. public static float Analog(Buttons b, bool last = false)
  35. {
  36. //get output from analog controls
  37. //mousexjoy and mouseyjoy attempt to convert mouse input to a joystick like input 1.0f to -1.0f
  38. float tmp = 0f;
  39. if (last)
  40. {
  41. switch (b)
  42. {
  43. case Buttons.LeftStickX:
  44. return LastGPState.ThumbSticks.Left.X;
  45. case Buttons.LeftStickY:
  46. return LastGPState.ThumbSticks.Left.Y;
  47. case Buttons.RightStickX:
  48. return LastGPState.ThumbSticks.Right.X;
  49. case Buttons.RightStickY:
  50. return LastGPState.ThumbSticks.Right.Y;
  51. case Buttons.L2:
  52. return LastGPState.Triggers.Left;
  53. case Buttons.R2:
  54. return LastGPState.Triggers.Right;
  55. }
  56. if (Memory.IsActive)
  57. {
  58. switch (b)
  59. {
  60. case Buttons.MouseX:
  61. return LastMState.X;
  62. case Buttons.MouseY:
  63. return LastMState.Y;
  64. case Buttons.MouseXjoy:
  65. tmp = (LastMState.X - Memory.graphics.GraphicsDevice.Viewport.Bounds.Width / 2) / (50f);
  66. return MathHelper.Clamp(tmp, -1f, 1f);
  67. case Buttons.MouseYjoy:
  68. tmp = (Memory.graphics.GraphicsDevice.Viewport.Bounds.Height / 2 - LastMState.Y) / (50f);
  69. return MathHelper.Clamp(tmp, -1f, 1f);
  70. }
  71. }
  72. }
  73. else
  74. {
  75. switch (b)
  76. {
  77. case Buttons.LeftStickX:
  78. return CurrentGPState.ThumbSticks.Left.X;
  79. case Buttons.LeftStickY:
  80. return CurrentGPState.ThumbSticks.Left.Y;
  81. case Buttons.RightStickX:
  82. return CurrentGPState.ThumbSticks.Right.X;
  83. case Buttons.RightStickY:
  84. return CurrentGPState.ThumbSticks.Right.Y;
  85. case Buttons.L2:
  86. return CurrentGPState.Triggers.Left;
  87. case Buttons.R2:
  88. return CurrentGPState.Triggers.Right;
  89. }
  90. if (Memory.IsActive)
  91. {
  92. switch (b)
  93. {
  94. case Buttons.MouseX:
  95. return LastMState.X;
  96. case Buttons.MouseY:
  97. return LastMState.Y;
  98. case Buttons.MouseXjoy:
  99. tmp = (CurrentMState.X - Memory.graphics.GraphicsDevice.Viewport.Bounds.Width / 2) / (50f);
  100. return MathHelper.Clamp(tmp, -1f, 1f);
  101. case Buttons.MouseYjoy:
  102. tmp = (Memory.graphics.GraphicsDevice.Viewport.Bounds.Height / 2 - CurrentMState.Y) / (50f);
  103. return MathHelper.Clamp(tmp, -1f, 1f);
  104. }
  105. }
  106. }
  107. return 0.0f;
  108. }
  109. public static bool Button(Keys k, bool dblinput = false) => IsPressed(k, dblinput);
  110. public static bool Button(Buttons b, bool dblinput = false)
  111. {
  112. // To add support for controller I was extracting the boolean bits from the if
  113. // statements. Maybe it could be a scheme in future. When these are configureable. This
  114. // function mostly translates the function to the button(s) or key(s).
  115. switch (b)
  116. {
  117. case Buttons.Up:
  118. return (IsPressed(Keys.Up, true) || IsPressed(Buttons.MouseWheelup) || IsPressed(Keys.W, true) || (CurrentGPState.IsConnected && (IsPressed(b, true) || Analog(Buttons.LeftStickY) > 0.0f))) && !bLimitInput;
  119. case Buttons.Down:
  120. return (IsPressed(Keys.Down, true) || IsPressed(Buttons.MouseWheeldown) || IsPressed(Keys.S, true) || (CurrentGPState.IsConnected && (IsPressed(b, true) || Analog(Buttons.LeftStickY) < 0.0f))) && !bLimitInput;
  121. case Buttons.Left:
  122. return (IsPressed(Keys.Left, true) || IsPressed(Keys.A, true) || (CurrentGPState.IsConnected && (IsPressed(b, true) || Analog(Buttons.LeftStickX) < 0.0f))) && !bLimitInput;
  123. case Buttons.Right:
  124. return (IsPressed(Keys.Right, true) || IsPressed(Keys.D, true) || (CurrentGPState.IsConnected && (IsPressed(b, true) || Analog(Buttons.LeftStickX) > 0.0f))) && !bLimitInput;
  125. case Buttons.Okay:
  126. return IsPressed(Keys.Enter, dblinput) || IsPressed(Buttons.B, dblinput) || IsPressed(Buttons.MouseLeft);
  127. case Buttons.Cancel:
  128. return IsPressed(Keys.Back, dblinput) || IsPressed(Buttons.A, dblinput) || IsPressed(Buttons.MouseRight);
  129. case Buttons.Menu:
  130. return IsPressed(Keys.PageUp, dblinput) || IsPressed(Buttons.Y, dblinput);
  131. case Buttons.Switch:
  132. return IsPressed(Keys.PageDown, dblinput) || IsPressed(Buttons.X, dblinput);
  133. case Buttons.Start:
  134. return IsPressed(Keys.Home, dblinput) || IsPressed(Buttons.Start, dblinput);
  135. case Buttons.Select:
  136. return IsPressed(Keys.End, dblinput) || IsPressed(Buttons.Back, dblinput);
  137. case Buttons.Exit:
  138. return IsPressed(Keys.Escape, dblinput);
  139. default:
  140. return IsPressed(b, dblinput); // fail over to IsPressed if no custom input is avalible above
  141. }
  142. }
  143. public static float Distance(float speed) =>
  144. // no input throttle but still take the max speed * time; for non analog controls
  145. speed * Memory.gameTime.ElapsedGameTime.Milliseconds;
  146. public static float Distance(Buttons b, float speed, bool last = false) =>
  147. // (speed * stickvalue) * time = distance idea is you get the distance traveled per ms
  148. // value the speed being the max speed. your sticks value being the throttle.
  149. (speed * Analog(b, last)) * Memory.gameTime.ElapsedGameTime.Milliseconds;
  150. public static bool GetInputDelayed(Keys key)
  151. {
  152. //if (bLimitInput)
  153. // bLimitInput = (msDelay += Memory.gameTime.ElapsedGameTime.Milliseconds) < msDelayLimit;
  154. if (Keyboard.GetState().IsKeyDown(key) && !bLimitInput)
  155. {
  156. ResetInputLimit();
  157. return true;
  158. }
  159. return false;
  160. }
  161. public static void Init()
  162. {
  163. Convert_Button = new Dictionary<Button_Flags, Buttons>()
  164. {
  165. //Buttons is
  166. //finisher = 0x0001
  167. //up = 0x0010
  168. //-> = 0x0020
  169. //do = 0x0040
  170. //< - = 0x0080
  171. //L2 = 0x0100
  172. //R2 = 0x0200
  173. //L1 = 0x0400
  174. //R1 = 0x0800
  175. // /\ = 0x1000
  176. //O = 0x2000
  177. //X = 0x4000
  178. //| _ |= 0x8000
  179. //None = 0xFFFF
  180. {Button_Flags.Up,Buttons.Up},
  181. {Button_Flags.Right,Buttons.Right },
  182. {Button_Flags.Down,Buttons.Down },
  183. {Button_Flags.Left,Buttons.Left },
  184. {Button_Flags.L2,Buttons.L2 },
  185. {Button_Flags.R2,Buttons.R2 },
  186. {Button_Flags.L1,Buttons.L1 },
  187. {Button_Flags.R1,Buttons.R1 },
  188. {Button_Flags.Triangle,Buttons.Triangle},
  189. {Button_Flags.Circle,Buttons.Circle },
  190. {Button_Flags.Cross,Buttons.Cross },
  191. {Button_Flags.Square,Buttons.Square }
  192. };
  193. Update();
  194. }
  195. public static void LockMouse()
  196. {
  197. if (Memory.IsActive && OverrideLockMouse) // check for focus to allow for tabbing out with out taking over mouse.
  198. {
  199. if (CurrentMode == MouseLockMode.Center) //center mouse in screen after grabbing state, release mouse if alt tabbed out.
  200. {
  201. Mouse.SetPosition(Memory.graphics.GraphicsDevice.Viewport.Bounds.Width / 2, Memory.graphics.GraphicsDevice.Viewport.Bounds.Height / 2);
  202. }
  203. else if (CurrentMode == MouseLockMode.Screen) //alt lock that clamps to viewport every frame. would be useful if using mouse to navigate menus and stuff.
  204. {
  205. //there is a better way to clamp as if you move mouse fast enough it will escape for a short time.
  206. Mouse.SetPosition(
  207. MathHelper.Clamp(CurrentMState.X, 0, Memory.graphics.GraphicsDevice.Viewport.Bounds.Width),
  208. MathHelper.Clamp(CurrentMState.Y, 0, Memory.graphics.GraphicsDevice.Viewport.Bounds.Height));
  209. }
  210. }
  211. }
  212. /// <summary>
  213. /// Input was grabbed, reset for next update cycle.
  214. /// </summary>
  215. public static void ResetInputLimit()
  216. {
  217. msDelay = 0;
  218. bLimitInput = false;
  219. }
  220. public static void Update()
  221. {
  222. CurrentGPState = GamePad.GetState(PlayerIndex.One, GamePadDeadZone.Circular);
  223. CurrentKBState = Keyboard.GetState();
  224. CurrentMState = Mouse.GetState();
  225. LockMouse();
  226. CheckInputLimit();
  227. }
  228. private static void CheckInputLimit()
  229. {
  230. //issue here if CheckInputLimit is checked more than once per update cycle this will be wrong.
  231. if (Memory.gameTime != null)
  232. bLimitInput = (msDelay += Memory.gameTime.ElapsedGameTime.Milliseconds) < msDelayLimit;
  233. }
  234. private static bool IsPressed(Keys k, bool dblinput = false)
  235. {
  236. //This function checks if the key on KB is pressed
  237. //if dblinput is false it makes sure the key wasn't pressed last time.
  238. bool boolRT = CurrentKBState.IsKeyDown(k);
  239. boolRT = !dblinput ? boolRT && LastKBState.IsKeyUp(k) && !bLimitInput : boolRT && !bLimitInput;
  240. return boolRT;
  241. }
  242. private static bool IsPressed(Buttons b, bool dblinput = false)
  243. {
  244. //This function checks if the button on controller is pressed
  245. //if dblinput is false it makes sure the button wasn't pressed last time.
  246. bool boolRT = false;
  247. if (CurrentGPState.IsConnected)
  248. {
  249. switch (b)
  250. {
  251. case Buttons.Up:
  252. boolRT = CurrentGPState.DPad.Up == ButtonState.Pressed;
  253. break;
  254. case Buttons.Down:
  255. boolRT = CurrentGPState.DPad.Down == ButtonState.Pressed;
  256. break;
  257. case Buttons.Left:
  258. boolRT = CurrentGPState.DPad.Left == ButtonState.Pressed;
  259. break;
  260. case Buttons.Right:
  261. boolRT = CurrentGPState.DPad.Right == ButtonState.Pressed;
  262. break;
  263. case Buttons.B:
  264. boolRT = CurrentGPState.Buttons.B == ButtonState.Pressed;
  265. break;
  266. case Buttons.A:
  267. boolRT = CurrentGPState.Buttons.A == ButtonState.Pressed;
  268. break;
  269. case Buttons.Y:
  270. boolRT = CurrentGPState.Buttons.Y == ButtonState.Pressed;
  271. break;
  272. case Buttons.X:
  273. boolRT = CurrentGPState.Buttons.X == ButtonState.Pressed;
  274. break;
  275. case Buttons.L1:
  276. boolRT = CurrentGPState.Buttons.LeftShoulder == ButtonState.Pressed;
  277. break;
  278. case Buttons.L2:
  279. case Buttons.R2:
  280. boolRT = Analog(b) >= 0.25f; // treating the trigger like a button ignoring .25
  281. break;
  282. case Buttons.L3:
  283. boolRT = CurrentGPState.Buttons.LeftStick == ButtonState.Pressed;
  284. break;
  285. case Buttons.R1:
  286. boolRT = CurrentGPState.Buttons.RightShoulder == ButtonState.Pressed;
  287. break;
  288. case Buttons.R3:
  289. boolRT = CurrentGPState.Buttons.RightStick == ButtonState.Pressed;
  290. break;
  291. case Buttons.Start:
  292. boolRT = CurrentGPState.Buttons.Start == ButtonState.Pressed;
  293. break;
  294. case Buttons.Back:
  295. boolRT = CurrentGPState.Buttons.Back == ButtonState.Pressed;
  296. break;
  297. // this would be used as a test to see if stick is currently used. not ment to
  298. // control anything.
  299. case Buttons.LeftStickX:
  300. case Buttons.LeftStickY:
  301. case Buttons.RightStickX:
  302. case Buttons.RightStickY:
  303. boolRT = Analog(b) != 0.0f;
  304. break;
  305. }
  306. if (Memory.IsActive)
  307. {
  308. switch (b)
  309. {
  310. case Buttons.MouseXjoy:
  311. case Buttons.MouseYjoy:
  312. boolRT = Analog(b) != 0.0f;
  313. break;
  314. case Buttons.MouseX:
  315. case Buttons.MouseY:
  316. boolRT = Analog(b) != Analog(b, true);
  317. break;
  318. case Buttons.MouseLeft:
  319. boolRT = CurrentMState.LeftButton == ButtonState.Pressed;
  320. break;
  321. case Buttons.MouseMiddle:
  322. boolRT = CurrentMState.MiddleButton == ButtonState.Pressed;
  323. break;
  324. case Buttons.MouseRight:
  325. boolRT = CurrentMState.RightButton == ButtonState.Pressed;
  326. break;
  327. case Buttons.Mouse4:
  328. boolRT = CurrentMState.XButton1 == ButtonState.Pressed;
  329. break;
  330. case Buttons.Mouse5:
  331. boolRT = CurrentMState.XButton2 == ButtonState.Pressed;
  332. break;
  333. case Buttons.MouseWheelup:
  334. boolRT = CurrentMState.ScrollWheelValue > LastMState.ScrollWheelValue;
  335. break;
  336. case Buttons.MouseWheeldown:
  337. boolRT = CurrentMState.ScrollWheelValue < LastMState.ScrollWheelValue;
  338. break;
  339. }
  340. }
  341. if (!dblinput && boolRT)
  342. {
  343. switch (b)
  344. {
  345. case Buttons.Up:
  346. boolRT = LastGPState.DPad.Up == ButtonState.Released;
  347. break;
  348. case Buttons.Down:
  349. boolRT = LastGPState.DPad.Down == ButtonState.Released;
  350. break;
  351. case Buttons.Left:
  352. boolRT = LastGPState.DPad.Left == ButtonState.Released;
  353. break;
  354. case Buttons.Right:
  355. boolRT = LastGPState.DPad.Right == ButtonState.Released;
  356. break;
  357. case Buttons.B:
  358. boolRT = LastGPState.Buttons.B == ButtonState.Released;
  359. break;
  360. case Buttons.A:
  361. boolRT = LastGPState.Buttons.A == ButtonState.Released;
  362. break;
  363. case Buttons.Y:
  364. boolRT = LastGPState.Buttons.Y == ButtonState.Released;
  365. break;
  366. case Buttons.X:
  367. boolRT = LastGPState.Buttons.X == ButtonState.Released;
  368. break;
  369. case Buttons.L1:
  370. boolRT = LastGPState.Buttons.LeftShoulder == ButtonState.Released;
  371. break;
  372. case Buttons.L2:
  373. case Buttons.R2:
  374. boolRT = Analog(b, true) < 0.25f; // treating the trigger like a button ignoring .25
  375. break;
  376. case Buttons.L3:
  377. boolRT = LastGPState.Buttons.LeftStick == ButtonState.Released;
  378. break;
  379. case Buttons.R1:
  380. boolRT = LastGPState.Buttons.RightShoulder == ButtonState.Released;
  381. break;
  382. case Buttons.R3:
  383. boolRT = LastGPState.Buttons.RightStick == ButtonState.Released;
  384. break;
  385. case Buttons.Start:
  386. boolRT = LastGPState.Buttons.Start == ButtonState.Released;
  387. break;
  388. case Buttons.Back:
  389. boolRT = LastGPState.Buttons.Back == ButtonState.Released;
  390. break;
  391. // this would be used as a test to see if stick was released previously not
  392. // ment to control anything.
  393. case Buttons.LeftStickX:
  394. case Buttons.LeftStickY:
  395. case Buttons.RightStickX:
  396. case Buttons.RightStickY:
  397. boolRT = Analog(b, true) == 0.0f;
  398. break;
  399. }
  400. if (Memory.IsActive)
  401. {
  402. switch (b)
  403. {
  404. case Buttons.MouseXjoy:
  405. case Buttons.MouseYjoy:
  406. boolRT = Analog(b, true) == 0.0f;
  407. break;
  408. case Buttons.MouseLeft:
  409. boolRT = LastMState.LeftButton == ButtonState.Released;
  410. break;
  411. case Buttons.MouseMiddle:
  412. boolRT = LastMState.MiddleButton == ButtonState.Released;
  413. break;
  414. case Buttons.MouseRight:
  415. boolRT = LastMState.RightButton == ButtonState.Released;
  416. break;
  417. case Buttons.Mouse4:
  418. boolRT = LastMState.XButton1 == ButtonState.Released;
  419. break;
  420. case Buttons.Mouse5:
  421. boolRT = LastMState.XButton2 == ButtonState.Released;
  422. break;
  423. }
  424. }
  425. }
  426. else
  427. {
  428. boolRT = boolRT && !bLimitInput;
  429. }
  430. }
  431. if (boolRT)
  432. {
  433. }
  434. return boolRT;
  435. }
  436. #endregion Methods
  437. // fail over to IsPressed
  438. }
  439. }