I can haz Lua?
This commit is contained in:
120
Cargo.lock
generated
120
Cargo.lock
generated
@@ -1779,6 +1779,16 @@ dependencies = [
|
||||
"piper",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "built"
|
||||
version = "0.8.0"
|
||||
@@ -2769,6 +2779,15 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "g13-os"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"embedded-graphics",
|
||||
"g13-driver",
|
||||
"mlua",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "1.1.0"
|
||||
@@ -3428,6 +3447,15 @@ dependencies = [
|
||||
"imgref",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "luau0-src"
|
||||
version = "0.18.2+luau708"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eed3214ab526e7e7b76c3f324a965d363db94a99ae67f65e67ec6fc499eb5e6d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mach2"
|
||||
version = "0.4.3"
|
||||
@@ -3528,6 +3556,55 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlua"
|
||||
version = "0.11.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccd36acfa49ce6ee56d1307a061dd302c564eee757e6e4cd67eb4f7204846fab"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"either",
|
||||
"erased-serde",
|
||||
"futures-util",
|
||||
"libc",
|
||||
"mlua-sys",
|
||||
"mlua_derive",
|
||||
"num-traits",
|
||||
"parking_lot",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"serde-value",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlua-sys"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f1c3a7fc7580227ece249fd90aa2fa3b39eb2b49d3aec5e103b3e85f2c3dfc8"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"luau0-src",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mlua_derive"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "465bddde514c4eb3b50b543250e97c1d4b284fa3ef7dc0ba2992c77545dbceb2"
|
||||
dependencies = [
|
||||
"itertools 0.14.0",
|
||||
"once_cell",
|
||||
"proc-macro-error2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "moxcms"
|
||||
version = "0.7.11"
|
||||
@@ -4109,6 +4186,15 @@ dependencies = [
|
||||
"libredox",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "2.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ordered-float"
|
||||
version = "5.0.0"
|
||||
@@ -4317,6 +4403,28 @@ dependencies = [
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error2"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr2",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
@@ -4775,6 +4883,16 @@ dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-value"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c"
|
||||
dependencies = [
|
||||
"ordered-float 2.10.1",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
@@ -5793,7 +5911,7 @@ dependencies = [
|
||||
"ndk-sys 0.6.0+11769913",
|
||||
"objc",
|
||||
"once_cell",
|
||||
"ordered-float",
|
||||
"ordered-float 5.0.0",
|
||||
"parking_lot",
|
||||
"portable-atomic",
|
||||
"portable-atomic-util",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["driver", "joystick", "mini-game"]
|
||||
default-members = ["joystick", "mini-game"]
|
||||
members = ["driver", "g13-os", "joystick", "mini-game"]
|
||||
default-members = ["joystick", "mini-game", "g13-os"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0"
|
||||
|
||||
@@ -24,7 +24,7 @@ pub const G13_LCD_BUF_SIZE: i32 = (G13_LCD_ROWS + 5) * G13_LCD_BYTES_PER_ROW;
|
||||
#[derive(Clone)]
|
||||
pub struct G13 {
|
||||
interface: Interface,
|
||||
img_buffer: [u8; G13_LCD_BUF_SIZE as usize + 8],
|
||||
img_buffer: Arc<RwLock<[u8; G13_LCD_BUF_SIZE as usize + 8]>>,
|
||||
state: Arc<RwLock<State>>,
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ impl G13 {
|
||||
|
||||
Ok(Self {
|
||||
interface,
|
||||
img_buffer,
|
||||
img_buffer: Arc::new(RwLock::new(img_buffer)),
|
||||
state: Arc::new(RwLock::new(Default::default())),
|
||||
})
|
||||
}
|
||||
@@ -191,9 +191,11 @@ impl G13 {
|
||||
}
|
||||
|
||||
pub fn render(&mut self) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let img_buffer = self.img_buffer.read().expect("Poisoned");
|
||||
|
||||
let mut buffer = [0u8; G13_LCD_BUF_SIZE as usize + 32 + 8];
|
||||
buffer[0] = 0x03;
|
||||
buffer[32..G13_LCD_BUF_SIZE as usize + 32 + 8].copy_from_slice(&self.img_buffer);
|
||||
buffer[32..G13_LCD_BUF_SIZE as usize + 32 + 8].copy_from_slice(&(*img_buffer));
|
||||
|
||||
let mut w = self.interface.endpoint::<Interrupt, Out>(0x02)?.writer(64);
|
||||
w.write_all(&buffer)?;
|
||||
@@ -219,6 +221,7 @@ impl DrawTarget for G13 {
|
||||
where
|
||||
I: IntoIterator<Item = embedded_graphics_core::Pixel<Self::Color>>,
|
||||
{
|
||||
let mut img_buffer = self.img_buffer.write().expect("Poisoned");
|
||||
for p in pixels {
|
||||
if p.0.x < 0 || p.0.x > G13_LCD_COLUMNS - 1 || p.0.y < 0 || p.0.y > G13_LCD_ROWS - 1 {
|
||||
continue;
|
||||
@@ -228,9 +231,9 @@ impl DrawTarget for G13 {
|
||||
let mask = 1 << (p.0.y.rem_euclid(8));
|
||||
|
||||
if p.1.is_on() {
|
||||
self.img_buffer[offset as usize] |= mask;
|
||||
img_buffer[offset as usize] |= mask;
|
||||
} else {
|
||||
self.img_buffer[offset as usize] &= !mask;
|
||||
img_buffer[offset as usize] &= !mask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
9
g13-os/Cargo.toml
Normal file
9
g13-os/Cargo.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "g13-os"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
|
||||
[dependencies]
|
||||
g13-driver.workspace = true
|
||||
embedded-graphics = "0.8"
|
||||
mlua = { version = "0.11.6", features = ["luau-jit", "async", "macros", "serde"] }
|
||||
87
g13-os/src/main.rs
Normal file
87
g13-os/src/main.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use std::{
|
||||
fs,
|
||||
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 g13 = G13::new()?;
|
||||
let lua = Lua::new();
|
||||
let globals = lua.globals();
|
||||
|
||||
let g13_table = lua.create_table()?;
|
||||
|
||||
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())?,
|
||||
)?;
|
||||
|
||||
let _g13 = g13.clone();
|
||||
let fn_clear = lua.create_function(move |_, on| {
|
||||
let mut _g13 = _g13.clone();
|
||||
use embedded_graphics::pixelcolor::BinaryColor;
|
||||
use embedded_graphics::prelude::*;
|
||||
let color = if on {
|
||||
BinaryColor::On
|
||||
} else {
|
||||
BinaryColor::Off
|
||||
};
|
||||
_g13.clear(color).into_lua_err()
|
||||
});
|
||||
g13_table.set("clear", fn_clear?)?;
|
||||
|
||||
let mut _g13 = g13.clone();
|
||||
let fn_set_pixel = lua.create_function_mut(move |_, (x, y, on)| {
|
||||
use embedded_graphics::pixelcolor::BinaryColor;
|
||||
use embedded_graphics::prelude::*;
|
||||
let color = if on {
|
||||
BinaryColor::On
|
||||
} else {
|
||||
BinaryColor::Off
|
||||
};
|
||||
Pixel(Point::new(x, y), color)
|
||||
.draw(&mut _g13)
|
||||
.into_lua_err()
|
||||
});
|
||||
g13_table.set("set_pixel", fn_set_pixel?)?;
|
||||
|
||||
g13_table.set("display_width", G13_LCD_COLUMNS)?;
|
||||
g13_table.set("display_height", G13_LCD_ROWS)?;
|
||||
|
||||
globals.set("g13", g13_table)?;
|
||||
|
||||
// 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")?;
|
||||
|
||||
lua.load(main).set_name("main.luau").exec()?;
|
||||
|
||||
if lua.load("setup ~= nil").eval()? {
|
||||
lua.load("setup()").exec()?;
|
||||
}
|
||||
|
||||
if lua.load("update ~= nil").eval()? {
|
||||
let mut _g13 = g13.clone();
|
||||
let mut delta: f32 = 0.0;
|
||||
loop {
|
||||
let start = Instant::now();
|
||||
|
||||
lua.load(format!("update({})", delta)).exec()?;
|
||||
_g13.render()?;
|
||||
|
||||
let duration = Instant::now() - start;
|
||||
|
||||
// 30 fps lock
|
||||
if duration < Duration::from_millis(33) {
|
||||
sleep(Duration::from_millis(33) - duration);
|
||||
}
|
||||
delta = (Instant::now() - start).as_secs_f32();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -28,7 +28,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let mut _g13 = g13.clone();
|
||||
tokio::spawn(async move {
|
||||
let character_style = MonoTextStyle::new(&FONT_10X20, BinaryColor::On);
|
||||
let character_style_time = MonoTextStyle::new(&FONT_10X20, BinaryColor::On);
|
||||
let character_style_date = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
|
||||
let textstyle = TextStyleBuilder::new()
|
||||
.alignment(Alignment::Center)
|
||||
.baseline(embedded_graphics::text::Baseline::Middle)
|
||||
@@ -39,21 +40,35 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let now = OffsetDateTime::now_utc().to_offset(offset!(+1)); // GMT+1
|
||||
|
||||
// Render
|
||||
let string = format!(
|
||||
let time = format!(
|
||||
"{:0>2}:{:0>2}:{:0>2}",
|
||||
now.hour(),
|
||||
now.minute(),
|
||||
now.second()
|
||||
);
|
||||
|
||||
let date = format!("{}, {} {}", now.weekday(), now.day(), now.month());
|
||||
|
||||
_g13.clear(BinaryColor::Off).unwrap();
|
||||
Text::with_text_style(
|
||||
&string,
|
||||
&time,
|
||||
Point::new(
|
||||
(G13_LCD_COLUMNS as f64 / 2.0) as i32,
|
||||
(G13_LCD_ROWS as f64 / 2.0) as i32,
|
||||
(G13_LCD_ROWS as f64 / 2.0) as i32 - 8,
|
||||
),
|
||||
character_style,
|
||||
character_style_time,
|
||||
textstyle,
|
||||
)
|
||||
.draw(&mut _g13)
|
||||
.unwrap();
|
||||
|
||||
Text::with_text_style(
|
||||
&date,
|
||||
Point::new(
|
||||
(G13_LCD_COLUMNS as f64 / 2.0) as i32,
|
||||
(G13_LCD_ROWS as f64 / 2.0) as i32 + 8,
|
||||
),
|
||||
character_style_date,
|
||||
textstyle,
|
||||
)
|
||||
.draw(&mut _g13)
|
||||
|
||||
43
scripts/main.luau
Normal file
43
scripts/main.luau
Normal file
@@ -0,0 +1,43 @@
|
||||
name = "DVD"
|
||||
authors = {"AviiNL"}
|
||||
description = "Bouncing 'dvd' Logo"
|
||||
|
||||
local width = g13.display_width
|
||||
local height = g13.display_height
|
||||
|
||||
local x = 22.0
|
||||
local y = 6.0
|
||||
|
||||
local x_direction = 1
|
||||
local y_direction = 1
|
||||
|
||||
local speed = 20
|
||||
|
||||
local size = 3
|
||||
|
||||
function update(delta: number)
|
||||
x = x + speed * delta * x_direction
|
||||
y = y + speed * delta * y_direction
|
||||
|
||||
if x <= size or x >= width - size then
|
||||
x_direction = -x_direction
|
||||
end
|
||||
|
||||
if y <= size or y >= height - size then
|
||||
y_direction = -y_direction
|
||||
end
|
||||
|
||||
color_x = (x / width) * 255
|
||||
color_y = (y / height) * 255
|
||||
color_z = 255 - (color_x + color_y) / 2
|
||||
|
||||
g13.set_color(color_x/2, color_y/2, color_z/2)
|
||||
|
||||
g13.clear()
|
||||
|
||||
for sy = -size,size do
|
||||
for sx = -size,size do
|
||||
g13.set_pixel(x + sx, y + sy, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user