desmume_rs/
input.rs

1use crate::DeSmuMEError;
2use desmume_sys::*;
3use std::marker::PhantomData;
4
5/// Manage input processing for the emulator.
6pub struct DeSmuMEInput {
7    pub(crate) joystick_was_init: bool,
8    pub(crate) _notsendsync: PhantomData<*mut u8>,
9}
10
11impl DeSmuMEInput {
12    /// Initialize the joystick input processing.
13    /// Call this to enable automatic joystick input processing.
14    pub fn joy_init(&mut self) -> Result<(), DeSmuMEError> {
15        unsafe {
16            if desmume_input_joy_init() > 0 {
17                self.joystick_was_init = true;
18                Ok(())
19            } else {
20                Err(DeSmuMEError::FailedInitJoystick)
21            }
22        }
23    }
24
25    /// De-initialize the joystick input processing.
26    pub fn joy_uninit(&mut self) {
27        if self.joystick_was_init {
28            unsafe { desmume_input_joy_uninit() }
29            self.joystick_was_init = false;
30        }
31    }
32
33    /// Returns the number of connected joysticks. Joysticks must be initialized.
34    pub fn joy_number_connected(&self) -> Result<u16, DeSmuMEError> {
35        if self.joystick_was_init {
36            Ok(unsafe { desmume_input_joy_number_connected() })
37        } else {
38            Err(DeSmuMEError::JoystickNotInit)
39        }
40    }
41
42    /// Returns the number of connected joysticks. Joysticks must be initialized.
43    pub fn joy_get_key(&self, index: u16) -> Result<u16, DeSmuMEError> {
44        if self.joystick_was_init {
45            Ok(unsafe { desmume_input_joy_get_key(index as c_int) })
46        } else {
47            Err(DeSmuMEError::JoystickNotInit)
48        }
49    }
50
51    /// Pause the thread and wait for the user to press a button.
52    /// This button will be assigned to the specified emulator key. Joysticks must be initialized.
53    pub fn joy_get_set_key(&mut self, index: u16) -> Result<u16, DeSmuMEError> {
54        if self.joystick_was_init {
55            Ok(unsafe { desmume_input_joy_get_set_key(index as c_int) })
56        } else {
57            Err(DeSmuMEError::JoystickNotInit)
58        }
59    }
60
61    /// Sets the emulator key `index` to the specified joystick key `joystick_key_index`.
62    /// Joysticks must be initialized.
63    pub fn joy_set_key(&mut self, index: u16, joystick_key_index: i32) -> Result<(), DeSmuMEError> {
64        if self.joystick_was_init {
65            unsafe { desmume_input_joy_set_key(index as c_int, joystick_key_index as c_int) };
66            Ok(())
67        } else {
68            Err(DeSmuMEError::JoystickNotInit)
69        }
70    }
71
72    /// Update the keypad (pressed DS buttons) of currently pressed emulator keys.
73    /// You should probably use `keypad_add_key` and `keypad_rm_key` instead.
74    pub fn keypad_update(&mut self, keys: u16) {
75        unsafe { desmume_input_keypad_update(keys) }
76    }
77
78    /// Returns the current emulator key keypad (pressed DS buttons).
79    pub fn keypad_get(&self) -> u16 {
80        unsafe { desmume_input_keypad_get() }
81    }
82
83    /// Adds a key to the emulators current keymask (presses it). To be used with `keymask`:
84    ///
85    /// ```rs
86    /// let emu: DeSmuME;
87    /// emu.input.keypad_add_key(keymask(Key::A)));
88    /// ```
89    pub fn keypad_add_key(&mut self, keymask: u16) {
90        let old_keypad = self.keypad_get();
91        self.keypad_update(add_key(old_keypad, keymask));
92    }
93
94    /// Removes a key from the emulators current keymask (releases it).
95    /// See ``keypad_add_key`` for a usage example.
96    pub fn keypad_rm_key(&mut self, keymask: u16) {
97        let old_keypad = self.keypad_get();
98        self.keypad_update(rm_key(old_keypad, keymask));
99    }
100
101    pub fn touch_set_pos(&mut self, x: u16, y: u16) {
102        unsafe { desmume_input_set_touch_pos(x, y) }
103    }
104
105    pub fn touch_release(&mut self) {
106        unsafe { desmume_input_release_touch() }
107    }
108}
109
110impl Drop for DeSmuMEInput {
111    fn drop(&mut self) {
112        self.joy_uninit()
113    }
114}
115
116/// Joystick input types.
117#[repr(u8)]
118#[derive(PartialEq, PartialOrd)]
119pub enum Joy {
120    Axis = 0,
121    Hat = 1,
122    Button = 2,
123}
124
125/// Jostick hat identifiers.
126#[repr(u8)]
127#[derive(PartialEq, PartialOrd)]
128pub enum JoyHats {
129    Right = 0,
130    Left = 1,
131    Up = 2,
132    Down = 3,
133}
134
135/// The total number of keys.
136pub const NB_KEYS: u8 = 15;
137pub const NO_KEY_SET: u16 = 0xFFFF;
138
139/// DS key identifiers.
140#[repr(u8)]
141#[derive(PartialEq, PartialOrd)]
142pub enum Key {
143    None = 0,
144    A = 1,
145    B = 2,
146    Select = 3,
147    Start = 4,
148    Right = 5,
149    Left = 6,
150    Up = 7,
151    Down = 8,
152    R = 9,
153    L = 10,
154    X = 11,
155    Y = 12,
156    Debug = 13,
157    Boost = 14,
158    Lid = 15,
159}
160
161#[inline(always)]
162fn add_key(keypad: u16, keymask: u16) -> u16 {
163    keypad | keymask
164}
165
166#[inline(always)]
167fn rm_key(keypad: u16, keymask: u16) -> u16 {
168    keypad & !keymask
169}
170
171pub fn keymask(k: Key) -> u16 {
172    // Returns the keymask for key ``k``. ``k`` is a constant of the ``Keys`` class.
173    if k == Key::None {
174        0
175    } else {
176        1 << (k as u16 - 1)
177    }
178}