GamePadHelper.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. #region File Description
  2. //-----------------------------------------------------------------------------
  3. // GamePadHelper.cs
  4. //
  5. // Microsoft XNA Community Game Platform
  6. // Copyright (C) Microsoft Corporation. All rights reserved.
  7. //-----------------------------------------------------------------------------
  8. #endregion
  9. #region Using Statements
  10. using System;
  11. using System.Collections.Generic;
  12. using Microsoft.Xna.Framework.Input;
  13. using Microsoft.Xna.Framework;
  14. #endregion
  15. namespace Marblets
  16. {
  17. /// <summary>
  18. /// Useful class that wraps some game pad stuff to give you indication of single
  19. /// button presses by remembering previous state. Right now its one shot which means
  20. /// if you call a Pressed function that will 'remove' the press.
  21. ///
  22. /// Keyboard support should be mapped in here based on PlayerIndex.
  23. /// PlayerIndex.One Key mapping is (Keys for player one to use)
  24. /// PlayerIndex.Two Key mapping is (Keys for Player two to use)
  25. /// Players Three => Infinity are not supported on a keyboard!
  26. /// </summary>
  27. public enum GamePadKey
  28. {
  29. /// <summary>
  30. /// Start button
  31. /// </summary>
  32. Start=0,
  33. /// <summary>
  34. /// Back buton
  35. /// </summary>
  36. Back,
  37. /// <summary>
  38. /// A button
  39. /// </summary>
  40. A,
  41. /// <summary>
  42. /// B button
  43. /// </summary>
  44. B,
  45. /// <summary>
  46. /// X button
  47. /// </summary>
  48. X,
  49. /// <summary>
  50. /// Y button
  51. /// </summary>
  52. Y,
  53. /// <summary>
  54. /// Up Dpad
  55. /// </summary>
  56. Up,
  57. /// <summary>
  58. /// Down Dpad
  59. /// </summary>
  60. Down,
  61. /// <summary>
  62. /// Left Dpad
  63. /// </summary>
  64. Left,
  65. /// <summary>
  66. /// Right Dpad
  67. /// </summary>
  68. Right,
  69. };
  70. /// <summary>
  71. /// XNA gamepads only give you 'isUp/Down' options for buttons and key presses.
  72. /// This class allows you to detect an up/down press combination
  73. /// </summary>
  74. public class GamePadHelper
  75. {
  76. private PlayerIndex player;
  77. private Dictionary<GamePadKey, Keys> keyMapping =
  78. new Dictionary<GamePadKey, Keys>();
  79. private Game game;
  80. /// <summary>
  81. /// Default constructor
  82. /// </summary>
  83. /// <param name="player">Which player.</param>
  84. public GamePadHelper(PlayerIndex player)
  85. {
  86. //Need to store the player. If you try to store a reference to the GamePad
  87. //here it seems to 'forget'
  88. this.player = player;
  89. // Setup Dictionary with defaults
  90. keyMapping.Add(GamePadKey.Start, Keys.Home);
  91. keyMapping.Add(GamePadKey.Back, Keys.End);
  92. keyMapping.Add(GamePadKey.A, Keys.A);
  93. keyMapping.Add(GamePadKey.B, Keys.B);
  94. keyMapping.Add(GamePadKey.X, Keys.X);
  95. keyMapping.Add(GamePadKey.Y, Keys.Y);
  96. keyMapping.Add(GamePadKey.Up, Keys.Up);
  97. keyMapping.Add(GamePadKey.Down, Keys.Down);
  98. keyMapping.Add(GamePadKey.Left, Keys.Left);
  99. keyMapping.Add(GamePadKey.Right, Keys.Right);
  100. }
  101. private bool AWasReleased;
  102. private bool BWasReleased;
  103. private bool YWasReleased;
  104. private bool XWasReleased;
  105. private bool StartWasReleased;
  106. private bool BackWasReleased;
  107. private bool UpWasReleased;
  108. private bool DownWasReleased;
  109. private bool LeftWasReleased;
  110. private bool RightWasReleased;
  111. private bool AKeyWasReleased;
  112. private bool BKeyWasReleased;
  113. private bool YKeyWasReleased;
  114. private bool XKeyWasReleased;
  115. private bool StartKeyWasReleased;
  116. private bool BackKeyWasReleased;
  117. private bool UpKeyWasReleased;
  118. private bool DownKeyWasReleased;
  119. private bool LeftKeyWasReleased;
  120. private bool RightKeyWasReleased;
  121. private GamePadState state;
  122. private KeyboardState keyState;
  123. /// <summary>
  124. /// Has the A button been pressed
  125. /// </summary>
  126. public bool APressed
  127. {
  128. get
  129. {
  130. return (
  131. (checkPressed(state.Buttons.A, ref AWasReleased)) ||
  132. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.A]),
  133. ref AKeyWasReleased))
  134. );
  135. }
  136. }
  137. /// <summary>
  138. /// Has the B button been pressed
  139. /// </summary>
  140. public bool BPressed
  141. {
  142. get
  143. {
  144. return (
  145. (checkPressed(state.Buttons.B, ref BWasReleased)) ||
  146. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.B]),
  147. ref BKeyWasReleased))
  148. );
  149. }
  150. }
  151. /// <summary>
  152. /// Has the Y button been pressed
  153. /// </summary>
  154. public bool YPressed
  155. {
  156. get
  157. {
  158. return (
  159. (checkPressed(state.Buttons.Y, ref YWasReleased)) ||
  160. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.Y]),
  161. ref YKeyWasReleased))
  162. );
  163. }
  164. }
  165. /// <summary>
  166. /// Has the X button been pressed
  167. /// </summary>
  168. public bool XPressed
  169. {
  170. get
  171. {
  172. return (
  173. (checkPressed(state.Buttons.X, ref XWasReleased)) ||
  174. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.X]),
  175. ref XKeyWasReleased))
  176. );
  177. }
  178. }
  179. /// <summary>
  180. /// Has the start button been pressed
  181. /// </summary>
  182. public bool StartPressed
  183. {
  184. get
  185. {
  186. return (
  187. (checkPressed(state.Buttons.Start, ref StartWasReleased)) ||
  188. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.Start]),
  189. ref StartKeyWasReleased))
  190. );
  191. }
  192. }
  193. /// <summary>
  194. /// Has the back button been pressed
  195. /// </summary>
  196. public bool BackPressed
  197. {
  198. get
  199. {
  200. return (
  201. (checkPressed(state.Buttons.Back, ref BackWasReleased)) ||
  202. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.Back]),
  203. ref BackKeyWasReleased))
  204. );
  205. }
  206. }
  207. /// <summary>
  208. /// Has the up dpad been pressed
  209. /// </summary>
  210. public bool UpPressed
  211. {
  212. get
  213. {
  214. return (
  215. (checkPressed(state.DPad.Up, ref UpWasReleased)) ||
  216. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.Up]),
  217. ref UpKeyWasReleased))
  218. );
  219. }
  220. }
  221. /// <summary>
  222. /// Has the down dpad been pressed
  223. /// </summary>
  224. public bool DownPressed
  225. {
  226. get
  227. {
  228. return (
  229. (checkPressed(state.DPad.Down, ref DownWasReleased)) ||
  230. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.Down]),
  231. ref DownKeyWasReleased))
  232. );
  233. }
  234. }
  235. /// <summary>
  236. /// Has the left dpad been pressed
  237. /// </summary>
  238. public bool LeftPressed
  239. {
  240. get
  241. {
  242. return (
  243. (checkPressed(state.DPad.Left, ref LeftWasReleased)) ||
  244. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.Left]),
  245. ref LeftKeyWasReleased))
  246. );
  247. }
  248. }
  249. /// <summary>
  250. /// Has the right dpad been pressed
  251. /// </summary>
  252. public bool RightPressed
  253. {
  254. get
  255. {
  256. return (
  257. (checkPressed(state.DPad.Right, ref RightWasReleased)) ||
  258. (checkPressed(keyState.IsKeyDown(keyMapping[GamePadKey.Right]),
  259. ref RightKeyWasReleased))
  260. );
  261. }
  262. }
  263. private bool checkPressed(ButtonState buttonState, ref bool controlWasReleased)
  264. {
  265. //Buttons are considered pressed when their state = Pressed or their key
  266. //equivalent is down
  267. return checkPressed(buttonState == ButtonState.Pressed,
  268. ref controlWasReleased);
  269. }
  270. private bool checkPressed(bool pressed, ref bool controlWasReleased)
  271. {
  272. bool returnValue = controlWasReleased && pressed;
  273. if(game != null && game.IsActive)
  274. {
  275. //If the item is currently pressed then reset the 'released' indicators
  276. if(returnValue)
  277. {
  278. controlWasReleased = false;
  279. }
  280. }
  281. else
  282. {
  283. return false; // Control can never be pressed, game is not the active
  284. // application!
  285. }
  286. return returnValue;
  287. }
  288. /// <summary>
  289. /// Updates the states. Should be called once per frame in the game loop
  290. /// otherwise the IsPressed functions won't work
  291. /// </summary>
  292. public void Update(Game game)
  293. {
  294. state = GamePad.GetState(player);
  295. keyState = Keyboard.GetState();
  296. this.game = game;
  297. if(state.IsConnected)
  298. {
  299. //Check which buttons have been released so we can detect presses
  300. if((state.Buttons.A == ButtonState.Released))
  301. AWasReleased = true;
  302. if((state.Buttons.B == ButtonState.Released))
  303. BWasReleased = true;
  304. if((state.Buttons.Y == ButtonState.Released))
  305. YWasReleased = true;
  306. if((state.Buttons.X == ButtonState.Released))
  307. XWasReleased = true;
  308. if((state.Buttons.Start == ButtonState.Released))
  309. StartWasReleased = true;
  310. if((state.Buttons.Back == ButtonState.Released))
  311. BackWasReleased = true;
  312. if((state.DPad.Up == ButtonState.Released))
  313. UpWasReleased = true;
  314. if((state.DPad.Down == ButtonState.Released))
  315. DownWasReleased = true;
  316. if((state.DPad.Left == ButtonState.Released))
  317. LeftWasReleased = true;
  318. if((state.DPad.Right == ButtonState.Released))
  319. RightWasReleased = true;
  320. }
  321. //Check which keys on the keyboard have been released so we can detect
  322. //presses
  323. if(!keyState.IsKeyDown(keyMapping[GamePadKey.A]))
  324. AKeyWasReleased = true;
  325. if(!keyState.IsKeyDown(keyMapping[GamePadKey.B]))
  326. BKeyWasReleased = true;
  327. if(!keyState.IsKeyDown(keyMapping[GamePadKey.Y]))
  328. YKeyWasReleased = true;
  329. if(!keyState.IsKeyDown(keyMapping[GamePadKey.X]))
  330. XKeyWasReleased = true;
  331. if(!keyState.IsKeyDown(keyMapping[GamePadKey.Start]))
  332. StartKeyWasReleased = true;
  333. if(!keyState.IsKeyDown(keyMapping[GamePadKey.Back]))
  334. BackKeyWasReleased = true;
  335. if(!keyState.IsKeyDown(keyMapping[GamePadKey.Up]))
  336. UpKeyWasReleased = true;
  337. if(!keyState.IsKeyDown(keyMapping[GamePadKey.Down]))
  338. DownKeyWasReleased = true;
  339. if(!keyState.IsKeyDown(keyMapping[GamePadKey.Left]))
  340. LeftKeyWasReleased = true;
  341. if(!keyState.IsKeyDown(keyMapping[GamePadKey.Right]))
  342. RightKeyWasReleased = true;
  343. }
  344. }
  345. }