mindustry logic execution, map- and schematic- parsing and rendering
add linePoly
| -rw-r--r-- | lemu/Cargo.toml | 4 | ||||
| -rw-r--r-- | lemu/src/instructions/draw.rs | 56 | ||||
| -rw-r--r-- | lemu/src/parser/mod.rs | 20 |
3 files changed, 70 insertions, 10 deletions
diff --git a/lemu/Cargo.toml b/lemu/Cargo.toml index 13604c0..5985dad 100644 --- a/lemu/Cargo.toml +++ b/lemu/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lemu" -version = "0.2.12" +version = "0.2.13" edition = "2021" description = "M-LOG runner" authors = ["bend-n <[email protected]>"] @@ -12,7 +12,7 @@ keywords = ["mindustry", "logic", "emulator", "executor"] [dependencies] thiserror = "1.0" enum_dispatch = "0.3" -fimg = { version = "0.4.10", default-features = false } +fimg = { version = "0.4.16", default-features = false } logos = "0.13.0" rust-fuzzy-search = { version = "0.1.1", optional = true } beef = "0.5" diff --git a/lemu/src/instructions/draw.rs b/lemu/src/instructions/draw.rs index 1e57447..fc93d8f 100644 --- a/lemu/src/instructions/draw.rs +++ b/lemu/src/instructions/draw.rs @@ -8,7 +8,7 @@ use fimg::Image; use std::fmt::{self, Display as Disp, Formatter}; pub const INSTRS: &[&str] = &[ - "clear", "color", "col", "stroke", "line", "rect", "lineRect", "triangle", "poly", + "clear", "color", "col", "stroke", "line", "rect", "lineRect", "triangle", "poly", "linePoly", ]; #[enum_dispatch] @@ -32,6 +32,7 @@ pub enum DrawInstr<'v> { SetColor(SetColor<'v>), SetStroke(SetStroke<'v>), Poly(Poly<'v>), + LinePoly(LinePoly<'v>), } impl Disp for DrawInstr<'_> { @@ -45,6 +46,7 @@ impl Disp for DrawInstr<'_> { Self::SetColor(i) => write!(f, "{i}"), Self::SetStroke(i) => write!(f, "{i}"), Self::Poly(i) => write!(f, "{i}"), + Self::LinePoly(i) => write!(f, "{i}"), } } } @@ -54,7 +56,6 @@ pub struct Clear<'v> { pub r: LAddress<'v>, pub g: LAddress<'v>, pub b: LAddress<'v>, - pub a: LAddress<'v>, } impl<'v> DrawInstruction<'v> for Clear<'v> { @@ -67,16 +68,16 @@ impl<'v> DrawInstruction<'v> for Clear<'v> { } }; } - let (r, g, b, a) = (u8!(r), u8!(g), u8!(b), u8!(a)); + let (r, g, b) = (u8!(r), u8!(g), u8!(b)); for [r2, g2, b2, a2] in image.chunked_mut() { - (*r2, *b2, *g2, *a2) = (r, g, b, a); + (*r2, *b2, *g2, *a2) = (r, g, b, 255); } } } impl Disp for Clear<'_> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "draw clear {} {} {} {}", self.r, self.g, self.b, self.a) + write!(f, "draw clear {} {} {}", self.r, self.g, self.b) } } @@ -306,6 +307,51 @@ impl Disp for Poly<'_> { } } +#[derive(Debug)] +pub struct LinePoly<'v> { + pub(crate) pos: Point<'v>, + pub(crate) sides: LAddress<'v>, + pub(crate) radius: LAddress<'v>, + pub(crate) rot: LAddress<'v>, +} + +impl<'v> DrawInstruction<'v> for LinePoly<'v> { + fn draw( + &self, + mem: &mut LRegistry<'v>, + image: &mut Image<&mut [u8], 4>, + state: &mut DisplayState, + ) { + let sides = get_num!(mem.get(&self.sides)).round() as usize; + if sides < 90 { + image.border_poly( + map!(point!([email protected]), |n| n as f32), + sides, + get_num!(mem.get(&self.radius)) as f32, + get_num!(mem.get(&self.rot)) as f32, + state.stroke as f32, + state.col(), + ); + } else { + image.border_circle( + map!(point!([email protected]), |n: f64| n.round() as i32), + get_num!(mem.get(&self.radius)).round() as i32, + state.col(), + ); + } + } +} + +impl Disp for LinePoly<'_> { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "draw linePoly {} {} {} {} {}", + self.pos.0, self.pos.1, self.sides, self.radius, self.rot + ) + } +} + #[derive(Debug, Default)] pub struct Flush { pub(crate) display: Display, diff --git a/lemu/src/parser/mod.rs b/lemu/src/parser/mod.rs index 53c2940..1091a82 100644 --- a/lemu/src/parser/mod.rs +++ b/lemu/src/parser/mod.rs @@ -6,7 +6,10 @@ pub use error::Error; use super::{ executor::{ExecutorBuilderInternal, Instruction, UPInstr}, instructions::{ - draw::{Clear, Flush, Line, Poly, RectBordered, RectFilled, SetColor, SetStroke, Triangle}, + draw::{ + Clear, Flush, Line, LinePoly, Poly, RectBordered, RectFilled, SetColor, SetStroke, + Triangle, + }, io::{Print, Read, Write}, AlwaysJump, ConditionOp, DynJump, End, Instr, Jump, MathOp1, MathOp2, Op1, Op2, Set, Stop, }, @@ -327,6 +330,8 @@ pub fn parse<'source, W: Wr>( yeet!(ExpectedIdent(dty)); }; #[rustfmt::skip] + macro_rules! three { ($a:expr) => { ($a, $a, $a) }; } + #[rustfmt::skip] macro_rules! four { ($a:expr) => { ($a, $a, $a, $a) }; } #[rustfmt::skip] macro_rules! five { ($a:expr) => { ($a, $a, $a, $a, $a) }; } @@ -334,8 +339,8 @@ pub fn parse<'source, W: Wr>( macro_rules! six { ($a:expr) => { ($a, $a, $a, $a, $a, $a) }; } match instr { "clear" => { - let (r, g, b, a) = four! { take_numvar!(tok!()?)? }; - executor.draw(Clear { r, g, b, a }); + let (r, g, b) = three! { take_numvar!(tok!()?)? }; + executor.draw(Clear { r, g, b }); } "color" => { let (r, g, b, a) = four! { take_numvar!(tok!()?)? }; @@ -396,6 +401,15 @@ pub fn parse<'source, W: Wr>( rot, }) } + "linePoly" => { + let (x, y, sides, radius, rot) = five! { take_numvar!(tok!()?)? }; + executor.draw(LinePoly { + pos: (x, y), + sides, + radius, + rot, + }) + } // image is WONTFIX i => yeet!(UnsupportedImageOp(i)), } |