From fc6c66ff314675fa257b1eaa25c169eb78372909 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Sat, 5 Oct 2024 20:22:18 +0200 Subject: [PATCH] add digit tool --- assets/digit_tool.png | Bin 0 -> 179 bytes assets/selection.png | Bin 116 -> 116 bytes src/main.rs | 158 ++++++++++++++++++++++++------------- src/marble_engine.rs | 18 ++--- src/marble_engine/board.rs | 19 ++++- 5 files changed, 130 insertions(+), 65 deletions(-) create mode 100644 assets/digit_tool.png diff --git a/assets/digit_tool.png b/assets/digit_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..64bc6eacac235f65098d5da71841d9ccfa6d98ea GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Rh}-6AsQ2tb0W)o8buBqI&h%i zo8ab+ckX*@t33!@E*{7bc au`w**^0&CXx^_Cy6%3xPelF{r5}E+}Gem#@ literal 0 HcmV?d00001 diff --git a/assets/selection.png b/assets/selection.png index 32e7b35bc723af32605e8eb85b13e432946ea2de..4842ff73690c63c9eae1f706b693eddff6c56414 100644 GIT binary patch delta 76 zcmXRZnV{?b|NsAbHZO)V3_(0j*A8<$HZU?Wnv`tlX_jo<(iwBsz#!|u3dREF6P~>i go--evanWO7cpzebC;v{j9Rm<}y85}Sb4q9e0I19zQvd(} delta 76 zcmXRZnV{>wf5Jn1W>tnX22D1_*NH8K5|1S%PHvo`GJB)sA(wS&5)!5fR~U9MK3U?{ gv&5$`O-Y=AAx%mv)64%KD+3UCy85}Sb4q9e073&AsQ>@~ diff --git a/src/main.rs b/src/main.rs index 48b4f93..26d6cf3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use std::{fs::read_to_string, ops::Rem}; use marble_engine::{ - board::Board, + board::{Board, Pos}, tile::{Direction, GateType, MathOp, MirrorType, PTile, Tile, WireType}, Machine, }; @@ -31,16 +31,16 @@ struct Game { time_since_step: f32, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone)] enum Tool { None, SetTile(Tile), + Digits(Option), Math, Gate, Wire, Arrow, Mirror, - Number, // SelectArea, } @@ -149,7 +149,7 @@ impl Game { } Tool::None => (), Tool::SetTile(_) => (), - Tool::Number => (), + Tool::Digits(_) => (), } } @@ -271,7 +271,7 @@ impl Game { texture_button( d, Vector2 { - x: 300. + col as f32 * bound_offset - if col < 0 { 15. } else { 0. }, + x: 320. + col as f32 * bound_offset - if col < 0 { 15. } else { 0. }, y: footer_top + 5. + row as f32 * bound_offset, }, textures.get(texture), @@ -281,7 +281,8 @@ impl Game { border, ); }; - tool_button((0, -1), "eraser", Tool::SetTile(Tile::from_char(' '))); + tool_button((0, -2), "eraser", Tool::SetTile(Tile::from_char(' '))); + tool_button((0, -1), "digit_tool", Tool::Digits(None)); tool_button((1, -1), "transparent", Tool::None); tool_button((0, 0), "block", Tool::SetTile(Tile::from_char('#'))); @@ -325,63 +326,110 @@ impl Game { } let mouse_pos = d.get_mouse_position(); - if self.sim_state == SimState::Editing && mouse_pos.y < footer_top { - let tile_pos = (mouse_pos - self.view_offset) / (16 << self.zoom) as f32; - let tile_pos = Vector2::new(tile_pos.x.floor(), tile_pos.y.floor()); - - let tile_screen_pos = tile_pos * (16 << self.zoom) as f32 + self.view_offset; - - if self.active_tool != Tool::None { - let tex = match self.active_tool { - Tool::None => unreachable!(), - Tool::SetTile(t) => { - if t == Tile::Blank { - "selection".into() - } else { - t.texture() - } - } - Tool::Math => format!("{}_off", self.tool_menu_math.texture_name()), - Tool::Gate => format!("{}_off", self.tool_menu_gate.texture_name()), - Tool::Wire => format!("{}_off", self.tool_menu_wire.texture_name()), - Tool::Arrow => self.tool_menu_arrow.arrow_texture_name().into(), - Tool::Mirror => self.tool_menu_mirror.texture_name().into(), - Tool::Number => todo!(), - }; - + if self.sim_state == SimState::Editing { + if let Tool::Digits(Some(pos)) = &mut self.active_tool { + let tile_screen_pos = pos.to_vec() * (16 << self.zoom) as f32 + self.view_offset; d.draw_texture_ex( - textures.get(&tex), + textures.get("selection"), tile_screen_pos, 0., (1 << self.zoom) as f32, - Color::new(255, 255, 255, 100), + Color::new(255, 180, 20, 255), ); + for n in 0..10 { + if d.is_key_pressed(unsafe { std::mem::transmute(KeyboardKey::KEY_ZERO as u32 + n) }) { + self.source_board.set(*pos, Tile::Digit(n as u8)); + } + } + if d.is_key_pressed(KeyboardKey::KEY_LEFT) { + pos.x -= 1; + } + if d.is_key_pressed(KeyboardKey::KEY_RIGHT) { + pos.x += 1; + } + if d.is_key_pressed(KeyboardKey::KEY_UP) { + pos.y -= 1; + } + if d.is_key_pressed(KeyboardKey::KEY_DOWN) { + pos.y += 1; + } } - if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) { - match self.active_tool { - Tool::None => (), - Tool::SetTile(tile) => self.source_board.set(tile_pos.into(), tile), - Tool::Math => self.source_board.set( - tile_pos.into(), - Tile::Powerable(PTile::Math(self.tool_menu_math), false), - ), - Tool::Gate => self.source_board.set( - tile_pos.into(), - Tile::Powerable(PTile::Gate(self.tool_menu_gate), false), - ), - Tool::Wire => self.source_board.set( - tile_pos.into(), - Tile::Powerable(PTile::Wire(self.tool_menu_wire), false), - ), - Tool::Arrow => self - .source_board - .set(tile_pos.into(), Tile::Arrow(self.tool_menu_arrow)), - Tool::Mirror => self - .source_board - .set(tile_pos.into(), Tile::Mirror(self.tool_menu_mirror)), - Tool::Number => todo!(), + if mouse_pos.y < footer_top { + let tile_pos = (mouse_pos - self.view_offset) / (16 << self.zoom) as f32; + let tile_pos = Vector2::new(tile_pos.x.floor(), tile_pos.y.floor()); + + let tile_screen_pos = tile_pos * (16 << self.zoom) as f32 + self.view_offset; + + if self.active_tool != Tool::None { + let tex = match self.active_tool { + Tool::None => unreachable!(), + Tool::SetTile(t) => { + if t == Tile::Blank { + "selection".into() + } else { + t.texture() + } + } + Tool::Math => format!("{}_off", self.tool_menu_math.texture_name()), + Tool::Gate => format!("{}_off", self.tool_menu_gate.texture_name()), + Tool::Wire => format!("{}_off", self.tool_menu_wire.texture_name()), + Tool::Arrow => self.tool_menu_arrow.arrow_texture_name().into(), + Tool::Mirror => self.tool_menu_mirror.texture_name().into(), + Tool::Digits(_) => "selection".into(), + }; + + d.draw_texture_ex( + textures.get(&tex), + tile_screen_pos, + 0., + (1 << self.zoom) as f32, + Color::new(255, 255, 255, 100), + ); + } + if d.is_mouse_button_down(MouseButton::MOUSE_BUTTON_LEFT) { + match self.active_tool { + Tool::None => (), + Tool::SetTile(tile) => self.source_board.set(tile_pos.into(), tile), + Tool::Math => self.source_board.set( + tile_pos.into(), + Tile::Powerable(PTile::Math(self.tool_menu_math), false), + ), + Tool::Gate => self.source_board.set( + tile_pos.into(), + Tile::Powerable(PTile::Gate(self.tool_menu_gate), false), + ), + Tool::Wire => self.source_board.set( + tile_pos.into(), + Tile::Powerable(PTile::Wire(self.tool_menu_wire), false), + ), + Tool::Arrow => self + .source_board + .set(tile_pos.into(), Tile::Arrow(self.tool_menu_arrow)), + Tool::Mirror => self + .source_board + .set(tile_pos.into(), Tile::Mirror(self.tool_menu_mirror)), + Tool::Digits(_pos) => { + self.active_tool = Tool::Digits(Some(tile_pos.into())); + if let Some(tile) = self.source_board.get_mut(tile_pos.into()) { + if let Tile::Digit(_) = tile { + } else { + *tile = Tile::Digit(0); + } + } + } + } } } } } } + +impl PartialEq for Tool{ + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (Self::SetTile(l0), Self::SetTile(r0)) => l0 == r0, + (Self::Digits(_), Self::Digits(_)) => true, + _ => ::core::mem::discriminant(self) == ::core::mem::discriminant(other), + } + } +} diff --git a/src/marble_engine.rs b/src/marble_engine.rs index 4157771..7cf90e4 100644 --- a/src/marble_engine.rs +++ b/src/marble_engine.rs @@ -89,7 +89,7 @@ impl Machine { // reset wires for y in 0..self.board.height() { for x in 0..self.board.width() { - if let Tile::Powerable(_, state) = self.board.get_mut((x, y).into()) { + if let Tile::Powerable(_, state) = self.board.get_mut_unchecked((x, y).into()) { *state = false; } } @@ -106,7 +106,7 @@ impl Machine { continue; } let mut new_tile = None; - let target = self.board.get_mut(next_pos); + let target = self.board.get_mut_unchecked(next_pos); match target { Tile::Blank => { *target = tile; @@ -175,7 +175,7 @@ impl Machine { Tile::Mirror(mirror) => { let new_dir = mirror.new_dir(dir); let far_pos = new_dir.step(next_pos); - let far_target = self.board.get_mut(far_pos); + let far_target = self.board.get_mut_unchecked(far_pos); if let Tile::Blank = far_target { *far_target = Tile::Marble { value, @@ -189,7 +189,7 @@ impl Machine { } if let Some(t) = new_tile { - *self.board.get_mut(marble_pos) = t; + *self.board.get_mut_unchecked(marble_pos) = t; } } } @@ -209,7 +209,7 @@ impl Machine { if !self.board.in_bounds(pos) { return; } - let tile = self.board.get_mut(pos); + let tile = self.board.get_mut_unchecked(pos); let front_pos = dir.step(pos); if let Tile::Powerable(tile, state) = tile { if let PTile::Trigger = tile { @@ -234,7 +234,7 @@ impl Machine { } PTile::Bag => { if let Some(Tile::Blank) = self.board.get(front_pos) { - *self.board.get_mut(front_pos) = Tile::Marble { value: 0, dir }; + *self.board.get_mut_unchecked(front_pos) = Tile::Marble { value: 0, dir }; self.marbles.push(front_pos); } } @@ -243,7 +243,7 @@ impl Machine { && self.board.get_or_blank(front_pos).is_blank() { let value = self.input[self.input_index] as MarbleValue; - *self.board.get_mut(front_pos) = Tile::Marble { value, dir }; + *self.board.get_mut_unchecked(front_pos) = Tile::Marble { value, dir }; self.marbles.push(front_pos); self.input_index += 1; } @@ -266,12 +266,12 @@ impl Machine { MathOp::Rem => val_a.checked_rem(val_b).unwrap_or_default(), }; // println!("{op:?} a:{val_a} b:{val_b}"); - *self.board.get_mut(front_pos) = Tile::Marble { value: result, dir }; + *self.board.get_mut_unchecked(front_pos) = Tile::Marble { value: result, dir }; self.marbles.push(front_pos); } } PTile::Flipper => { - let m = self.board.get_mut(front_pos); + let m = self.board.get_mut_unchecked(front_pos); match m { Tile::Powerable(PTile::Wire(wire_type), _) => { *wire_type = match *wire_type { diff --git a/src/marble_engine/board.rs b/src/marble_engine/board.rs index 08e4e5b..26064d8 100644 --- a/src/marble_engine/board.rs +++ b/src/marble_engine/board.rs @@ -9,6 +9,15 @@ pub struct Pos { pub y: isize, } +impl Pos { + pub const fn to_vec(&self) -> Vector2 { + Vector2 { + x: self.x as f32, + y: self.y as f32, + } + } +} + impl From<(usize, usize)> for Pos { fn from(value: (usize, usize)) -> Self { Self { @@ -91,7 +100,15 @@ impl Board { } } - pub fn get_mut(&mut self, p: Pos) -> &mut Tile { + pub fn get_mut(&mut self, p: Pos) -> Option<&mut Tile> { + if self.in_bounds(p) { + Some(&mut self.rows[p.y as usize][p.x as usize]) + } else { + None + } + } + + pub fn get_mut_unchecked(&mut self, p: Pos) -> &mut Tile { if self.in_bounds(p) { &mut self.rows[p.y as usize][p.x as usize] } else {