1pub use crate::controller_device::ControllerDevice;
2
3use crate::{Event, EventData};
4use std::{collections::HashSet, mem::offset_of};
5use uxn::{Ports, Uxn};
6use zerocopy::{BigEndian, U16};
7
8pub fn inject_pedal_keys(controller: &mut Controller, vm: &mut Uxn, prev: u8, pedal: u8) {
10 let pedal_map = [
11 (0, Key::Shift),
12 (1, Key::Ctrl),
13 (2, Key::Alt),
14 (3, Key::Home),
15 (4, Key::Up),
16 (5, Key::Down),
17 (6, Key::Left),
18 (7, Key::Right),
19 ];
20 for (bit, key) in pedal_map.iter() {
21 let was_down = (prev & (1 << bit)) != 0;
22 let is_down = (pedal & (1 << bit)) != 0;
23 if !was_down && is_down {
24 controller.pressed(vm, *key, false);
25 } else if was_down && !is_down {
26 controller.released(vm, *key);
27 }
28 }
29}
30
31#[derive(zerocopy::FromBytes, zerocopy::IntoBytes, zerocopy::Immutable, zerocopy::KnownLayout)]
32#[repr(C)]
33pub struct ControllerPorts {
35 pub vector: U16<BigEndian>,
37 pub button: u8,
39 pub key: u8,
41 pub _pad: [u8; 12],
43}
44
45impl Ports for ControllerPorts {
46 const BASE: u8 = 0x80;
47}
48
49impl ControllerPorts {
50 pub const KEY: u8 = Self::BASE | offset_of!(Self, key) as u8;
52}
53
54#[derive(Default)]
55pub struct Controller {
57 pub down: HashSet<Key>,
59
60 pub buttons: u8,
62}
63
64#[allow(missing_docs)]
66#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
67pub enum Key {
68 Shift,
69 Ctrl,
70 Alt,
71 Up,
72 Down,
73 Left,
74 Right,
75 Home,
76 End,
77 Char(u8),
78}
79
80impl Controller {
81 pub fn new() -> Self {
83 Self::default()
84 }
85
86 pub fn char(&mut self, vm: &mut Uxn, c: u8) -> Event {
88 let p = vm.dev::<ControllerPorts>();
89 let event = Event {
90 vector: p.vector.get(),
91 data: Some(EventData {
92 addr: ControllerPorts::KEY,
93 value: c,
94 clear: true,
95 }),
96 };
97 println!(
98 "[og CONTROLLER][char] char: '{}' (0x{:02x}), vector: 0x{:04x}, addr: 0x{:02x}",
99 c as char,
100 c,
101 event.vector,
102 ControllerPorts::KEY
103 );
104 event
105 }
106
107 pub fn pressed(&mut self, vm: &mut Uxn, k: Key, repeat: bool) -> Option<Event> {
109 if let Key::Char(k) = k {
110 Some(self.char(vm, k))
111 } else {
112 self.down.insert(k);
113 self.check_buttons(vm, repeat)
114 }
115 }
116
117 pub fn released(&mut self, vm: &mut Uxn, k: Key) -> Option<Event> {
121 if !matches!(k, Key::Char(..)) {
122 self.down.remove(&k);
123 self.check_buttons(vm, false)
124 } else {
125 None
126 }
127 }
128
129 pub fn check_buttons(&mut self, vm: &mut Uxn, repeat: bool) -> Option<Event> {
131 let mut buttons = 0;
132 for (i, k) in [
133 Key::Ctrl,
134 Key::Alt,
135 Key::Shift,
136 Key::Home,
137 Key::Up,
138 Key::Down,
139 Key::Left,
140 Key::Right,
141 ]
142 .iter()
143 .enumerate()
144 {
145 if self.down.contains(k) {
146 buttons |= 1 << i;
147 }
148 }
149
150 if buttons != self.buttons || repeat {
153 let p = vm.dev_mut::<ControllerPorts>();
154 self.buttons = buttons;
155 p.button = buttons;
156 Some(Event {
157 vector: p.vector.get(),
158 data: None,
159 })
160 } else {
161 None
162 }
163 }
164}