summaryrefslogtreecommitdiff
path: root/src/sim
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2026-08-09 16:30:29 -0700
committerKai Stevenson <kai@kaistevenson.com>2026-08-09 16:30:29 -0700
commit167e31655b63aa4d4548532cf0410cea9fd145ca (patch)
tree2b9b3d3832404979fecfa3972464c37613d43db2 /src/sim
parent2eff3a26da27f68355ee2316f956e1bdfb6f1b68 (diff)
drawing
Diffstat (limited to 'src/sim')
-rw-r--r--src/sim/board.rs72
-rw-r--r--src/sim/materials.rs22
-rw-r--r--src/sim/mod.rs4
-rw-r--r--src/sim/overlay.rs50
-rw-r--r--src/sim/sim.rs3
5 files changed, 151 insertions, 0 deletions
diff --git a/src/sim/board.rs b/src/sim/board.rs
new file mode 100644
index 0000000..4cc5756
--- /dev/null
+++ b/src/sim/board.rs
@@ -0,0 +1,72 @@
+use crate::config::{PIXEL_BUFFER_HEIGHT, PIXEL_BUFFER_WIDTH};
+
+type MaterialId = u16;
+
+#[derive(Clone, Copy)]
+pub struct Cell {
+ pub material: MaterialId,
+ pub velocity_x: i8,
+ pub velocity_y: i8,
+ pub flags: u8,
+}
+
+impl Cell {
+ fn empty() -> Cell {
+ Cell {
+ material: 0,
+ velocity_x: 0,
+ velocity_y: 0,
+ flags: 0,
+ }
+ }
+}
+
+pub struct Board {
+ pub size_x: u32,
+ pub size_y: u32,
+ pub cells: Vec<Cell>,
+}
+
+impl Board {
+ pub fn index_to_position(&self, idx: usize) -> (i32, i32) {
+ let y = idx / self.size_x as usize;
+ let x = idx % self.size_x as usize;
+ let board_x = x as i32 - self.size_x as i32 / 2;
+ let board_y = y as i32 - self.size_x as i32 / 2;
+ return (board_x, board_y);
+ }
+ pub fn set_cell_at_position(&mut self, x: i32, y: i32, c: Cell) {
+ // TODO: option?
+ let idx = self.position_to_index(x, y).unwrap();
+ self.cells[idx] = c;
+ }
+ pub fn cell_at_position(&self, x: i32, y: i32) -> Option<&Cell> {
+ Some(&self.cells[self.position_to_index(x, y)?])
+ }
+ pub fn position_to_index(&self, x: i32, y: i32) -> Option<usize> {
+ let board_x = x + self.size_x as i32 / 2;
+ let board_y = y + self.size_y as i32 / 2;
+
+ let on_board = board_x >= 0
+ && board_x < self.size_x as i32
+ && board_y >= 0
+ && board_y < self.size_y as i32;
+
+ if !on_board {
+ return None;
+ }
+
+ return Some((board_y * self.size_x as i32 + board_x) as usize);
+ }
+ pub fn empty() -> Board {
+ let size_x = PIXEL_BUFFER_WIDTH * 2;
+ let size_y = PIXEL_BUFFER_HEIGHT * 2;
+ let cells: Vec<Cell> = vec![Cell::empty(); (size_x * size_y) as usize];
+
+ Board {
+ size_x,
+ size_y,
+ cells,
+ }
+ }
+}
diff --git a/src/sim/materials.rs b/src/sim/materials.rs
new file mode 100644
index 0000000..13a45f3
--- /dev/null
+++ b/src/sim/materials.rs
@@ -0,0 +1,22 @@
+#[derive(Clone, Copy)]
+pub struct Material<'a> {
+ pub name: &'a str,
+ pub r: u8,
+ pub g: u8,
+ pub b: u8,
+}
+
+pub static MATERIALS: [Material; 2] = [
+ Material {
+ name: "Void",
+ r: 0x00,
+ g: 0x00,
+ b: 0x00,
+ },
+ Material {
+ name: "Sand",
+ r: 0xFF,
+ g: 0x00,
+ b: 0xFF,
+ },
+];
diff --git a/src/sim/mod.rs b/src/sim/mod.rs
new file mode 100644
index 0000000..2b29628
--- /dev/null
+++ b/src/sim/mod.rs
@@ -0,0 +1,4 @@
+pub mod board;
+pub mod materials;
+pub mod overlay;
+pub mod sim;
diff --git a/src/sim/overlay.rs b/src/sim/overlay.rs
new file mode 100644
index 0000000..36a810b
--- /dev/null
+++ b/src/sim/overlay.rs
@@ -0,0 +1,50 @@
+use crate::{Config, Input, sim::board::Board};
+
+pub fn create_compute_combined_overlay_offset(
+ board: &Board,
+ config: &Config,
+ input: &Input,
+) -> impl Fn(i32, i32) -> (u8, u8, u8, u8) {
+ |x: i32, y: i32| {
+ // could allow negative offsets too
+ let mut offset: (u8, u8, u8, u8) = (0x00, 0x00, 0x00, 0x00);
+
+ // bounds
+ // left
+ let xl = -((board.size_x / 2 + 1) as i32);
+ // right
+ let xu = (board.size_x / 2 + 1) as i32;
+ // bottom
+ let yl = -((board.size_y / 2 + 1) as i32);
+ // top
+ let yu = (board.size_y / 2 + 1) as i32;
+
+ if ((x == xl || x == xu) && (y <= yu && y >= yl))
+ || (y == yl || y == yu) && (x <= xu && x >= xl)
+ {
+ offset.0 = offset.0.saturating_add(0xFF);
+ offset.1 = offset.1.saturating_add(0xFF);
+ offset.2 = offset.2.saturating_add(0xFF);
+ }
+
+ // grid
+ if x % 30 == 0 || y % 30 == 0 {
+ offset.0 = offset.0.saturating_add(0x10);
+ offset.1 = offset.1.saturating_add(0x10);
+ offset.2 = offset.2.saturating_add(0x10);
+ }
+
+ // brush/selection
+ if (((x - input.last_mouse_pos_on_board.0).pow(2)
+ + (y - input.last_mouse_pos_on_board.1).pow(2)) as f32)
+ .sqrt()
+ < config.brush_size as f32
+ {
+ offset.0 = offset.0.saturating_add(0xAA);
+ offset.1 = offset.1.saturating_add(0x00);
+ offset.2 = offset.2.saturating_add(0xAA);
+ }
+
+ return offset;
+ }
+}
diff --git a/src/sim/sim.rs b/src/sim/sim.rs
new file mode 100644
index 0000000..bb68306
--- /dev/null
+++ b/src/sim/sim.rs
@@ -0,0 +1,3 @@
+use crate::Board;
+
+fn sim_tick(board: Board, seqno: u64) {}