Compare commits
2 Commits
dd94bfdafa
...
a122fde6da
| Author | SHA1 | Date | |
|---|---|---|---|
| a122fde6da | |||
| 93fbc8fc12 |
@@ -1,6 +1,6 @@
|
|||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Axis {
|
pub enum Axis {
|
||||||
X,
|
X,
|
||||||
Y,
|
Y,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub enum Button {
|
pub enum Button {
|
||||||
Back,
|
Back,
|
||||||
Screen1,
|
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::*;
|
use Button::*;
|
||||||
[
|
[
|
||||||
Back, Screen1, Screen2, Screen3, Screen4, Light, M1, M2, M3, MR, G1, G2, G3, G4, G5, G6, G7, G8, G9, G10,
|
Back, Screen1, Screen2, Screen3, Screen4, Light, M1, M2, M3, MR, G1, G2, G3, G4, G5, G6, G7, G8, G9, G10,
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
// gracefully stolen from https://github.com/gwilymk/arduino-joystick/tree/master/joystick-daemon/src/joystick <3
|
||||||
|
|
||||||
mod axis;
|
mod axis;
|
||||||
mod button;
|
mod button;
|
||||||
mod error;
|
mod error;
|
||||||
|
|||||||
119
src/g13/mod.rs
119
src/g13/mod.rs
@@ -1,7 +1,9 @@
|
|||||||
pub mod joystick;
|
pub mod joystick;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
|
sync::Arc,
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -14,9 +16,12 @@ use nusb::{
|
|||||||
Interface,
|
Interface,
|
||||||
transfer::{ControlOut, ControlType, In, Interrupt, Out, Recipient},
|
transfer::{ControlOut, ControlType, In, Interrupt, Out, Recipient},
|
||||||
};
|
};
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use crate::g13::joystick::{Axis, Button, Joystick};
|
use crate::g13::joystick::{Axis, Button, Joystick};
|
||||||
|
|
||||||
|
const STICK_DEADZONE: i32 = 30;
|
||||||
|
|
||||||
pub const G13_LCD_COLUMNS: i32 = 160;
|
pub const G13_LCD_COLUMNS: i32 = 160;
|
||||||
pub const G13_LCD_ROWS: i32 = 43;
|
pub const G13_LCD_ROWS: i32 = 43;
|
||||||
pub const G13_LCD_BYTES_PER_ROW: i32 = G13_LCD_COLUMNS / 8;
|
pub const G13_LCD_BYTES_PER_ROW: i32 = G13_LCD_COLUMNS / 8;
|
||||||
@@ -27,6 +32,66 @@ pub struct G13 {
|
|||||||
interface: Interface,
|
interface: Interface,
|
||||||
joystick: Joystick,
|
joystick: Joystick,
|
||||||
img_buffer: [u8; G13_LCD_BUF_SIZE as usize + 8],
|
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 {
|
impl G13 {
|
||||||
@@ -65,6 +130,7 @@ impl G13 {
|
|||||||
interface,
|
interface,
|
||||||
joystick,
|
joystick,
|
||||||
img_buffer,
|
img_buffer,
|
||||||
|
state: Default::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,52 +139,91 @@ impl G13 {
|
|||||||
let mut buf = [0; 8];
|
let mut buf = [0; 8];
|
||||||
reader.read_exact(&mut buf)?;
|
reader.read_exact(&mut buf)?;
|
||||||
|
|
||||||
self.joystick
|
let x = (((buf[1] as f64) / 256.0 * 1024.0) - 512.0) as i32;
|
||||||
.move_axis(Axis::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.joystick
|
|
||||||
.move_axis(Axis::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
|
// the right most bit of the 7th byte is the back button
|
||||||
self.joystick.button_press(Button::Back, buf[6] & 0b00000001 != 0)?;
|
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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.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.joystick.button_press(Button::Stick3, buf[7] & 0b00001000 != 0)?;
|
||||||
|
self.state.set_button(Button::Stick3, buf[7] & 0b00001000 != 0).await;
|
||||||
|
|
||||||
self.joystick.synchronise()?;
|
self.joystick.synchronise()?;
|
||||||
|
|
||||||
@@ -157,7 +262,7 @@ impl G13 {
|
|||||||
|
|
||||||
impl Dimensions for G13 {
|
impl Dimensions for G13 {
|
||||||
fn bounding_box(&self) -> Rectangle {
|
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>>,
|
I: IntoIterator<Item = embedded_graphics_core::Pixel<Self::Color>>,
|
||||||
{
|
{
|
||||||
for p in pixels {
|
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 offset = image_byte_offset(p.0.y, p.0.x);
|
||||||
|
|
||||||
let mask = 1 << (p.0.y.rem_euclid(8));
|
let mask = 1 << (p.0.y.rem_euclid(8));
|
||||||
|
|||||||
34
src/main.rs
34
src/main.rs
@@ -6,7 +6,8 @@ use embedded_graphics::{
|
|||||||
prelude::*,
|
prelude::*,
|
||||||
text::{Alignment, Text, TextStyleBuilder},
|
text::{Alignment, Text, TextStyleBuilder},
|
||||||
};
|
};
|
||||||
use time::OffsetDateTime;
|
use time::{OffsetDateTime, macros::offset};
|
||||||
|
use tokio::time::Instant;
|
||||||
|
|
||||||
use crate::g13::{G13, G13_LCD_COLUMNS, G13_LCD_ROWS};
|
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)
|
.baseline(embedded_graphics::text::Baseline::Middle)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
loop {
|
let mut x = G13_LCD_COLUMNS as f64 / 2.0;
|
||||||
let now = OffsetDateTime::now_utc();
|
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());
|
let string = format!("{:0>2}:{:0>2}:{:0>2}", now.hour(), now.minute(), now.second());
|
||||||
|
|
||||||
_g13.clear(BinaryColor::Off).unwrap();
|
_g13.clear(BinaryColor::Off).unwrap();
|
||||||
Text::with_text_style(
|
Text::with_text_style(&string, Point::new(x as i32, y as i32), character_style, textstyle)
|
||||||
&string,
|
.draw(&mut _g13)
|
||||||
Point::new(G13_LCD_COLUMNS / 2, G13_LCD_ROWS / 2),
|
.unwrap();
|
||||||
character_style,
|
|
||||||
textstyle,
|
|
||||||
)
|
|
||||||
.draw(&mut _g13)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
_g13.render().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