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
//! Access to the real-time state of the joysticks.
//!
//! `joystick` provides an interface to the state of the joysticks.
//!
//! Each joystick is identified by an index that is passed to the functions of this module.
//!
//! This module allows users to query the state of joysticks at any time and directly,
//! without having to deal with a window and its events. Compared to the [`JoystickMoved`],
//! [`JoystickButtonPressed`] and [`JoystickButtonReleased`] events, `Joystick` can retrieve the
//! state of axes and buttons of joysticks at any time (you don't need to store and update a
//! boolean on your side in order to know if a button is pressed or released),
//! and you always get the real state of joysticks, even if they are moved,
//! pressed or released when your window is out of focus and no event is triggered.
//!
//! [`JoystickMoved`]: crate::window::Event::JoystickMoved
//! [`JoystickButtonPressed`]: crate::window::Event::JoystickButtonPressed
//! [`JoystickButtonReleased`]: crate::window::Event::JoystickButtonReleased
//!
//! SFML supports:
//!
//! - 8 joysticks ([`COUNT`])
//! - 32 buttons per joystick ([`BUTTON_COUNT`])
//! - 8 axes per joystick ([`AXIS_COUNT`])
//!
//! Unlike the keyboard or mouse, the state of joysticks is sometimes not directly
//! available (depending on the OS), therefore an [`update`] function must be called in order to
//! update the current state of joysticks. When you have a window with event handling, this is
//! done automatically, you don't need to call anything. But if you have no window, or if you want
//! to check joysticks state before creating one, you must call [`update`] explicitly.
//! # Usage example
//!
//! ```
//! use sfml::window::joystick;
//!
//! // If joystick #0 is connected
//! if joystick::is_connected(0) {
//! // How many buttons does joystick #0 support?
//! let _buttons = joystick::button_count(0);
//! // Does joystick #0 define a X axis?
//! let _hax_x = joystick::has_axis(0, joystick::Axis::X);
//! // Is button #2 pressed on joystick #0?
//! let _pressed = joystick::is_button_pressed(0, 2);
//! // What's the current position of the Y axis on joystick #0?
//! let _position = joystick::axis_position(0, joystick::Axis::Y);
//! }
//! ```
//!
//! [`COUNT`]: COUNT
//! [`BUTTON_COUNT`]: BUTTON_COUNT
//! [`AXIS_COUNT`]: AXIS_COUNT
//! [`update`]: update
//!
use crate::{ffi::window as ffi, SfBox};
/// Maximum number of supported joysticks.
pub const COUNT: u32 = 8;
/// Maximum number of supported buttons.
pub const BUTTON_COUNT: u32 = 32;
/// Maximum number of supported axes.
pub const AXIS_COUNT: u32 = 8;
/// Axes supported by SFML joysticks
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Hash)]
#[repr(transparent)]
pub struct Axis(pub(super) ffi::sfJoystickAxis);
impl Axis {
/// The X axis.
pub const X: Self = Self(ffi::sfJoystickAxis::sfJoystickX);
/// The Y axis.
pub const Y: Self = Self(ffi::sfJoystickAxis::sfJoystickY);
/// The Z axis.
pub const Z: Self = Self(ffi::sfJoystickAxis::sfJoystickZ);
/// The R axis.
pub const R: Self = Self(ffi::sfJoystickAxis::sfJoystickR);
/// The U axis.
pub const U: Self = Self(ffi::sfJoystickAxis::sfJoystickU);
/// The V axis.
pub const V: Self = Self(ffi::sfJoystickAxis::sfJoystickV);
/// The X axis of the point-of-view hat.
pub const POV_X: Self = Self(ffi::sfJoystickAxis::sfJoystickPovX);
/// The Y axis of the point-of-view hat.
pub const POV_Y: Self = Self(ffi::sfJoystickAxis::sfJoystickPovY);
}
/// Check if the joystick is connected
///
/// # Arguments
/// * joystick - Index of the joystick to check
///
/// Return true if the joystick is connected, false otherwise
#[must_use]
pub fn is_connected(joystick: u32) -> bool {
unsafe { ffi::sfJoystick_isConnected(joystick) }
}
/// Return the number of buttons supported by a joystick
///
/// # Arguments
/// * joystick - Index of the joystick
///
/// Return the number of buttons supported by the joystick.
#[must_use]
pub fn button_count(joystick: u32) -> u32 {
unsafe { ffi::sfJoystick_getButtonCount(joystick) }
}
/// Check if the joystick support a given axis
///
/// If the joystick is not connected, this function returns false.
///
/// # Arguments
/// * joystick - Index of the joystick
/// * axis - Axis to check
///
/// Return true if the joystick supports the axis, false otherwise
#[must_use]
pub fn has_axis(joystick: u32, axis: Axis) -> bool {
unsafe { ffi::sfJoystick_hasAxis(joystick, axis.0) }
}
/// Check if the button is pressed on a given joystick.
///
/// If the joystick is not connected, this function returns false.
///
/// # Arguments
/// * joystick - Index of the joystick
/// * button - Button to check
///
/// Return true if the button is pressed, false otherwise
#[must_use]
pub fn is_button_pressed(joystick: u32, button: u32) -> bool {
unsafe { ffi::sfJoystick_isButtonPressed(joystick, button) }
}
/// Get the current position on a given axis, on a given joystick.
///
/// If the joystick is not connected, this function returns 0.
///
/// # Arguments
/// * joystick - Index of the joystick
/// * axis - Axis to check
///
/// Return the current position of the axis, in range [-100 .. 100]
#[must_use]
pub fn axis_position(joystick: u32, axis: Axis) -> f32 {
unsafe { ffi::sfJoystick_getAxisPosition(joystick, axis.0) }
}
/// Update the states of all joysticks
///
/// This function is used internally by SFML, so you normally
/// don't have to call it explicitely. However, you may need to
/// call it if you have no window yet (or no window at all):
/// in this case the joysticks states are not updated automatically.
pub fn update() {
unsafe {
ffi::sfJoystick_update();
}
}
/// Get the joystick information.
#[must_use]
pub fn identification(joystick: u32) -> SfBox<ffi::JoystickIdentification> {
unsafe {
SfBox::new(ffi::sfJoystick_getIdentification(joystick))
.expect("Failed to create JoystickIdentification")
}
}
impl ffi::JoystickIdentification {
pub fn name(&self) -> &crate::ffi::system::sfString {
unsafe { &*ffi::sfJoystickIdentification_getName(self) }
}
pub fn vendor_id(&self) -> u32 {
unsafe { ffi::sfJoystickIdentification_getVendorId(self) }
}
pub fn product_id(&self) -> u32 {
unsafe { ffi::sfJoystickIdentification_getProductId(self) }
}
}