input and text and stuff
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -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",
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,27 +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)
|
||||||
x = x + speed * delta * x_direction
|
x = x + speed * delta * joy.x * 1.2
|
||||||
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.set_color(color_x/2, color_y/2, color_z/2)
|
|
||||||
|
|
||||||
g13.clear()
|
g13.clear()
|
||||||
|
|
||||||
print(x, y)
|
g13.set_color(color_x/2, color_y/2, color_z/2)
|
||||||
|
|
||||||
|
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
|
||||||
@@ -43,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
|
||||||
|
|||||||
Reference in New Issue
Block a user