input and text and stuff
This commit is contained in:
@@ -6,4 +6,10 @@ edition.workspace = true
|
||||
[dependencies]
|
||||
g13-driver.workspace = true
|
||||
embedded-graphics = "0.8"
|
||||
mlua = { version = "0.11.6", features = ["luau-jit", "async", "macros", "serde"] }
|
||||
mlua = { version = "0.11.6", features = [
|
||||
"luau-jit",
|
||||
"async",
|
||||
"macros",
|
||||
"serde",
|
||||
] }
|
||||
ctrlc = "3.5"
|
||||
|
||||
@@ -1,23 +1,48 @@
|
||||
use g13_driver::{G13, G13_LCD_COLUMNS, G13_LCD_ROWS};
|
||||
use mlua::{Error, ExternalResult, Lua};
|
||||
use std::{
|
||||
fs,
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::{AtomicBool, Ordering},
|
||||
},
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
use g13_driver::{G13, G13_LCD_COLUMNS, G13_LCD_ROWS};
|
||||
use mlua::{ExternalResult, Lua};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let running = Arc::new(AtomicBool::new(true));
|
||||
|
||||
let _running = running.clone();
|
||||
ctrlc::set_handler(move || _running.store(false, Ordering::SeqCst))
|
||||
.expect("Error setting Ctrl-C handler");
|
||||
|
||||
let g13 = G13::new()?;
|
||||
let lua = Lua::new();
|
||||
let globals = lua.globals();
|
||||
|
||||
let g13_table = lua.create_table()?;
|
||||
|
||||
let _running = running.clone();
|
||||
let _g13 = g13.clone();
|
||||
std::thread::spawn(move || {
|
||||
while _running.load(Ordering::SeqCst) {
|
||||
if _g13.read().is_err() {
|
||||
_running.store(false, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let _g13 = g13.clone();
|
||||
g13_table.set(
|
||||
"set_color",
|
||||
lua.create_function(move |_, (r, g, b)| _g13.set_lcd_color(r, g, b).into_lua_err())?,
|
||||
lua.create_function(move |_, (r, g, b): (i32, i32, i32)| {
|
||||
_g13.set_lcd_color(
|
||||
r.clamp(0, 255) as u8,
|
||||
g.clamp(0, 255) as u8,
|
||||
b.clamp(0, 255) as u8,
|
||||
)
|
||||
.into_lua_err()
|
||||
})?,
|
||||
)?;
|
||||
|
||||
let _g13 = g13.clone();
|
||||
@@ -31,8 +56,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
BinaryColor::Off
|
||||
};
|
||||
_g13.clear(color).into_lua_err()
|
||||
});
|
||||
g13_table.set("clear", fn_clear?)?;
|
||||
})?;
|
||||
g13_table.set("clear", fn_clear)?;
|
||||
|
||||
let mut _g13 = g13.clone();
|
||||
let fn_set_pixel = lua.create_function_mut(move |_, (x, y, on)| {
|
||||
@@ -46,14 +71,107 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
Pixel(Point::new(x, y), color)
|
||||
.draw(&mut _g13)
|
||||
.into_lua_err()
|
||||
});
|
||||
g13_table.set("set_pixel", fn_set_pixel?)?;
|
||||
})?;
|
||||
g13_table.set("set_pixel", fn_set_pixel)?;
|
||||
|
||||
let mut _g13 = g13.clone();
|
||||
let fn_text = lua.create_function_mut(
|
||||
move |_,
|
||||
(text, x, y, color, alignment, baseline, size): (
|
||||
String,
|
||||
i32,
|
||||
i32,
|
||||
bool,
|
||||
i32,
|
||||
i32,
|
||||
i32,
|
||||
)| {
|
||||
use embedded_graphics::mono_font::ascii::*;
|
||||
use embedded_graphics::pixelcolor::BinaryColor;
|
||||
use embedded_graphics::prelude::*;
|
||||
use embedded_graphics::text::*;
|
||||
|
||||
let alignment = match alignment {
|
||||
0 => Alignment::Left,
|
||||
1 => Alignment::Center,
|
||||
2 => Alignment::Right,
|
||||
_ => {
|
||||
return Err(Error::RuntimeError(
|
||||
"Invalid alignment, allowed values: 0, 1, 2".into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let baseline = match baseline {
|
||||
0 => Baseline::Top,
|
||||
1 => Baseline::Middle,
|
||||
2 => Baseline::Bottom,
|
||||
_ => {
|
||||
return Err(Error::RuntimeError(
|
||||
"Invalid baseline, allowed values: 0, 1, 2".into(),
|
||||
));
|
||||
}
|
||||
};
|
||||
|
||||
let color = if color {
|
||||
BinaryColor::On
|
||||
} else {
|
||||
BinaryColor::Off
|
||||
};
|
||||
|
||||
let size = match size {
|
||||
2 => FONT_5X7,
|
||||
3 => FONT_5X8,
|
||||
4 => FONT_6X9,
|
||||
5 => FONT_6X10,
|
||||
6 => FONT_6X12,
|
||||
7 => FONT_6X13,
|
||||
8 => FONT_6X13_BOLD,
|
||||
9 => FONT_6X13_ITALIC,
|
||||
10 => FONT_7X13,
|
||||
11 => FONT_7X13_BOLD,
|
||||
12 => FONT_7X13_ITALIC,
|
||||
13 => FONT_7X14,
|
||||
14 => FONT_7X14_BOLD,
|
||||
15 => FONT_8X13,
|
||||
16 => FONT_8X13_BOLD,
|
||||
17 => FONT_8X13_ITALIC,
|
||||
18 => FONT_9X15,
|
||||
19 => FONT_9X15_BOLD,
|
||||
20 => FONT_9X18,
|
||||
21 => FONT_9X18_BOLD,
|
||||
22 => FONT_10X20,
|
||||
_ => FONT_4X6,
|
||||
};
|
||||
|
||||
let character_style = embedded_graphics::mono_font::MonoTextStyle::new(&size, color);
|
||||
|
||||
let textstyle = TextStyleBuilder::new()
|
||||
.alignment(alignment)
|
||||
.baseline(baseline)
|
||||
.build();
|
||||
|
||||
let pos = Point::new(x, y);
|
||||
|
||||
Text::with_text_style(&text, pos, character_style, textstyle)
|
||||
.draw(&mut _g13)
|
||||
.into_lua_err()?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
g13_table.set("text", fn_text)?;
|
||||
|
||||
g13_table.set("display_width", G13_LCD_COLUMNS)?;
|
||||
g13_table.set("display_height", G13_LCD_ROWS)?;
|
||||
|
||||
globals.set("g13", g13_table)?;
|
||||
|
||||
let joy = lua.create_table()?;
|
||||
joy.set("x", 0.0f32)?;
|
||||
joy.set("y", 0.0f32)?;
|
||||
joy.set("deadzone", 40)?;
|
||||
globals.set("joy", joy)?;
|
||||
|
||||
// load all files from dir `./scripts` for now, user configurable later or ~/.config/g13-os/*.<lua[u]>
|
||||
// for now, just main.luau
|
||||
let main = fs::read_to_string("./scripts/main.luau")?;
|
||||
@@ -67,10 +185,46 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if lua.load("update ~= nil").eval()? {
|
||||
let mut _g13 = g13.clone();
|
||||
let mut delta: f32 = 0.0;
|
||||
loop {
|
||||
while running.load(std::sync::atomic::Ordering::SeqCst) {
|
||||
let start = Instant::now();
|
||||
let state = g13.state();
|
||||
|
||||
let mut deadzone: i32 = lua.load("joy.deadzone").eval()?;
|
||||
if deadzone > 512 {
|
||||
deadzone = 0;
|
||||
}
|
||||
let offset: i32 = 512 - deadzone;
|
||||
let mut x = state.x;
|
||||
let mut y = state.y;
|
||||
|
||||
x = if x.abs() < deadzone {
|
||||
0
|
||||
} else {
|
||||
x - deadzone * x.signum()
|
||||
};
|
||||
|
||||
y = if y.abs() < deadzone {
|
||||
0
|
||||
} else {
|
||||
y - deadzone * y.signum()
|
||||
};
|
||||
|
||||
lua.load(format!(
|
||||
"joy.x = {}\njoy.y = {}",
|
||||
x as f32 / offset as f32,
|
||||
y as f32 / offset as f32
|
||||
))
|
||||
.exec()?;
|
||||
|
||||
let buttons = lua.create_table()?;
|
||||
buttons.set("t1", state.buttons.screen1)?;
|
||||
buttons.set("t2", state.buttons.screen2)?;
|
||||
buttons.set("t3", state.buttons.screen3)?;
|
||||
buttons.set("t4", state.buttons.screen4)?;
|
||||
globals.set("buttons", buttons)?;
|
||||
|
||||
lua.load(format!("update({})", delta)).exec()?;
|
||||
|
||||
_g13.render()?;
|
||||
|
||||
let duration = Instant::now() - start;
|
||||
@@ -79,9 +233,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
if duration < Duration::from_millis(33) {
|
||||
sleep(Duration::from_millis(33) - duration);
|
||||
}
|
||||
|
||||
delta = (Instant::now() - start).as_secs_f32();
|
||||
}
|
||||
}
|
||||
|
||||
running.store(false, Ordering::SeqCst);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user