ds4_rs/dualshock4/
buttons.rs

1pub struct ButtonConfig {
2    pub block: usize,
3    pub value: u8,
4    pub mask: u8,
5    pub analog_block: Option<usize>
6}
7
8pub struct ButtonsConfig {
9    pub x: ButtonConfig,
10    pub square: ButtonConfig,
11    pub triangle: ButtonConfig,
12    pub circle: ButtonConfig,
13    pub dpad_up: ButtonConfig,
14    pub dpad_up_right: ButtonConfig,
15    pub dpad_right: ButtonConfig,
16    pub dpad_down_right: ButtonConfig,
17    pub dpad_down: ButtonConfig,
18    pub dpad_down_left: ButtonConfig,
19    pub dpad_left: ButtonConfig,
20    pub dpad_up_left: ButtonConfig,
21    pub share: ButtonConfig,
22    pub options: ButtonConfig,
23    pub psx: ButtonConfig,
24    pub touchpad: ButtonConfig,
25    pub l1: ButtonConfig,
26    pub r1: ButtonConfig,
27    pub left_stick: ButtonConfig,
28    pub right_stick: ButtonConfig,
29    pub l2: ButtonConfig,
30    pub r2: ButtonConfig
31}
32
33pub const CONFIG:ButtonsConfig = ButtonsConfig {
34    x: ButtonConfig {
35        block: 0x05,
36        value: 0x20,
37        mask: 0xff,
38        analog_block: Option::None
39    },
40    square: ButtonConfig {
41        block: 0x05,
42        value: 0x10,
43        mask: 0xff,
44        analog_block: Option::None
45    },
46    triangle: ButtonConfig {
47        block: 0x05,
48        value: 0x80,
49        mask: 0xff,
50        analog_block: Option::None
51    },
52    circle: ButtonConfig {
53        block: 0x05,
54        value: 0x40,
55        mask: 0xff,
56        analog_block: Option::None
57    },
58    dpad_up: ButtonConfig {
59        block: 0x05,
60        value: 0x00,
61        mask: 0xf,
62        analog_block: Option::None
63    },
64    dpad_up_right: ButtonConfig {
65        block: 0x05,
66        value: 0x01,
67        mask: 0xf,
68        analog_block: Option::None
69    },
70    dpad_right: ButtonConfig {
71        block: 0x05,
72        value: 0x02,
73        mask: 0xf,
74        analog_block: Option::None
75    },
76    dpad_down_right: ButtonConfig {
77        block: 0x05,
78        value: 0x03,
79        mask: 0xf,
80        analog_block: Option::None
81    },
82    dpad_down: ButtonConfig {
83        block: 0x05,
84        value: 0x04,
85        mask: 0xf,
86        analog_block: Option::None
87    },
88    dpad_down_left: ButtonConfig {
89        block: 0x05,
90        value: 0x05,
91        mask: 0xf,
92        analog_block: Option::None
93    },
94    dpad_left: ButtonConfig {
95        block: 0x05,
96        value: 0x06,
97        mask: 0xf,
98        analog_block: Option::None
99    },
100    dpad_up_left: ButtonConfig {
101        block: 0x05,
102        value: 0x07,
103        mask: 0xf,
104        analog_block: Option::None
105    },
106    share: ButtonConfig {
107        block: 0x06,
108        value: 0x10,
109        mask: 0xff,
110        analog_block: Option::None
111    },
112    options: ButtonConfig {
113        block: 0x06,
114        value: 0x20,
115        mask: 0xff,
116        analog_block: Option::None
117    },
118    psx: ButtonConfig {
119        block: 0x07,
120        value: 0x01,
121        mask: 0xff,
122        analog_block: Option::None
123    },
124    touchpad: ButtonConfig {
125        block: 0x07,
126        value: 0x02,
127        mask: 0xff,
128        analog_block: Option::None
129    },
130    l1: ButtonConfig {
131        block: 0x06,
132        value: 0x01,
133        mask: 0xff,
134        analog_block: Option::None
135    },
136    r1: ButtonConfig {
137        block: 0x06,
138        value: 0x02,
139        mask: 0xff,
140        analog_block: Option::None
141    },
142    left_stick: ButtonConfig {
143        block: 0x06,
144        value: 0x40,
145        mask: 0xff,
146        analog_block: Option::None
147    },
148    right_stick: ButtonConfig {
149        block: 0x06,
150        value: 0x80,
151        mask: 0xff,
152        analog_block: Option::None
153    },
154    l2: ButtonConfig {
155        block: 0x06,
156        value: 0x04,
157        mask: 0xff,
158        analog_block: Some(0x08)
159    },
160    r2: ButtonConfig {
161        block: 0x06,
162        value: 0x08,
163        mask: 0xff,
164        analog_block: Some(0x09)
165    }
166};
167
168#[derive(PartialEq, Debug)]
169pub struct Button {
170    pub pressed: bool,
171    pub analog_value: Option<u8>
172}
173
174#[derive(PartialEq, Debug)]
175pub struct Buttons {
176    pub x: Button,
177    pub square: Button,
178    pub triangle: Button,
179    pub circle: Button,
180    pub dpad_up: Button,
181    pub dpad_up_right: Button,
182    pub dpad_right: Button,
183    pub dpad_down_right: Button,
184    pub dpad_down: Button,
185    pub dpad_down_left: Button,
186    pub dpad_left: Button,
187    pub dpad_up_left: Button,
188    pub share: Button,
189    pub options: Button,
190    pub psx: Button,
191    pub touchpad: Button,
192    pub l1: Button,
193    pub r1: Button,
194    pub left_stick: Button,
195    pub right_stick: Button,
196    pub l2: Button,
197    pub r2: Button
198}
199
200pub fn decode(buf: &[u8]) -> Buttons {
201    Buttons {
202        x: decode_button(&CONFIG.x, buf),
203        square: decode_button(&CONFIG.square, buf),
204        triangle: decode_button(&CONFIG.triangle, buf),
205        circle: decode_button(&CONFIG.circle, buf),
206        dpad_up: decode_button(&CONFIG.dpad_up, buf),
207        dpad_up_right: decode_button(&CONFIG.dpad_up_right, buf),
208        dpad_right: decode_button(&CONFIG.dpad_right, buf),
209        dpad_down_right: decode_button(&CONFIG.dpad_down_right, buf),
210        dpad_down: decode_button(&CONFIG.dpad_down, buf),
211        dpad_down_left: decode_button(&CONFIG.dpad_down_left, buf),
212        dpad_left: decode_button(&CONFIG.dpad_left, buf),
213        dpad_up_left: decode_button(&CONFIG.dpad_up_left, buf),
214        share: decode_button(&CONFIG.share, buf),
215        options: decode_button(&CONFIG.options, buf),
216        psx: decode_button(&CONFIG.psx, buf),
217        touchpad: decode_button(&CONFIG.touchpad, buf),
218        l1: decode_button(&CONFIG.l1, buf),
219        r1: decode_button(&CONFIG.r1, buf),
220        left_stick: decode_button(&CONFIG.left_stick, buf),
221        right_stick: decode_button(&CONFIG.right_stick, buf),
222        l2: decode_button(&CONFIG.l2, buf),
223        r2: decode_button(&CONFIG.r2, buf)
224    }
225}
226
227fn decode_button(config: &ButtonConfig, buf: &[u8]) -> Button {
228    let is_pressed = is_button_pressed(config, buf);
229    let analog_value = get_analog_value(config, buf);
230
231    Button {
232        pressed: is_pressed,
233        analog_value
234    }
235}
236
237fn is_button_pressed(config: &ButtonConfig, buf: &[u8]) -> bool {
238    let block = buf[config.block] & config.mask;
239
240    // special case for dpadUp
241    if config.block == 0x05 && config.value == CONFIG.dpad_up.value {
242        return block == CONFIG.dpad_up.value
243    }
244
245    // special case for dpads, only one can be pressed at time
246    if config.block == 0x05 && block < 0x08 {
247        return block == config.value
248    }
249
250    (block & config.value) == config.value
251}
252
253fn get_analog_value(config: &ButtonConfig, buf: &[u8]) -> Option<u8> {
254    match config.analog_block {
255        Some(block) => Some(buf[block]),
256        None => None
257    }
258}