xinput/structures/
gamepad.rs

1use crate::*;
2use winapi::um::xinput::*;
3use bytemuck::{Pod, Zeroable};
4
5
6
7/// \[[microsoft.com](https://learn.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_gamepad)\]
8/// XINPUT_GAMEPAD
9///
10/// Describes the state of an Xbox 360 controller.
11///
12/// ### See Also
13/// *   [Doing thumbstick dead zones right](https://web.archive.org/web/20141025190105/https://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html)
14///     (**strongly** recommended reading!)
15/// *   [Xbox 360 controller - Layout](https://en.wikipedia.org/wiki/Xbox_360_controller#Layout) - Wikipedia
16#[derive(Clone, Copy, Debug)]
17#[derive(Default, Pod, Zeroable)]
18#[repr(C)] pub struct Gamepad {
19
20    /// Buttons of the gamepad that are currently held.
21    pub buttons: Buttons,
22
23    /// Analog trigger behind the left side of the gamepad.
24    ///
25    /// | Value | Description   |
26    /// | -----:| ------------- |
27    /// |     0 | Not held
28    /// |    30 | [`Gamepad::TRIGGER_THRESHOLD`]
29    /// |   255 | Fully held
30    pub left_trigger: u8,
31
32    /// Analog trigger behind the right side of the gamepad.
33    ///
34    /// | Value | Description   |
35    /// | -----:| ------------- |
36    /// |     0 | Not held
37    /// |    30 | [`Gamepad::TRIGGER_THRESHOLD`]
38    /// |   255 | Fully held
39    pub right_trigger: u8,
40
41    /// X-coordinate of the upper left thumbstick of the gamepad.
42    ///
43    /// | Value     | Description   |
44    /// | ---------:| ------------- |
45    /// |    -32768 | Fully left
46    /// |     -7849 | <code>- [Gamepad::LEFT_THUMB_DEADZONE]</code>
47    /// |         0 | Centered
48    /// |     +7849 | <code>+ [Gamepad::LEFT_THUMB_DEADZONE]</code>
49    /// |    +32767 | Fully right
50    pub left_thumb_x: i16,
51
52    /// Y-coordinate of the upper left thumbstick of the gamepad.
53    ///
54    /// | Value     | Description   |
55    /// | ---------:| ------------- |
56    /// |    -32768 | Fully down
57    /// |     -7849 | <code>- [Gamepad::LEFT_THUMB_DEADZONE]</code>
58    /// |         0 | Centered
59    /// |     +7849 | <code>+ [Gamepad::LEFT_THUMB_DEADZONE]</code>
60    /// |    +32767 | Fully up
61    pub left_thumb_y: i16,
62
63    /// X-coordinate of the right thumbstick of the gamepad.
64    ///
65    /// | Value     | Description   |
66    /// | ---------:| ------------- |
67    /// |    -32768 | Fully left
68    /// |     -8689 | <code>- [Gamepad::RIGHT_THUMB_DEADZONE]</code>
69    /// |         0 | Centered
70    /// |     +8689 | <code>+ [Gamepad::RIGHT_THUMB_DEADZONE]</code>
71    /// |    +32767 | Fully right
72    pub right_thumb_x: i16,
73
74    /// Y-coordinate of the right thumbstick of the gamepad.
75    ///
76    /// | Value     | Description   |
77    /// | ---------:| ------------- |
78    /// |    -32768 | Fully down
79    /// |     -8689 | <code>- [Gamepad::RIGHT_THUMB_DEADZONE]</code>
80    /// |         0 | Centered
81    /// |     +8689 | <code>+ [Gamepad::RIGHT_THUMB_DEADZONE]</code>
82    /// |    +32767 | Fully up
83    pub right_thumb_y: i16,
84}
85
86impl Gamepad {
87    /// An optional default threshhold to compare [`Gamepad::left_trigger`] or [`Gamepad::right_trigger`] to, before which you might avoid registering a trigger pull.
88    ///
89    /// In my experience, Xbox 360 controllers all perfectly report 0 trigger when untouched, so this is somewhat optional.
90    /// On the other hand, there's no guarantee third party XInput compatible controllers behave the same, so perhaps you should use such a constant!
91    pub const TRIGGER_THRESHOLD : u8 = XINPUT_GAMEPAD_TRIGGER_THRESHOLD;
92
93    /// A default deadzone magnitude for the left thumbstick.
94    ///
95    /// You might ignore [`Gamepad::left_thumb_x`] / [`Gamepad::left_thumb_y`] when they're within this magnitude of (0,0).
96    /// While this is generally large enough to avoid drift on new controllers, I have seen more well used controllers rest outside of this magnitude, resulting in suprising drift.
97    /// For maximum flexibility, consider making the user's deadzone customizeable, and perhaps using a higher threshhold for triggering game UI navigation.
98    ///
99    /// I also **strongly** recommend reading [Doing thumbstick dead zones right](https://web.archive.org/web/20141025190105/https://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html).
100    pub const LEFT_THUMB_DEADZONE : i16 = XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE;
101
102    /// A default deadzone magnitude for the right thumbstick.
103    ///
104    /// You might ignore [`Gamepad::right_thumb_x`] / [`Gamepad::right_thumb_y`] when they're within this magnitude of (0,0).
105    /// While this is generally large enough to avoid drift on new controllers, I have seen more well used controllers rest outside of this magnitude, resulting in suprising drift.
106    /// For maximum flexibility, consider making the user's deadzone customizeable, and perhaps using a higher threshhold for triggering game UI navigation.
107    ///
108    /// I also **strongly** recommend reading [Doing thumbstick dead zones right](https://web.archive.org/web/20141025190105/https://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html).
109    pub const RIGHT_THUMB_DEADZONE : i16 = XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE;
110}
111
112impl AsRef<Self> for Gamepad { fn as_ref(&    self) -> &    Self { self } }
113impl AsMut<Self> for Gamepad { fn as_mut(&mut self) -> &mut Self { self } }
114
115#[test] fn test_traits_for_coverage() {
116    let _gamepad = Gamepad::default();
117    let _gamepad = Gamepad::zeroed();
118    let _gamepad = _gamepad.clone();
119    dbg!(_gamepad);
120}
121
122//#cpp2rust XINPUT_GAMEPAD                      = xinput::Gamepad
123
124//#cpp2rust XINPUT_GAMEPAD_TRIGGER_THRESHOLD    = xinput::Gamepad::TRIGGER_THRESHOLD
125//#cpp2rust XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE  = xinput::Gamepad::LEFT_THUMB_DEADZONE
126//#cpp2rust XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE = xinput::Gamepad::RIGHT_THUMB_DEADZONE