Compare commits

..

2 Commits

Author SHA1 Message Date
3db5b5e094 input and text and stuff 2026-02-12 17:14:50 +01:00
5b27529cf8 x and y is not local, dumbass 2026-02-12 15:24:34 +01:00
4 changed files with 197 additions and 22 deletions

1
Cargo.lock generated
View File

@@ -2783,6 +2783,7 @@ dependencies = [
name = "g13-os" name = "g13-os"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"ctrlc",
"embedded-graphics", "embedded-graphics",
"g13-driver", "g13-driver",
"mlua", "mlua",

View File

@@ -6,4 +6,10 @@ edition.workspace = true
[dependencies] [dependencies]
g13-driver.workspace = true g13-driver.workspace = true
embedded-graphics = "0.8" 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"

View File

@@ -1,23 +1,48 @@
use g13_driver::{G13, G13_LCD_COLUMNS, G13_LCD_ROWS};
use mlua::{Error, ExternalResult, Lua};
use std::{ use std::{
fs, fs,
sync::{
Arc,
atomic::{AtomicBool, Ordering},
},
thread::sleep, thread::sleep,
time::{Duration, Instant}, 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>> { 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 g13 = G13::new()?;
let lua = Lua::new(); let lua = Lua::new();
let globals = lua.globals(); let globals = lua.globals();
let g13_table = lua.create_table()?; 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(); let _g13 = g13.clone();
g13_table.set( g13_table.set(
"set_color", "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(); let _g13 = g13.clone();
@@ -31,8 +56,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
BinaryColor::Off BinaryColor::Off
}; };
_g13.clear(color).into_lua_err() _g13.clear(color).into_lua_err()
}); })?;
g13_table.set("clear", fn_clear?)?; g13_table.set("clear", fn_clear)?;
let mut _g13 = g13.clone(); let mut _g13 = g13.clone();
let fn_set_pixel = lua.create_function_mut(move |_, (x, y, on)| { 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) Pixel(Point::new(x, y), color)
.draw(&mut _g13) .draw(&mut _g13)
.into_lua_err() .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_width", G13_LCD_COLUMNS)?;
g13_table.set("display_height", G13_LCD_ROWS)?; g13_table.set("display_height", G13_LCD_ROWS)?;
globals.set("g13", g13_table)?; 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]> // load all files from dir `./scripts` for now, user configurable later or ~/.config/g13-os/*.<lua[u]>
// for now, just main.luau // for now, just main.luau
let main = fs::read_to_string("./scripts/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()? { if lua.load("update ~= nil").eval()? {
let mut _g13 = g13.clone(); let mut _g13 = g13.clone();
let mut delta: f32 = 0.0; let mut delta: f32 = 0.0;
loop { while running.load(std::sync::atomic::Ordering::SeqCst) {
let start = Instant::now(); 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()?; lua.load(format!("update({})", delta)).exec()?;
_g13.render()?; _g13.render()?;
let duration = Instant::now() - start; let duration = Instant::now() - start;
@@ -79,9 +233,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
if duration < Duration::from_millis(33) { if duration < Duration::from_millis(33) {
sleep(Duration::from_millis(33) - duration); sleep(Duration::from_millis(33) - duration);
} }
delta = (Instant::now() - start).as_secs_f32(); delta = (Instant::now() - start).as_secs_f32();
} }
} }
running.store(false, Ordering::SeqCst);
Ok(()) Ok(())
} }

View File

@@ -15,25 +15,23 @@ local speed = 20
local size = 3 local size = 3
function setup()
joy.deadzone = 40
end
function update(delta: number) function update(delta: number)
local x = x + speed * delta * x_direction x = x + speed * delta * joy.x * 1.2
local y = y + speed * delta * y_direction y = y + speed * delta * joy.y
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
local color_x = (x / width) * 255 local color_x = (x / width) * 255
local color_y = (y / height) * 255 local color_y = (y / height) * 255
local color_z = 255 - (color_x + color_y) / 2 local color_z = 255 - (color_x + color_y) / 2
g13.clear()
g13.set_color(color_x/2, color_y/2, color_z/2) g13.set_color(color_x/2, color_y/2, color_z/2)
g13.clear() g13.text("Hello World!", 1, 1, true, 0, 0, 1)
for sy = -size,size do for sy = -size,size do
for sx = -size,size do for sx = -size,size do
@@ -41,3 +39,16 @@ function update(delta: number)
end end
end end
end end
function dump(o)
if type(o) == 'table' then
local s = '{ '
for k,v in pairs(o) do
if type(k) ~= 'number' then k = '"'..k..'"' end
s = s .. '['..k..'] = ' .. dump(v) .. ','
end
return s .. '} '
else
return tostring(o)
end
end