mindustry logic execution, map- and schematic- parsing and rendering
Diffstat (limited to 'lemu/src/instructions/draw.rs')
-rw-r--r--lemu/src/instructions/draw.rs601
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)
- }
-}