diff --git a/assets/tiles/add_off.png b/assets/tiles/add_off.png new file mode 100644 index 0000000..286a7e9 Binary files /dev/null and b/assets/tiles/add_off.png differ diff --git a/assets/tiles/add_on.png b/assets/tiles/add_on.png new file mode 100644 index 0000000..d9fe365 Binary files /dev/null and b/assets/tiles/add_on.png differ diff --git a/assets/tiles/bag_off.png b/assets/tiles/bag_off.png new file mode 100644 index 0000000..c270af5 Binary files /dev/null and b/assets/tiles/bag_off.png differ diff --git a/assets/tiles/bag_on.png b/assets/tiles/bag_on.png new file mode 100644 index 0000000..9630dab Binary files /dev/null and b/assets/tiles/bag_on.png differ diff --git a/assets/tiles/div_off.png b/assets/tiles/div_off.png new file mode 100644 index 0000000..272ecb4 Binary files /dev/null and b/assets/tiles/div_off.png differ diff --git a/assets/tiles/div_on.png b/assets/tiles/div_on.png new file mode 100644 index 0000000..3398ac3 Binary files /dev/null and b/assets/tiles/div_on.png differ diff --git a/assets/tiles/down.png b/assets/tiles/down.png new file mode 100644 index 0000000..9f40dea Binary files /dev/null and b/assets/tiles/down.png differ diff --git a/assets/tiles/eq_off.png b/assets/tiles/eq_off.png new file mode 100644 index 0000000..39f6cb1 Binary files /dev/null and b/assets/tiles/eq_off.png differ diff --git a/assets/tiles/eq_on.png b/assets/tiles/eq_on.png new file mode 100644 index 0000000..178d693 Binary files /dev/null and b/assets/tiles/eq_on.png differ diff --git a/assets/tiles/flipper_off.png b/assets/tiles/flipper_off.png new file mode 100644 index 0000000..71c7983 Binary files /dev/null and b/assets/tiles/flipper_off.png differ diff --git a/assets/tiles/flipper_on.png b/assets/tiles/flipper_on.png new file mode 100644 index 0000000..7da4ad9 Binary files /dev/null and b/assets/tiles/flipper_on.png differ diff --git a/assets/tiles/gt_off.png b/assets/tiles/gt_off.png new file mode 100644 index 0000000..28ba595 Binary files /dev/null and b/assets/tiles/gt_off.png differ diff --git a/assets/tiles/gt_on.png b/assets/tiles/gt_on.png new file mode 100644 index 0000000..ae01917 Binary files /dev/null and b/assets/tiles/gt_on.png differ diff --git a/assets/tiles/input_off.png b/assets/tiles/input_off.png new file mode 100644 index 0000000..c2606d7 Binary files /dev/null and b/assets/tiles/input_off.png differ diff --git a/assets/tiles/input_on.png b/assets/tiles/input_on.png new file mode 100644 index 0000000..418f467 Binary files /dev/null and b/assets/tiles/input_on.png differ diff --git a/assets/tiles/left.png b/assets/tiles/left.png new file mode 100644 index 0000000..5bb4a87 Binary files /dev/null and b/assets/tiles/left.png differ diff --git a/assets/tiles/lt_off.png b/assets/tiles/lt_off.png new file mode 100644 index 0000000..6b8bb6b Binary files /dev/null and b/assets/tiles/lt_off.png differ diff --git a/assets/tiles/lt_on.png b/assets/tiles/lt_on.png new file mode 100644 index 0000000..591877f Binary files /dev/null and b/assets/tiles/lt_on.png differ diff --git a/assets/tiles/mul_off.png b/assets/tiles/mul_off.png new file mode 100644 index 0000000..8fb3dc7 Binary files /dev/null and b/assets/tiles/mul_off.png differ diff --git a/assets/tiles/mul_on.png b/assets/tiles/mul_on.png new file mode 100644 index 0000000..0120b07 Binary files /dev/null and b/assets/tiles/mul_on.png differ diff --git a/assets/tiles/neq_off.png b/assets/tiles/neq_off.png new file mode 100644 index 0000000..a649dd1 Binary files /dev/null and b/assets/tiles/neq_off.png differ diff --git a/assets/tiles/neq_on.png b/assets/tiles/neq_on.png new file mode 100644 index 0000000..af8cba0 Binary files /dev/null and b/assets/tiles/neq_on.png differ diff --git a/assets/tiles/output_off.png b/assets/tiles/output_off.png new file mode 100644 index 0000000..43fb910 Binary files /dev/null and b/assets/tiles/output_off.png differ diff --git a/assets/tiles/output_on.png b/assets/tiles/output_on.png new file mode 100644 index 0000000..9271dec Binary files /dev/null and b/assets/tiles/output_on.png differ diff --git a/assets/tiles/rem_off.png b/assets/tiles/rem_off.png new file mode 100644 index 0000000..23093cd Binary files /dev/null and b/assets/tiles/rem_off.png differ diff --git a/assets/tiles/rem_on.png b/assets/tiles/rem_on.png new file mode 100644 index 0000000..dde5d96 Binary files /dev/null and b/assets/tiles/rem_on.png differ diff --git a/assets/tiles/right.png b/assets/tiles/right.png new file mode 100644 index 0000000..f3dc6b9 Binary files /dev/null and b/assets/tiles/right.png differ diff --git a/assets/tiles/sub_off.png b/assets/tiles/sub_off.png new file mode 100644 index 0000000..af38167 Binary files /dev/null and b/assets/tiles/sub_off.png differ diff --git a/assets/tiles/sub_on.png b/assets/tiles/sub_on.png new file mode 100644 index 0000000..a2181e6 Binary files /dev/null and b/assets/tiles/sub_on.png differ diff --git a/assets/tiles/trigger_off.png b/assets/tiles/trigger_off.png new file mode 100644 index 0000000..a818b72 Binary files /dev/null and b/assets/tiles/trigger_off.png differ diff --git a/assets/tiles/trigger_on.png b/assets/tiles/trigger_on.png new file mode 100644 index 0000000..f730800 Binary files /dev/null and b/assets/tiles/trigger_on.png differ diff --git a/assets/tiles/up.png b/assets/tiles/up.png new file mode 100644 index 0000000..956e270 Binary files /dev/null and b/assets/tiles/up.png differ diff --git a/assets/tiles/wire_cross_off.png b/assets/tiles/wire_cross_off.png new file mode 100644 index 0000000..3b582ca Binary files /dev/null and b/assets/tiles/wire_cross_off.png differ diff --git a/assets/tiles/wire_cross_on.png b/assets/tiles/wire_cross_on.png new file mode 100644 index 0000000..c21ee12 Binary files /dev/null and b/assets/tiles/wire_cross_on.png differ diff --git a/assets/tiles/wire_horizontal_off.png b/assets/tiles/wire_horizontal_off.png new file mode 100644 index 0000000..b03fd94 Binary files /dev/null and b/assets/tiles/wire_horizontal_off.png differ diff --git a/assets/tiles/wire_horizontal_on.png b/assets/tiles/wire_horizontal_on.png new file mode 100644 index 0000000..4c5f82d Binary files /dev/null and b/assets/tiles/wire_horizontal_on.png differ diff --git a/assets/tiles/wire_vertical_off.png b/assets/tiles/wire_vertical_off.png new file mode 100644 index 0000000..7d060e4 Binary files /dev/null and b/assets/tiles/wire_vertical_off.png differ diff --git a/assets/tiles/wire_vertical_on.png b/assets/tiles/wire_vertical_on.png new file mode 100644 index 0000000..37d508c Binary files /dev/null and b/assets/tiles/wire_vertical_on.png differ diff --git a/src/main.rs b/src/main.rs index ae41baa..e5dc30a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,7 @@ -use std::fs::read_to_string; +use std::{ + collections::HashMap, + fs::{read_dir, read_to_string}, +}; use marble_engine::parse; use raylib::prelude::*; @@ -6,13 +9,28 @@ use raylib::prelude::*; mod marble_engine; fn main() { - let (mut rl, thread) = raylib::init().resizable().title("good window title").build(); + let (mut rl, thread) = raylib::init() + .resizable() + .title("good window title") + .build(); rl.set_target_fps(60); - let board = parse(&read_to_string("boards/adder.mbl").unwrap()); + let board = parse(&read_to_string("boards/counter.mbl").unwrap()); let mut pos_offset = Vector2::zero(); let mut machine = marble_engine::Machine::new(board, "Vec::new()".bytes().collect()); + let mut textures: HashMap = HashMap::new(); + for d in read_dir("assets/tiles").unwrap().flatten() { + let name = d.file_name(); + if d.path().is_file() { + let name = name.to_string_lossy(); + let texture = rl + .load_texture(&thread, &format!("assets/tiles/{name}")) + .unwrap(); + textures.insert(name.to_string(), texture); + } + } + while !rl.window_should_close() { if rl.is_key_pressed(KeyboardKey::KEY_SPACE) { machine.step(); @@ -27,7 +45,7 @@ fn main() { let mut d = rl.begin_drawing(&thread); d.clear_background(Color::new(64, 64, 64, 255)); - machine.draw(&mut d, pos_offset); + machine.draw(&mut d, &textures, pos_offset); d.draw_fps(2, 2); } diff --git a/src/marble_engine.rs b/src/marble_engine.rs index c8b043d..519477d 100644 --- a/src/marble_engine.rs +++ b/src/marble_engine.rs @@ -1,4 +1,6 @@ -use raylib::{drawing::RaylibDrawHandle, math::Vector2}; +use std::collections::HashMap; + +use raylib::{drawing::RaylibDrawHandle, math::Vector2, texture::Texture2D}; mod board; mod tile; @@ -48,14 +50,19 @@ impl Machine { } } - pub fn draw(&self, d: &mut RaylibDrawHandle, offset: Vector2) { + pub fn draw( + &self, + d: &mut RaylibDrawHandle, + textures: &HashMap, + offset: Vector2, + ) { let tile_size = 32; for x in 0..self.board.width() { for y in 0..self.board.height() { if let Some(tile) = self.board.get((x, y).into()) { let px = x as i32 * tile_size + offset.x as i32 + tile_size / 2; let py = y as i32 * tile_size + offset.y as i32 + tile_size / 2; - tile.draw(d, px, py, tile_size); + tile.draw(d, textures, px, py, tile_size); } } } @@ -66,10 +73,8 @@ impl Machine { // reset wires for y in 0..self.board.height() { for x in 0..self.board.width() { - match self.board.get_mut((x, y).into()) { - Tile::Powerable(_, state) => *state = false, - Tile::Trigger(state) => *state = false, - _ => (), + if let Tile::Powerable(_, state) = self.board.get_mut((x, y).into()) { + *state = false; } } } @@ -120,7 +125,7 @@ impl Machine { *other_dir = dir; } } - Tile::Trigger(state) => { + Tile::Powerable(PTile::Trigger, state) => { *state = true; triggers.push(next_pos); let far_pos = dir.step(next_pos); @@ -191,6 +196,9 @@ impl Machine { let tile = self.board.get_mut(pos); let front_pos = dir.step(pos); if let Tile::Powerable(tile, state) = tile { + if let PTile::Trigger = tile { + return; + } if *state { return; } @@ -285,6 +293,7 @@ impl Machine { self.propagate_power(dir, dir.step(pos)); } } + PTile::Trigger => (), } } } @@ -316,7 +325,7 @@ pub fn parse(source: &str) -> Board { value: 0, dir: Direction::Down, }, - '*' => Tile::Trigger(false), + '*' => Tile::Powerable(PTile::Trigger, false), '-' => Tile::Powerable(PTile::Wire(WireType::Horizontal), false), '|' => Tile::Powerable(PTile::Wire(WireType::Vertical), false), '+' => Tile::Powerable(PTile::Wire(WireType::Cross), false), diff --git a/src/marble_engine/tile.rs b/src/marble_engine/tile.rs index 7f24a40..439ece1 100644 --- a/src/marble_engine/tile.rs +++ b/src/marble_engine/tile.rs @@ -1,8 +1,11 @@ +use std::collections::HashMap; + use raylib::{ color::Color, drawing::{RaylibDraw, RaylibDrawHandle}, ffi::Rectangle, math::Vector2, + texture::Texture2D, }; use super::board::Pos; @@ -19,7 +22,6 @@ pub enum Tile { value: MarbleValue, dir: Direction, }, - Trigger(bool), Digit(u8), Mirror(MirrorType), Arrow(Direction), @@ -28,6 +30,7 @@ pub enum Tile { #[derive(Debug, Clone, Copy)] pub enum PTile { + Trigger, Wire(WireType), Gate(GateType), Math(MathOp), @@ -88,16 +91,73 @@ impl Tile { } } - pub fn draw(&self, d: &mut RaylibDrawHandle, x: i32, y: i32, size: i32) { - let up = y - size / 2 + 1; - let down = y + size / 2 - 1; - let left = x - size / 2 + 1; - let right = x + size / 2 - 1; + pub fn draw( + &self, + d: &mut RaylibDrawHandle, + textures: &HashMap, + x: i32, + y: i32, + size: i32, + ) { + let tex_name = match self { + Tile::Blank => "", + Tile::Block => "", + Tile::Comment(_) => "", + Tile::Marble { value, dir } => "todo!()", + Tile::Digit(_) => "", + Tile::Mirror(_) => "", + Tile::Arrow(dir) => match dir { + Direction::Up => "up", + Direction::Down => "down", + Direction::Left => "left", + Direction::Right => "right", + }, + Tile::Powerable(tile, state) => { + let t = match tile { + PTile::Trigger => "trigger", + PTile::Wire(wire) => match wire { + WireType::Vertical => "wire_vertical", + WireType::Horizontal => "wire_horizontal", + WireType::Cross => "wire_cross", + }, + PTile::Gate(gate) => match gate { + GateType::LessThan => "lt", + GateType::GreaterThan => "gt", + GateType::Equal => "eq", + GateType::NotEqual => "neq", + }, + PTile::Math(math_op) => match math_op { + MathOp::Add => "add", + MathOp::Sub => "sub", + MathOp::Mul => "mul", + MathOp::Div => "div", + MathOp::Rem => "rem", + }, + PTile::Bag => "bag", + PTile::Flipper => "flipper", + PTile::Input => "input", + PTile::Output => "output", + }; + &format!("{t}_{}", if *state { "on" } else { "off" }) + } + }; + let tex_name = format!("{tex_name}.png"); + if let Some(texture) = textures.get(&tex_name) { + d.draw_texture_ex( + texture, + Vector2::new((x - size / 2) as f32, (y - size / 2) as f32), + 0.0, + 2.0, + Color::WHITE, + ); + return; + } + match self { Tile::Blank => (), Tile::Block => d.draw_rectangle(x - size / 2, y - size / 2, size, size, Color::DIMGRAY), Tile::Comment(c) => { - d.draw_rectangle(x-size/2, y-size/2, size, size, Color::DIMGRAY); + d.draw_rectangle(x - size / 2, y - size / 2, size, size, Color::DIMGRAY); d.draw_text(&format!("{}", *c as char), x - 10, y - 10, 20, Color::WHITE); } Tile::Marble { value, dir } => { @@ -110,10 +170,6 @@ impl Tile { Color::MAGENTA, ); } - Tile::Trigger(state) => { - let color = if *state { Color::RED } else { Color::LIGHTGRAY }; - d.draw_rectangle(x - size / 4, y - size / 4, size / 2, size / 2, color) - } Tile::Digit(n) => { d.draw_text(&String::from(*n as char), x - 10, y - 10, 20, Color::ORANGE) } @@ -132,45 +188,7 @@ impl Tile { }; d.draw_rectangle_pro(rec, Vector2::new(width, height) * 0.5, rot, Color::CYAN); } - Tile::Arrow(dir) => { - let up = Vector2::from((x as f32, up as f32)); - let down = Vector2::from((x as f32, down as f32)); - let left = Vector2::from((left as f32, y as f32)); - let right = Vector2::from((right as f32, y as f32)); - let (v1, v2, v3) = match dir { - Direction::Up => (up, left, right), - Direction::Down => (down, right, left), - Direction::Left => (left, down, up), - Direction::Right => (right, up, down), - }; - d.draw_triangle(v1, v2, v3, Color::CYAN); - } - Tile::Powerable(tile, state) => { - let color = if *state { Color::RED } else { Color::LIGHTGRAY }; - match tile { - PTile::Bag => { - d.draw_circle(x, y, size as f32 * 0.4, color); - d.draw_circle(x, y, size as f32 * 0.2, Color::GRAY); - } - PTile::Wire(wire) => { - let vertical = !matches!(wire, WireType::Horizontal); - let horizontal = !matches!(wire, WireType::Vertical); - if vertical { - d.draw_rectangle(x - size / 8, y - size / 2, size / 4, size, color) - } - if horizontal { - d.draw_rectangle(x - size / 2, y - size / 8, size, size / 4, color) - } - } - // PTile::Gate(_) => todo!(), - // PTile::Math(_) => todo!(), - // PTile::Print => todo!(), - // PTile::Input => todo!(), - // PTile::Flip => todo!(), - _ => d.draw_rectangle(x - size / 2, y - size / 2, size, size, color), - } - } - + _ => d.draw_rectangle(x - size / 2, y - size / 2, size, size, Color::YELLOW), } } }