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}