1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
#![allow(deprecated)] // Guide button flags! impl
use bytemuck::{Pod, Zeroable};
use winapi::um::xinput::*;
/// \[[docs.microsoft.com](https://docs.microsoft.com/en-us/windows/win32/api/xinput/ns-xinput-xinput_gamepad#members)\]
/// XINPUT_GAMEPAD_\*
///
/// Bitmask of the device digital buttons of an Xbox 360 style gamepad.
///
/// ### See Also
/// * [Xbox 360 controller: Layout](https://en.wikipedia.org/wiki/Xbox_360_controller#Layout) (Wikipedia)
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[derive(Default, Pod, Zeroable)] // 0 = No buttons
#[repr(transparent)] pub struct Buttons(u16);
flags! { Buttons => u16; None, DPadUp, DPadDown, DPadLeft, DPadRight, Start, Guide, Back, LeftThumb, RightThumb, LeftShoulder, RightShoulder, A, B, X, Y }
impl Buttons {
/// Returns `true` if any button from `buttons` is set in `self`
pub fn any_held(&self, buttons: Buttons) -> bool { self.0 & buttons.0 != 0 }
/// Returns `true` if **all** buttons from `buttons` are set in `self`
pub fn all_held(&self, buttons: Buttons) -> bool { self.0 & buttons.0 == buttons.0 }
}
#[allow(non_upper_case_globals)] impl Buttons {
/// No buttons are held.
pub const None : Buttons = Buttons(0);
/// | Controller | Where |
/// | ------------- | ----- |
/// | Xbox 360 | Directional pad on the bottom left of the face
/// | Xbox One | Directional pad on the bottom left of the face
pub const DPadUp : Buttons = Buttons(XINPUT_GAMEPAD_DPAD_UP as _);
/// | Controller | Where |
/// | ------------- | ------ |
/// | Xbox 360 | Directional pad on the bottom left of the face
/// | Xbox One | Directional pad on the bottom left of the face
pub const DPadDown : Buttons = Buttons(XINPUT_GAMEPAD_DPAD_DOWN as _);
/// | Controller | Where |
/// | ------------- | ----- |
/// | Xbox 360 | Directional pad on the bottom left of the face
/// | Xbox One | Directional pad on the bottom left of the face
pub const DPadLeft : Buttons = Buttons(XINPUT_GAMEPAD_DPAD_LEFT as _);
/// | Controller | Where |
/// | ------------- | ----- |
/// | Xbox 360 | Directional pad on the bottom left of the face
/// | Xbox One | Directional pad on the bottom left of the face
pub const DPadRight : Buttons = Buttons(XINPUT_GAMEPAD_DPAD_RIGHT as _);
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | Start `ᐅ` | Right button of the middle face cluster
/// | Xbox One | Menu `≡` | Right button of the middle face cluster
pub const Start : Buttons = Buttons(XINPUT_GAMEPAD_START as _);
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | Back `ᐊ` | Left button of the middle face cluster
/// | Xbox One | View `⧉` | Left button of the middle face cluster
pub const Back : Buttons = Buttons(XINPUT_GAMEPAD_BACK as _);
/// | Controller | Legend | When |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | `L` | Pressing the left thumbstick into the controller
/// | Xbox One | `L` | Pressing the left thumbstick into the controller
pub const LeftThumb : Buttons = Buttons(XINPUT_GAMEPAD_LEFT_THUMB as _);
/// | Controller | Legend | When |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | `R` | Pressing the right thumbstick into the controller
/// | Xbox One | `R` | Pressing the right thumbstick into the controller
pub const RightThumb : Buttons = Buttons(XINPUT_GAMEPAD_RIGHT_THUMB as _);
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | `LB` | Top left on the controller
/// | Xbox One | `LB` | Top left on the controller
pub const LeftShoulder : Buttons = Buttons(XINPUT_GAMEPAD_LEFT_SHOULDER as _);
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | `RB` | Top right on the controller
/// | Xbox One | `RB` | Top right on the controller
pub const RightShoulder : Buttons = Buttons(XINPUT_GAMEPAD_RIGHT_SHOULDER as _);
#[cfg(doc)]
/// ❌ **NOTE** ❌ Not actually exposed by XInput as [`Buttons`], see [`Gamepad::left_trigger`](crate::xinput::Gamepad::left_trigger) instead.
///
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | `LT` | Under the top left of the controller
/// | Xbox One | `LT` | Under the top left of the controller
pub const LeftTrigger : () = ();
#[cfg(doc)]
/// ❌ **NOTE** ❌ Not actually available as part of [`Buttons`], see [`Gamepad::right_trigger`](crate::xinput::Gamepad::right_trigger) instead.
///
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | `RT` | Under the top right on the controller
/// | Xbox One | `RT` | Under the top right on the controller
pub const RightTrigger : () = ();
/// ⚠️ **NOTE** ⚠️ This undocumented button is not returned by most APIs, being reserved for system software.
///
/// Specifically, you must use the undocumented `XInputGetStateEx` function (same API as [`XInputGetState`](https://docs.microsoft.com/en-us/windows/win32/api/xinput/nf-xinput-xinputgetstate)?) to ever retrieve this value.
/// Additionally, this is generally meant to be reserved by the system software.
/// Windows, Steam, and other store apps all hook this globally regardless of what app/window has focus.
///
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | Guide | Center of the middle face cluster.
/// | Xbox One | Xbox | Center of the middle face cluster.
///
/// #### Conflicting Software: Xbox Game Bar (Windows 8+)
///
/// To disable:
/// * Launch `Xbox Game Bar` from the start menu
/// * Open `Settings` (Gear icon on the right of the top menu bar)
/// * Under `Shortcuts` > `Controller`,
/// * Unselect `Open Xbox Game Bar using (X) button on a controller`
///
/// #### Conflicting Software: Steam
///
/// To disable, close Steam, or:
/// * Open Steam's Settings
/// * `Settings` after right clicking the Steam system tray icon, or
/// * `Steam` > `Settings` in Steam's menu bar
/// * Under `Controller` > `Guide Button Chord Configuration`:
/// * Choose `Browse Configs`
/// * Select `Templates` > `Gamepad` (inert/do-nothing template)
/// * Under `Controller` > `General Controller Settings`:
/// * Disable `Guide Button Focuses Steam`
///
#[deprecated = "This undocumented button is not returned by most APIs, being reserved for system software. See thindx's docs for details."]
pub const Guide : Buttons = Buttons(1 << 10);
/// Typically synonymous select/accept in menus on Xbox 360 style controllers/games/console.
///
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | Green A | Bottom button of the right face cluster
/// | Xbox One | A | Bottom button of the right face cluster
pub const A : Buttons = Buttons(XINPUT_GAMEPAD_A as _);
/// Typically synonymous back/cancel in menus on Xbox 360 style controllers/games/console.
///
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | Red B | Right button of the right face cluster
/// | Xbox One | B | Right button of the right face cluster
pub const B : Buttons = Buttons(XINPUT_GAMEPAD_B as _);
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | Blue X | Left button of the right face cluster
/// | Xbox One | X | Left button of the right face cluster
pub const X : Buttons = Buttons(XINPUT_GAMEPAD_X as _);
/// | Controller | Legend | Where |
/// | ------------- | --------- | ----- |
/// | Xbox 360 | Yellow Y | Top button of the right face cluster
/// | Xbox One | Y | Top button of the right face cluster
pub const Y : Buttons = Buttons(XINPUT_GAMEPAD_Y as _);
}
#[doc(hidden)] impl Buttons {
pub const NONE : Buttons = Buttons(0);
pub const DPAD_UP : Buttons = Buttons(XINPUT_GAMEPAD_DPAD_UP as _);
pub const DPAD_DOWN : Buttons = Buttons(XINPUT_GAMEPAD_DPAD_DOWN as _);
pub const DPAD_LEFT : Buttons = Buttons(XINPUT_GAMEPAD_DPAD_LEFT as _);
pub const DPAD_RIGHT : Buttons = Buttons(XINPUT_GAMEPAD_DPAD_RIGHT as _);
pub const START : Buttons = Buttons(XINPUT_GAMEPAD_START as _);
pub const BACK : Buttons = Buttons(XINPUT_GAMEPAD_BACK as _);
pub const LEFT_THUMB : Buttons = Buttons(XINPUT_GAMEPAD_LEFT_THUMB as _);
pub const RIGHT_THUMB : Buttons = Buttons(XINPUT_GAMEPAD_RIGHT_THUMB as _);
pub const LEFT_SHOULDER : Buttons = Buttons(XINPUT_GAMEPAD_LEFT_SHOULDER as _);
pub const RIGHT_SHOULDER : Buttons = Buttons(XINPUT_GAMEPAD_RIGHT_SHOULDER as _);
#[deprecated = "This undocumented button is not returned by most APIs, being reserved for system software. See thindx's docs for details."]
pub const GUIDE : Buttons = Buttons(1 << 10);
// A, B, X, Y are already canon
}