safe_vex/
controller.rs

1//! # Controller API
2
3use alloc::ffi::CString;
4
5use crate::{bindings, error::{PROSErr, PROSResult}};
6
7/// A controller that you can read from
8#[derive(Debug, Clone, Copy)]
9#[repr(u8)]
10pub enum Controller {
11    /// The master controller
12    Master = 0,
13    /// The partner controller
14    Partner = 1,
15}
16
17/// An Analog Joystick on the Controller
18#[derive(Debug, Clone, Copy)]
19#[repr(u8)]
20pub enum ControllerAnalog {
21    /// The x axis of the left joystick
22    LeftX = 0,
23    /// The y axis of the left joystick
24    LeftY = 1,
25    /// The x axis of the right joystick
26    RightX = 2,
27    /// The y axis of the right joystick
28    RightY = 3,
29}
30
31/// A digital (button) on the controller
32#[derive(Debug, Clone, Copy)]
33#[repr(u8)]
34pub enum ControllerDigital {
35    /// The first trigger on the left side of the controller
36    L1 = 6,
37    /// The second trigger on the left side of the controller
38    L2,
39    /// The first trigger on the right side of the controller
40    R1,
41    /// The second trigger on the right side of the controller
42    R2,
43    /// The up arrow on the left arrow pad of the controller
44    Up,
45    /// The down arrow on the left arrow pad of the controller
46    Down,
47    /// The left arrow on the left arrow pad of the controller
48    Left,
49    /// The right arrow on the left arrow pad of the controller
50    Right,
51    /// The ‘X’ button on the right button pad of the controller
52    X,
53    /// The ‘B’ button on the right button pad of the controller
54    B,
55    /// The ‘Y’ button on the right button pad of the controller
56    Y,
57    /// The ‘A’ button on the right button pad of the controller
58    A,
59}
60
61/// Returns the analog value of a controller
62///
63/// # Errors
64///
65/// Returns `PROSErr::Access` if another resource is currently trying to access the controller
66/// Returns `0` if the controller is not connected
67pub fn get_analog(controller: Controller, analog: ControllerAnalog) -> Result<i8, PROSErr> {
68    unsafe {
69        bindings::controller_get_analog(controller as u32, analog as u32)
70    }.check().map(|x| x as i8)
71}
72
73/// Returns the digital value of a controller button
74///
75/// # Errors
76///
77/// Returns `PROSErr::Access` if another resource is currently trying to access the controller
78/// Returns `false` if the controller is not connected
79pub fn get_digital(controller: Controller, digital: ControllerDigital) -> Result<bool, PROSErr> {
80    unsafe {
81        bindings::controller_get_digital(controller as u32, digital as u32)
82    }.check().map(|x| x != 0)
83}
84
85/// Rumbles the controller
86///
87/// The rumble pattern is a string consisting of the characters '.', '-', and ' ', where dots are short rumbles, dashes are long rumbles, and spaces are pauses. Maximum supported length is 8 characters
88///
89/// # Errors
90///
91/// Returns `PROSErr::Access` if another resource is currently trying to access the controller
92pub fn rumble(controller: Controller, rumble_pattern: &str) -> Result<(), PROSErr> {
93    // rumble the controller
94    unsafe {
95        let rumble_pattern = CString::new(rumble_pattern).unwrap();
96        bindings::controller_rumble(controller as u32, rumble_pattern.as_ptr() as *const u8)
97    }.check().map(|_| ())
98}