sdl/
joy.rs

1use libc::c_int;
2use std::ffi::CStr;
3use std::str;
4
5use get_error;
6
7pub mod ll {
8    #![allow(non_camel_case_types)]
9
10    use std::ffi::c_char;
11
12    use libc::{c_int, c_void, int16_t, uint8_t};
13
14    pub type SDL_Joystick = c_void;
15
16    extern "C" {
17        pub fn SDL_NumJoysticks() -> c_int;
18        pub fn SDL_JoystickName(i: c_int) -> *const c_char;
19        pub fn SDL_JoystickOpen(i: c_int) -> *mut SDL_Joystick;
20        pub fn SDL_JoystickOpened(i: c_int) -> c_int;
21        pub fn SDL_JoystickIndex(joystick: *mut SDL_Joystick) -> c_int;
22        pub fn SDL_JoystickNumAxes(joystick: *mut SDL_Joystick) -> c_int;
23        pub fn SDL_JoystickNumBalls(joystick: *mut SDL_Joystick) -> c_int;
24        pub fn SDL_JoystickNumHats(joystick: *mut SDL_Joystick) -> c_int;
25        pub fn SDL_JoystickNumButtons(joystick: *mut SDL_Joystick) -> c_int;
26        pub fn SDL_JoystickUpdate();
27        pub fn SDL_JoystickEventState(state: c_int) -> c_int;
28        pub fn SDL_JoystickGetAxis(joystick: *mut SDL_Joystick, axis: c_int) -> int16_t;
29        pub fn SDL_JoystickGetHat(joystick: *mut SDL_Joystick, hat: c_int) -> uint8_t;
30        pub fn SDL_JoystickGetBall(
31            joystick: *mut SDL_Joystick,
32            ball: c_int,
33            dx: *mut c_int,
34            dy: *mut c_int,
35        ) -> c_int;
36        pub fn SDL_JoystickGetButton(joystick: *mut SDL_Joystick, button: c_int) -> uint8_t;
37        pub fn SDL_JoystickClose(joystick: *mut SDL_Joystick);
38    }
39}
40
41pub fn get_num_joysticks() -> isize {
42    unsafe { ll::SDL_NumJoysticks() as isize }
43}
44
45pub fn get_joystick_name(index: isize) -> Result<String, String> {
46    unsafe {
47        let cstr = ll::SDL_JoystickName(index as c_int);
48
49        if cstr.is_null() {
50            Err(get_error())
51        } else {
52            Ok(str::from_utf8(CStr::from_ptr(cstr).to_bytes())
53                .unwrap()
54                .to_string())
55        }
56    }
57}
58
59pub fn is_joystick_open(index: isize) -> bool {
60    unsafe { ll::SDL_JoystickOpened(index as c_int) == 1 }
61}
62
63pub fn update_joysticks() {
64    unsafe {
65        ll::SDL_JoystickUpdate();
66    }
67}
68
69#[derive(PartialEq)]
70pub struct Joystick {
71    pub raw: *mut ll::SDL_Joystick,
72}
73
74fn wrap_joystick(raw: *mut ll::SDL_Joystick) -> Joystick {
75    Joystick { raw: raw }
76}
77
78impl Joystick {
79    pub fn open(index: isize) -> Result<Joystick, String> {
80        unsafe {
81            let raw = ll::SDL_JoystickOpen(index as c_int);
82
83            if raw.is_null() {
84                Err(get_error())
85            } else {
86                Ok(wrap_joystick(raw))
87            }
88        }
89    }
90
91    pub fn get_index(&self) -> isize {
92        unsafe { ll::SDL_JoystickIndex(self.raw) as isize }
93    }
94
95    pub fn get_num_axes(&self) -> isize {
96        unsafe { ll::SDL_JoystickNumAxes(self.raw) as isize }
97    }
98
99    pub fn get_num_balls(&self) -> isize {
100        unsafe { ll::SDL_JoystickNumBalls(self.raw) as isize }
101    }
102
103    pub fn get_num_hats(&self) -> isize {
104        unsafe { ll::SDL_JoystickNumHats(self.raw) as isize }
105    }
106
107    pub fn get_num_buttons(&self) -> isize {
108        unsafe { ll::SDL_JoystickNumButtons(self.raw) as isize }
109    }
110
111    pub fn get_axis(&self, axis: isize) -> i16 {
112        unsafe { ll::SDL_JoystickGetAxis(self.raw, axis as c_int) as i16 }
113    }
114
115    pub fn get_hat(&self, hat: isize) -> u8 {
116        unsafe { ll::SDL_JoystickGetAxis(self.raw, hat as c_int) as u8 }
117    }
118
119    pub fn get_button(&self, button: isize) -> u8 {
120        unsafe { ll::SDL_JoystickGetButton(self.raw, button as c_int) as u8 }
121    }
122
123    pub fn get_ball(&self, ball: isize) -> (isize, isize) {
124        let mut dx = 0;
125        let mut dy = 0;
126
127        unsafe {
128            ll::SDL_JoystickGetBall(self.raw, ball as c_int, &mut dx, &mut dy);
129        }
130
131        (dx as isize, dy as isize)
132    }
133}
134
135impl Drop for Joystick {
136    fn drop(&mut self) {
137        unsafe {
138            ll::SDL_JoystickClose(self.raw);
139        }
140    }
141}