I/O
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::slice;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Axis {
|
||||
X,
|
||||
Y,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::slice;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum Button {
|
||||
Back,
|
||||
Screen1,
|
||||
@@ -88,7 +88,7 @@ impl Button {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn all_buttons() -> slice::Iter<'static, Self> {
|
||||
pub fn all_buttons() -> slice::Iter<'static, Self> {
|
||||
use Button::*;
|
||||
[
|
||||
Back, Screen1, Screen2, Screen3, Screen4, Light, M1, M2, M3, MR, G1, G2, G3, G4, G5, G6, G7, G8, G9, G10,
|
||||
|
||||
119
src/g13/mod.rs
119
src/g13/mod.rs
@@ -1,7 +1,9 @@
|
||||
pub mod joystick;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
io::{Read, Write},
|
||||
sync::Arc,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
@@ -14,9 +16,12 @@ use nusb::{
|
||||
Interface,
|
||||
transfer::{ControlOut, ControlType, In, Interrupt, Out, Recipient},
|
||||
};
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
use crate::g13::joystick::{Axis, Button, Joystick};
|
||||
|
||||
const STICK_DEADZONE: i32 = 30;
|
||||
|
||||
pub const G13_LCD_COLUMNS: i32 = 160;
|
||||
pub const G13_LCD_ROWS: i32 = 43;
|
||||
pub const G13_LCD_BYTES_PER_ROW: i32 = G13_LCD_COLUMNS / 8;
|
||||
@@ -27,6 +32,66 @@ pub struct G13 {
|
||||
interface: Interface,
|
||||
joystick: Joystick,
|
||||
img_buffer: [u8; G13_LCD_BUF_SIZE as usize + 8],
|
||||
pub state: State,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct State {
|
||||
x: Arc<RwLock<i32>>,
|
||||
y: Arc<RwLock<i32>>,
|
||||
buttons: Arc<RwLock<HashMap<Button, bool>>>,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
let mut buttons = HashMap::new();
|
||||
for button in Button::all_buttons() {
|
||||
buttons.insert(button.clone(), false);
|
||||
}
|
||||
|
||||
Self {
|
||||
x: Arc::new(RwLock::new(0)),
|
||||
y: Arc::new(RwLock::new(0)),
|
||||
buttons: Arc::new(RwLock::new(buttons)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
impl State {
|
||||
pub async fn get_x(&self) -> f64 {
|
||||
let mut value = *self.x.read().await;
|
||||
if value < STICK_DEADZONE && value > -STICK_DEADZONE {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
value as f64 / 512.0
|
||||
}
|
||||
|
||||
pub async fn get_y(&self) -> f64 {
|
||||
let mut value = *self.y.read().await;
|
||||
if value < STICK_DEADZONE && value > -STICK_DEADZONE {
|
||||
value = 0;
|
||||
}
|
||||
|
||||
value as f64 / 512.0
|
||||
}
|
||||
|
||||
pub async fn is_down(&self, button: Button) -> bool {
|
||||
self.buttons.read().await[&button]
|
||||
}
|
||||
|
||||
async fn set_x(&self, value: i32) {
|
||||
*self.x.write().await = value;
|
||||
}
|
||||
|
||||
async fn set_y(&self, value: i32) {
|
||||
*self.y.write().await = value;
|
||||
}
|
||||
|
||||
async fn set_button(&self, button: Button, value: bool) {
|
||||
self.buttons.write().await.insert(button, value);
|
||||
}
|
||||
}
|
||||
|
||||
impl G13 {
|
||||
@@ -65,6 +130,7 @@ impl G13 {
|
||||
interface,
|
||||
joystick,
|
||||
img_buffer,
|
||||
state: Default::default(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -73,52 +139,91 @@ impl G13 {
|
||||
let mut buf = [0; 8];
|
||||
reader.read_exact(&mut buf)?;
|
||||
|
||||
self.joystick
|
||||
.move_axis(Axis::X, (((buf[1] as f64) / 256.0 * 1024.0) - 512.0) as i32)?;
|
||||
self.joystick
|
||||
.move_axis(Axis::Y, (((buf[2] as f64) / 256.0 * 1024.0) - 512.0) as i32)?;
|
||||
let x = (((buf[1] as f64) / 256.0 * 1024.0) - 512.0) as i32;
|
||||
let y = (((buf[2] as f64) / 256.0 * 1024.0) - 512.0) as i32;
|
||||
|
||||
self.state.set_x(x).await;
|
||||
self.state.set_y(y).await;
|
||||
|
||||
self.joystick.move_axis(Axis::X, x)?;
|
||||
self.joystick.move_axis(Axis::Y, y)?;
|
||||
|
||||
// the right most bit of the 7th byte is the back button
|
||||
self.joystick.button_press(Button::Back, buf[6] & 0b00000001 != 0)?;
|
||||
self.state.set_button(Button::Back, buf[6] & 0b00000001 != 0).await;
|
||||
self.joystick.button_press(Button::Screen1, buf[6] & 0b00000010 != 0)?;
|
||||
self.state.set_button(Button::Screen1, buf[6] & 0b00000010 != 0).await;
|
||||
self.joystick.button_press(Button::Screen2, buf[6] & 0b00000100 != 0)?;
|
||||
self.state.set_button(Button::Screen2, buf[6] & 0b00000100 != 0).await;
|
||||
self.joystick.button_press(Button::Screen3, buf[6] & 0b00001000 != 0)?;
|
||||
self.state.set_button(Button::Screen3, buf[6] & 0b00001000 != 0).await;
|
||||
self.joystick.button_press(Button::Screen4, buf[6] & 0b00010000 != 0)?;
|
||||
self.state.set_button(Button::Screen4, buf[6] & 0b00010000 != 0).await;
|
||||
self.joystick.button_press(Button::Light, buf[7] & 0b0100000 != 0)?;
|
||||
self.state.set_button(Button::Light, buf[7] & 0b0100000 != 0).await;
|
||||
|
||||
self.joystick.button_press(Button::M1, buf[6] & 0b00100000 != 0)?;
|
||||
self.state.set_button(Button::M1, buf[6] & 0b00100000 != 0).await;
|
||||
self.joystick.button_press(Button::M2, buf[6] & 0b01000000 != 0)?;
|
||||
self.state.set_button(Button::M2, buf[6] & 0b01000000 != 0).await;
|
||||
self.joystick.button_press(Button::M3, buf[6] & 0b10000000 != 0)?;
|
||||
self.state.set_button(Button::M3, buf[6] & 0b10000000 != 0).await;
|
||||
self.joystick.button_press(Button::MR, buf[7] & 0b00000001 != 0)?;
|
||||
self.state.set_button(Button::MR, buf[7] & 0b00000001 != 0).await;
|
||||
|
||||
self.joystick.button_press(Button::G1, buf[3] & 0b00000001 != 0)?;
|
||||
self.state.set_button(Button::G1, buf[3] & 0b00000001 != 0).await;
|
||||
self.joystick.button_press(Button::G2, buf[3] & 0b00000010 != 0)?;
|
||||
self.state.set_button(Button::G2, buf[3] & 0b00000010 != 0).await;
|
||||
self.joystick.button_press(Button::G3, buf[3] & 0b00000100 != 0)?;
|
||||
self.state.set_button(Button::G3, buf[3] & 0b00000100 != 0).await;
|
||||
self.joystick.button_press(Button::G4, buf[3] & 0b00001000 != 0)?;
|
||||
self.state.set_button(Button::G4, buf[3] & 0b00001000 != 0).await;
|
||||
self.joystick.button_press(Button::G5, buf[3] & 0b00010000 != 0)?;
|
||||
self.state.set_button(Button::G5, buf[3] & 0b00010000 != 0).await;
|
||||
self.joystick.button_press(Button::G6, buf[3] & 0b00100000 != 0)?;
|
||||
self.state.set_button(Button::G6, buf[3] & 0b00100000 != 0).await;
|
||||
self.joystick.button_press(Button::G7, buf[3] & 0b01000000 != 0)?;
|
||||
self.state.set_button(Button::G7, buf[3] & 0b01000000 != 0).await;
|
||||
self.joystick.button_press(Button::G8, buf[3] & 0b10000000 != 0)?;
|
||||
self.state.set_button(Button::G8, buf[3] & 0b10000000 != 0).await;
|
||||
|
||||
self.joystick.button_press(Button::G9, buf[4] & 0b00000001 != 0)?;
|
||||
self.state.set_button(Button::G9, buf[4] & 0b00000001 != 0).await;
|
||||
self.joystick.button_press(Button::G10, buf[4] & 0b00000010 != 0)?;
|
||||
self.state.set_button(Button::G10, buf[4] & 0b00000010 != 0).await;
|
||||
self.joystick.button_press(Button::G11, buf[4] & 0b00000100 != 0)?;
|
||||
self.state.set_button(Button::G11, buf[4] & 0b00000100 != 0).await;
|
||||
self.joystick.button_press(Button::G12, buf[4] & 0b00001000 != 0)?;
|
||||
self.state.set_button(Button::G12, buf[4] & 0b00001000 != 0).await;
|
||||
self.joystick.button_press(Button::G13, buf[4] & 0b00010000 != 0)?;
|
||||
self.state.set_button(Button::G13, buf[4] & 0b00010000 != 0).await;
|
||||
self.joystick.button_press(Button::G14, buf[4] & 0b00100000 != 0)?;
|
||||
self.state.set_button(Button::G14, buf[4] & 0b00100000 != 0).await;
|
||||
self.joystick.button_press(Button::G15, buf[4] & 0b01000000 != 0)?;
|
||||
self.state.set_button(Button::G15, buf[4] & 0b01000000 != 0).await;
|
||||
self.joystick.button_press(Button::G16, buf[4] & 0b10000000 != 0)?;
|
||||
self.state.set_button(Button::G16, buf[4] & 0b10000000 != 0).await;
|
||||
|
||||
self.joystick.button_press(Button::G17, buf[5] & 0b00000001 != 0)?;
|
||||
self.state.set_button(Button::G17, buf[5] & 0b00000001 != 0).await;
|
||||
self.joystick.button_press(Button::G18, buf[5] & 0b00000010 != 0)?;
|
||||
self.state.set_button(Button::G18, buf[5] & 0b00000010 != 0).await;
|
||||
self.joystick.button_press(Button::G19, buf[5] & 0b00000100 != 0)?;
|
||||
self.state.set_button(Button::G19, buf[5] & 0b00000100 != 0).await;
|
||||
self.joystick.button_press(Button::G20, buf[5] & 0b00001000 != 0)?;
|
||||
self.state.set_button(Button::G20, buf[5] & 0b00001000 != 0).await;
|
||||
self.joystick.button_press(Button::G21, buf[5] & 0b00010000 != 0)?;
|
||||
self.state.set_button(Button::G21, buf[5] & 0b00010000 != 0).await;
|
||||
self.joystick.button_press(Button::G22, buf[5] & 0b00100000 != 0)?;
|
||||
self.state.set_button(Button::G22, buf[5] & 0b00100000 != 0).await;
|
||||
|
||||
self.joystick.button_press(Button::Stick1, buf[7] & 0b00000010 != 0)?;
|
||||
self.state.set_button(Button::Stick1, buf[7] & 0b00000010 != 0).await;
|
||||
self.joystick.button_press(Button::Stick2, buf[7] & 0b00000100 != 0)?;
|
||||
self.state.set_button(Button::Stick2, buf[7] & 0b00000100 != 0).await;
|
||||
self.joystick.button_press(Button::Stick3, buf[7] & 0b00001000 != 0)?;
|
||||
self.state.set_button(Button::Stick3, buf[7] & 0b00001000 != 0).await;
|
||||
|
||||
self.joystick.synchronise()?;
|
||||
|
||||
@@ -157,7 +262,7 @@ impl G13 {
|
||||
|
||||
impl Dimensions for G13 {
|
||||
fn bounding_box(&self) -> Rectangle {
|
||||
Rectangle::new(Point::new(1, 1), Size::new(160, 42))
|
||||
Rectangle::new(Point::new(0, 0), Size::new(160, 42))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,6 +275,10 @@ impl DrawTarget for G13 {
|
||||
I: IntoIterator<Item = embedded_graphics_core::Pixel<Self::Color>>,
|
||||
{
|
||||
for p in pixels {
|
||||
if p.0.x < 0 || p.0.x > G13_LCD_COLUMNS || p.0.y < 0 || p.0.y > G13_LCD_ROWS {
|
||||
continue;
|
||||
}
|
||||
|
||||
let offset = image_byte_offset(p.0.y, p.0.x);
|
||||
|
||||
let mask = 1 << (p.0.y.rem_euclid(8));
|
||||
|
||||
28
src/main.rs
28
src/main.rs
@@ -7,6 +7,7 @@ use embedded_graphics::{
|
||||
text::{Alignment, Text, TextStyleBuilder},
|
||||
};
|
||||
use time::{OffsetDateTime, macros::offset};
|
||||
use tokio::time::Instant;
|
||||
|
||||
use crate::g13::{G13, G13_LCD_COLUMNS, G13_LCD_ROWS};
|
||||
|
||||
@@ -26,24 +27,33 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.baseline(embedded_graphics::text::Baseline::Middle)
|
||||
.build();
|
||||
|
||||
let mut x = G13_LCD_COLUMNS as f64 / 2.0;
|
||||
let mut y = G13_LCD_ROWS as f64 / 2.0;
|
||||
|
||||
// 30 fps render loop
|
||||
let mut dt = 0.0;
|
||||
loop {
|
||||
let start = Instant::now();
|
||||
let now = OffsetDateTime::now_utc().to_offset(offset!(+1));
|
||||
|
||||
// Update Logic
|
||||
x += _g13.state.get_x().await * dt * 25.0;
|
||||
y += _g13.state.get_y().await * dt * 25.0;
|
||||
|
||||
// Render
|
||||
let string = format!("{:0>2}:{:0>2}:{:0>2}", now.hour(), now.minute(), now.second());
|
||||
|
||||
_g13.clear(BinaryColor::Off).unwrap();
|
||||
Text::with_text_style(
|
||||
&string,
|
||||
Point::new(G13_LCD_COLUMNS / 2, G13_LCD_ROWS / 2),
|
||||
character_style,
|
||||
textstyle,
|
||||
)
|
||||
.draw(&mut _g13)
|
||||
.unwrap();
|
||||
Text::with_text_style(&string, Point::new(x as i32, y as i32), character_style, textstyle)
|
||||
.draw(&mut _g13)
|
||||
.unwrap();
|
||||
|
||||
_g13.render().unwrap();
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
// Calculate delta time
|
||||
let delta = Instant::now() - start;
|
||||
tokio::time::sleep(Duration::from_millis(33) - delta).await;
|
||||
dt = (Instant::now() - start).as_secs_f64();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user