cardinal_varvara/
controller_usb.rs1#[cfg(not(feature = "uses_usb"))]
2compile_error!("controller_usb.rs should not be compiled unless the 'uses_usb' feature is enabled");
3
4#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
5use super::controller::Controller;
6#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
7use super::controller::{ControllerDevice, Key};
8#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
9use crate::Event;
10#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
11use std::any::Any;
12#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
13use uxn::Uxn;
14
15#[cfg(feature = "uses_gilrs")]
17use super::controller_gilrs::ControllerGilrs;
18
19#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
20pub struct ControllerUsb {
22 pub rx: std::sync::mpsc::Receiver<UsbControllerMessage>,
24 pub last_pedal: Option<u8>,
26 pub controller: Controller,
28 #[cfg(feature = "uses_gilrs")]
30 pub gilrs: Option<ControllerGilrs>,
31}
32
33#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
34impl ControllerDevice for ControllerUsb {
35 fn char(&mut self, vm: &mut Uxn, c: u8) -> Event {
37 let _event = self.controller.char(vm, c);
38 #[cfg(feature = "uses_gilrs")]
39 if let Some(gilrs) = &mut self.gilrs {
40 gilrs.char(vm, c);
41 }
42 let p = vm.dev::<crate::controller::ControllerPorts>();
43 Event {
44 vector: p.vector.get(),
45 data: Some(crate::EventData {
46 addr: crate::controller::ControllerPorts::KEY,
47 value: c,
48 clear: true,
49 }),
50 }
51 }
53
54 fn pressed(&mut self, vm: &mut Uxn, k: Key, repeat: bool) -> Option<Event> {
56 let event = self.controller.pressed(vm, k, repeat);
57 #[cfg(feature = "uses_gilrs")]
58 if let Some(gilrs) = &mut self.gilrs {
59 gilrs.pressed(vm, k, repeat);
60 }
61 event
62 }
63
64 fn released(&mut self, vm: &mut Uxn, k: Key) -> Option<Event> {
68 let event = self.controller.released(vm, k);
69 #[cfg(feature = "uses_gilrs")]
70 if let Some(gilrs) = &mut self.gilrs {
71 gilrs.released(vm, k);
72 }
73 event
74 }
75 fn as_any(&mut self) -> &mut dyn Any {
76 self
77 }
78}
79
80pub trait ControllerPollEvents: Send {
82 fn poll_usb_events(&mut self, vm: &mut Uxn) -> Vec<Event>;
84}
85
86#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
87impl ControllerPollEvents for ControllerUsb {
88 fn poll_usb_events(&mut self, vm: &mut Uxn) -> Vec<Event> {
90 let mut events = Vec::new();
91
92 #[cfg(feature = "uses_gilrs")]
94 if let Some(gilrs) = &mut self.gilrs {
95 events.extend(gilrs.poll_gilrs_event(vm).into_iter().flatten());
96 }
97
98 while let Ok(msg) = self.rx.try_recv() {
101 println!("[USB] Received message: {msg:?}");
102 if let Some(&pedal_byte) = msg.data.first() {
104 match self.last_pedal {
105 Some(prev) => {
106 println!(
107 "[USB] Pedal state changed: 0x{pedal_byte:02x} (was 0x{prev:02x})"
108 );
109 let changed = pedal_byte ^ prev;
110 for i in 0..8 {
111 let mask = 1 << i;
112 if changed & mask != 0 {
113 if pedal_byte & mask != 0 {
114 println!("[USB] Pedal {i} pressed (bit {mask:02b})");
115 if let Some(e) = self.controller.pressed(vm, Key::Right, true) {
116 events.push(e);
117 }
118 if let Some(event) = self.controller.released(vm, Key::Right) {
119 events.push(event);
120 }
121 } else {
122 println!("[USB] Pedal {i} released (bit {mask:02b})");
123 if let Some(event) = self.controller.released(vm, Key::Right) {
124 events.push(event);
125 }
126 }
127 }
128 }
129 }
130 None => {
131 println!("[USB] Initial pedal state: 0x{pedal_byte:02x}");
132 }
133 }
134 self.last_pedal = Some(pedal_byte);
135 } else {
136 println!("[USB] No pedal byte in message: {msg:?}");
137 }
138 }
139 if !events.is_empty() {
140 println!("[USB] Polling complete, returning {} events", events.len());
141 }
142 events
143 }
144 }
155
156#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
157impl ControllerUsb {
158 #[cfg(feature = "uses_gilrs")]
160 pub fn new(
161 controller: Controller,
162 rx: std::sync::mpsc::Receiver<UsbControllerMessage>,
163 gilrs: Option<ControllerGilrs>,
164 ) -> Self {
165 ControllerUsb {
166 rx,
167 last_pedal: None,
168 controller,
169 gilrs,
170 }
171 }
172
173 #[cfg(not(feature = "uses_gilrs"))]
174 pub fn new(
175 controller: Controller,
176 rx: std::sync::mpsc::Receiver<UsbControllerMessage>,
177 ) -> Self {
178 ControllerUsb {
179 rx,
180 last_pedal: None,
181 controller,
182 }
183 }
184
185 #[allow(dead_code)]
186 fn check_buttons(&mut self, vm: &mut Uxn, repeat: bool) -> Option<Event> {
188 self.controller.check_buttons(vm, repeat)
189 }
190}
191
192#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
193use hidapi::HidApi;
194use std::sync::mpsc;
195use std::thread;
196
197#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
198#[derive(Debug)]
200pub struct UsbControllerMessage {
201 pub data: Vec<u8>,
203}
204
205#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
206#[derive(Clone, Copy, Debug)]
208pub struct UsbDeviceConfig {
209 pub vendor_id: u16,
211 pub product_id: u16,
213}
214
215#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
216impl Default for UsbDeviceConfig {
217 fn default() -> Self {
219 UsbDeviceConfig {
237 vendor_id: 0x05f3,
238 product_id: 0x00ff,
239 }
240 }
241}
242
243#[cfg(all(feature = "uses_usb", not(target_arch = "wasm32")))]
244pub fn spawn_usb_controller_thread(
246 config: UsbDeviceConfig,
247) -> mpsc::Receiver<UsbControllerMessage> {
248 let (tx, rx) = mpsc::channel();
249 thread::spawn(move || {
250 println!("[USB] Starting HID thread, attempting to create API instance...");
251 let api = match HidApi::new() {
252 Ok(api) => api,
253 Err(e) => {
254 println!("[USB] Failed to create HID API instance: {e}");
255 return;
256 }
257 };
258 println!(
259 "[USB] HID API instance created. Attempting to open device {:04x}:{:04x}...",
260 config.vendor_id, config.product_id
261 );
262 let joystick = match api.open(config.vendor_id, config.product_id) {
263 Ok(dev) => {
264 println!("[USB] Device opened successfully.");
265 dev
266 }
267 Err(e) => {
268 println!("[USB] Failed to open device: {e}");
269 return;
270 }
271 };
272 loop {
273 let mut buf = [0u8; 256];
274 match joystick.read(&mut buf[..]) {
275 Ok(res) => {
276 let data = buf[..res].to_vec();
277 println!("[USB] Read {res} bytes: {data:?}");
278 let _ = tx.send(UsbControllerMessage { data });
279 }
280 Err(e) => {
281 println!("[USB] Error reading from device: {e}");
282 }
283 }
284 }
285 });
286 rx
287}