mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'lemu/src/instructions/draw.rs')
| -rw-r--r-- | lemu/src/instructions/draw.rs | 601 |
1 files changed, 0 insertions, 601 deletions
diff --git a/lemu/src/instructions/draw.rs b/lemu/src/instructions/draw.rs deleted file mode 100644 index 1644da0..0000000 --- a/lemu/src/instructions/draw.rs +++ /dev/null @@ -1,601 +0,0 @@ -use super::{Flow, LInstruction, get_num}; -use crate::{ - debug::{info::DebugInfo, printable::Printable}, - executor::{Display, DisplayState, ExecutorContext}, - memory::{LAddress, LRegistry, LVar}, -}; -use enum_dispatch::enum_dispatch; -use fimg::Image; -use std::fmt::{self, Display as Disp}; -use vecto::Vec2; - -pub const INSTRS: &[&str] = &[ - "clear", "color", "col", "stroke", "line", "rect", "lineRect", "triangle", "poly", "linePoly", -]; - -#[enum_dispatch] -pub trait Apply: Disp { - fn apply(self, image: Image<&mut [u8], 4>, state: &mut DisplayState); -} - -#[derive(Debug)] -#[enum_dispatch(Apply)] -pub enum Drawn { - Line(LineD), - RectBordered(RectBorderedD), - RectFilled(RectFilledD), - Triangle(TriangleD), - Clear(ClearD), - SetColor(SetColorD), - SetStroke(SetStrokeD), - Poly(PolyD), - LinePoly(LinePolyD), -} - -impl std::fmt::Display for Drawn { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Line(i) => write!(f, "{i}"), - Self::RectBordered(i) => write!(f, "{i}"), - Self::RectFilled(i) => write!(f, "{i}"), - Self::Triangle(i) => write!(f, "{i}"), - Self::Clear(i) => write!(f, "{i}"), - Self::SetColor(i) => write!(f, "{i}"), - Self::SetStroke(i) => write!(f, "{i}"), - Self::Poly(i) => write!(f, "{i}"), - Self::LinePoly(i) => write!(f, "{i}"), - } - } -} - -pub trait Frozen<A: Apply>: Printable { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<A>; -} - -macro_rules! dinstr { - [$($x:ident),+] => { - #[derive(Debug, Copy, Clone)] - pub enum DrawInstr { - $($x($x),)+ - } - - $(impl From<$x> for DrawInstr { - fn from(v: $x) -> Self { Self::$x(v) } - })+ - - impl Frozen<Drawn> for DrawInstr { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<Drawn> { - Some(match self { - $(Self::$x(i) => Drawn::from(i.freeze(mem)?),)+ - }) - } - } - impl Printable for DrawInstr { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - match self { - $(Self::$x(i) => i.print(info, f)),+ - } - } - } - } -} - -dinstr! { - Line, - RectBordered, - RectFilled, - Triangle, - Clear, - SetColor, - SetCol, - SetStroke, - Poly, - LinePoly -} - -#[derive(Debug, Copy, Clone)] - -pub struct Clear { - pub r: LAddress, - pub g: LAddress, - pub b: LAddress, -} - -#[derive(Debug, Copy, Clone)] -pub struct ClearD((u8, u8, u8)); - -impl Apply for ClearD { - fn apply(self, mut image: Image<&mut [u8], 4>, _: &mut DisplayState) { - let (r, g, b) = self.0; - for [r2, g2, b2, a2] in image.chunked_mut() { - (*r2, *b2, *g2, *a2) = (r, g, b, 255); - } - } -} - -macro_rules! u8 { - ($self:ident, $mem:expr, $($v:ident)+) => { - ($(match $mem.get($self.$v) { - LVar::Num(n) => n.round() as u8, - _ => return None, - },)+) - }; -} - -impl Frozen<ClearD> for Clear { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<ClearD> { - Some(ClearD(u8!(self, mem, r g b))) - } -} - -impl Printable for Clear { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!( - f, - "draw clear {} {} {}", - info[self.r], info[self.g], info[self.b] - ) - } -} - -impl Disp for ClearD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "draw clear {} {} {}", self.0.0, self.0.1, self.0.2) - } -} - -#[derive(Debug, Copy, Clone)] -pub struct SetColorD((u8, u8, u8, u8)); - -impl Apply for SetColorD { - fn apply(self, _: Image<&mut [u8], 4>, state: &mut DisplayState) { - state.color = self.0; - } -} - -#[derive(Debug, Copy, Clone)] - -pub struct SetColor { - pub r: LAddress, - pub g: LAddress, - pub b: LAddress, - pub a: LAddress, -} - -impl Frozen<SetColorD> for SetColor { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<SetColorD> { - Some(SetColorD(u8!(self, mem, r g b a))) - } -} - -impl Printable for SetColor { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!( - f, - "draw color {} {} {} {}", - info[self.r], info[self.g], info[self.b], info[self.a] - ) - } -} - -#[derive(Debug, Copy, Clone)] -pub struct SetCol { - pub col: LAddress, -} - -impl Printable for SetCol { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!(f, "draw col ")?; - match &info[self.col] { - crate::debug::info::VarData::Variable(v) => write!(f, "{v}"), - crate::debug::info::VarData::Constant(c) => match c { - LVar::Num(n) => write!(f, "0x{:0<6x}", *n as u32), - LVar::String(s) => write!(f, r#""{s}""#), - }, - } - } -} - -impl Frozen<SetColorD> for SetCol { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<SetColorD> { - let [r, g, b, a] = fimg::Pack::unpack(mem.get(self.col).num()? as u32); - Some(SetColorD((r, g, b, a))) - } -} - -impl Disp for SetColorD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "draw color {} {} {} {}", - self.0.0, self.0.1, self.0.2, self.0.3 - ) - } -} - -#[derive(Debug, Copy, Clone)] - -pub struct SetStroke { - pub size: LAddress, -} - -#[derive(Debug, Copy, Clone)] -pub struct SetStrokeD(f64); - -impl Apply for SetStrokeD { - fn apply(self, _: Image<&mut [u8], 4>, state: &mut DisplayState) { - state.stroke = self.0; - } -} - -impl Frozen<SetStrokeD> for SetStroke { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<SetStrokeD> { - mem.get(self.size).num().map(SetStrokeD) - } -} - -impl Disp for SetStrokeD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "draw stroke {}", self.0) - } -} - -impl Printable for SetStroke { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!(f, "draw stroke {}", info[self.size]) - } -} - -pub type Point = (LAddress, LAddress); -#[rustfmt::skip] -macro_rules! point { - ($mem:ident@$point:expr) => { - ($mem.get($point.0).num()?, $mem.get($point.1).num()?) - } -} - -macro_rules! map { - ($tup:expr, $fn:expr) => {{ - let (a, b) = $tup; - ($fn(a), $fn(b)) - }}; -} -#[derive(Debug, Copy, Clone)] - -pub struct Line { - pub point_a: Point, - pub point_b: Point, -} - -#[derive(Debug)] -pub struct LineD(Vec2, Vec2); - -impl Apply for LineD { - fn apply(self, mut image: Image<&mut [u8], 4>, state: &mut DisplayState) { - image.thick_line(self.0, self.1, state.stroke as f32, state.col()); - } -} - -impl Frozen<LineD> for Line { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<LineD> { - Some(LineD( - map!(point!([email protected]_a), |n| n as f32).into(), - map!(point!([email protected]_b), |n| n as f32).into(), - )) - } -} - -impl Disp for LineD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "draw line {} {} {} {}", - self.0.x, self.0.y, self.1.x, self.1.y - ) - } -} - -impl Printable for Line { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!( - f, - "draw line {} {} {} {}", - info[self.point_a.0], info[self.point_a.1], info[self.point_b.0], info[self.point_b.1] - ) - } -} - -#[derive(Debug, Copy, Clone)] - -pub struct RectFilled { - pub position: Point, - pub width: LAddress, - pub height: LAddress, -} - -#[derive(Debug)] -pub struct RectFilledD((u32, u32), (u32, u32)); - -impl Apply for RectFilledD { - fn apply(self, mut image: Image<&mut [u8], 4>, state: &mut DisplayState) { - image.filled_box(self.0, self.1.0, self.1.1, state.col()); - } -} - -impl Frozen<RectFilledD> for RectFilled { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<RectFilledD> { - Some(RectFilledD( - map!(point!([email protected]), |n| n as u32), - ( - get_num!(mem.get(self.width)) as u32, - get_num!(mem.get(self.height)) as u32, - ), - )) - } -} - -impl Disp for RectFilledD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "draw rect {} {} {} {}", - self.0.0, self.0.1, self.1.0, self.1.1 - ) - } -} - -impl Printable for RectFilled { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!( - f, - "draw rect {} {} {} {}", - info[self.position.0], info[self.position.1], info[self.width], info[self.height] - ) - } -} - -#[derive(Debug, Copy, Clone)] - -pub struct RectBordered { - pub position: Point, - pub width: LAddress, - pub height: LAddress, -} - -impl Disp for RectBorderedD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "draw lineRect {} {} {} {}", - self.0.0, self.0.1, self.1.0, self.1.1 - ) - } -} - -impl Printable for RectBordered { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!( - f, - "draw lineRect {} {} {} {}", - info[self.position.0], info[self.position.1], info[self.width], info[self.height] - ) - } -} - -#[derive(Debug)] -pub struct RectBorderedD((u32, u32), (u32, u32)); - -impl Apply for RectBorderedD { - fn apply(self, mut image: Image<&mut [u8], 4>, state: &mut DisplayState) { - image.stroked_box( - self.0, - self.1.0, - self.1.1, - state.stroke.round() as u32, - state.col(), - ); - } -} - -impl Frozen<RectBorderedD> for RectBordered { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<RectBorderedD> { - Some(RectBorderedD( - map!(point!([email protected]), |n| n as u32), - ( - get_num!(mem.get(self.width)) as u32, - get_num!(mem.get(self.height)) as u32, - ), - )) - } -} - -#[derive(Debug, Copy, Clone)] - -pub struct Triangle { - pub points: (Point, Point, Point), -} - -#[derive(Debug)] -pub struct TriangleD(Vec2, Vec2, Vec2); - -impl Apply for TriangleD { - fn apply(self, mut image: Image<&mut [u8], 4>, state: &mut DisplayState) { - image.tri::<f32>(self.0, self.1, self.2, state.col()); - } -} - -impl Frozen<TriangleD> for Triangle { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<TriangleD> { - Some(TriangleD( - map!(point!([email protected]), |n| n as f32).into(), - map!(point!([email protected]), |n| n as f32).into(), - map!(point!([email protected]), |n| n as f32).into(), - )) - } -} - -impl Disp for TriangleD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "draw triangle {} {} {} {} {} {}", - self.0.x, self.0.y, self.1.x, self.1.y, self.2.x, self.2.y - ) - } -} - -impl Printable for Triangle { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!( - f, - "draw triangle {} {} {} {} {} {}", - info[self.points.0.0], - info[self.points.0.1], - info[self.points.1.0], - info[self.points.1.1], - info[self.points.2.0], - info[self.points.2.1] - ) - } -} - -#[derive(Debug, Copy, Clone)] - -pub struct Poly { - pub(crate) pos: Point, - pub(crate) sides: LAddress, - pub(crate) radius: LAddress, - pub(crate) rot: LAddress, -} - -#[derive(Debug)] -pub enum PolyD { - Poly(Vec2, usize, f32, f32), - Circle((i32, i32), i32), -} - -impl Apply for PolyD { - fn apply(self, mut image: Image<&mut [u8], 4>, state: &mut DisplayState) { - match self { - PolyD::Poly(pos, sides, radius, rotation) => { - image.poly(pos, sides, radius, rotation, state.col()) - } - PolyD::Circle(pos, radius) => image.circle(pos, radius, state.col()), - } - } -} - -impl Frozen<PolyD> for Poly { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<PolyD> { - let sides = get_num!(mem.get(self.sides)).round() as usize; - Some(if sides < 90 { - PolyD::Poly( - map!(point!([email protected]), |n| n as f32).into(), - sides, - get_num!(mem.get(self.radius)) as f32, - get_num!(mem.get(self.rot)) as f32, - ) - } else { - PolyD::Circle( - map!(point!([email protected]), |n: f64| n.round() as i32), - get_num!(mem.get(self.radius)).round() as i32, - ) - }) - } -} - -impl Disp for PolyD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - PolyD::Poly(Vec2 { x, y }, sides, radius, rot) => { - write!(f, "draw poly {x} {y} {sides} {radius} {rot}") - } - PolyD::Circle((x, y), sides) => write!(f, "draw poly {x} {y} {sides}"), - } - } -} - -impl Printable for Poly { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!( - f, - "draw poly {} {} {} {} {}", - info[self.pos.0], info[self.pos.1], info[self.sides], info[self.radius], info[self.rot], - ) - } -} - -#[derive(Debug, Copy, Clone)] - -pub struct LinePoly { - pub(crate) pos: Point, - pub(crate) sides: LAddress, - pub(crate) radius: LAddress, - pub(crate) rot: LAddress, -} - -#[derive(Debug)] -/// border_Circle doesnt let you specify a stroke -pub struct LinePolyD(Vec2, usize, f32, f32); - -impl Apply for LinePolyD { - fn apply(self, mut image: Image<&mut [u8], 4>, state: &mut DisplayState) { - image.border_poly( - self.0, - self.1, - self.2, - self.3, - state.stroke as f32, - state.col(), - ) - } -} - -impl Frozen<LinePolyD> for LinePoly { - fn freeze(&self, mem: &LRegistry<'_>) -> Option<LinePolyD> { - Some(LinePolyD( - map!(point!([email protected]), |n| n as f32).into(), - get_num!(mem.get(self.sides)).round() as usize, - get_num!(mem.get(self.radius)) as f32, - get_num!(mem.get(self.rot)) as f32, - )) - } -} - -impl Disp for LinePolyD { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "draw linePoly {} {} {} {} {}", - self.0.x, self.0.y, self.1, self.2, self.3 - ) - } -} - -impl Printable for LinePoly { - fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!( - f, - "draw linePoly {} {} {} {} {}", - info[self.pos.0], info[self.pos.1], info[self.sides], info[self.radius], info[self.rot], - ) - } -} - -#[derive(Debug, Copy, Clone, Default)] - -pub struct Flush { - pub(crate) display: Display, -} -impl LInstruction for Flush { - fn run<W: std::io::Write>(&self, exec: &mut ExecutorContext<'_, W>) -> Flow { - exec.flush(self.display); - Flow::Continue - } -} - -impl Printable for Flush { - fn print(&self, _: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { - write!(f, "drawflush {}", self.display) - } -} |