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