- World expanded to 4096x3072 (16x area, tiled 4x4 copies) - Active region margin increased to 200px - Liquid momentum system (FLAG_MOMENTUM) for wave sloshing - Zoom-at-cursor support (camera.zoomAt) - Smoother zoom steps (0.2 per scroll tick) - Light propagation scaled by zoom (passes & falloff) - AGENTS.md updated with all current features
186 lines
6.8 KiB
Rust
186 lines
6.8 KiB
Rust
mod grid;
|
|
mod material;
|
|
mod physics;
|
|
mod render_buffer;
|
|
|
|
use grid::Grid;
|
|
use physics::Physics;
|
|
use render_buffer::RenderBuffer;
|
|
|
|
fn main() {
|
|
let width = 4096u32;
|
|
let height = 3072u32;
|
|
let rw = 320u32;
|
|
let rh = 180u32;
|
|
let mut grid = Grid::new(width, height);
|
|
let mut physics = Physics::new();
|
|
let mut rb = RenderBuffer::new(rw, rh);
|
|
|
|
for ty in 0..4 {
|
|
for tx in 0..4 {
|
|
let ox = tx * 1024;
|
|
let oy = ty * 768;
|
|
grid.fill_rect(ox, oy + 740, 1024, 28, 1);
|
|
grid.fill_rect(ox + 20, oy + 680, 80, 60, 1);
|
|
grid.fill_rect(ox + 30, oy + 640, 60, 40, 1);
|
|
grid.fill_rect(ox + 40, oy + 610, 40, 30, 1);
|
|
grid.fill_circle(ox + 60, oy + 600, 15, 2);
|
|
grid.fill_rect(ox + 50, oy + 660, 20, 20, 2);
|
|
grid.fill_rect(ox, oy + 720, 120, 20, 1);
|
|
grid.fill_rect(ox + 85, oy + 705, 35, 15, 1);
|
|
grid.fill_rect(ox + 5, oy + 705, 60, 15, 1);
|
|
grid.fill_circle(ox + 60, oy + 712, 12, 6);
|
|
grid.fill_circle(ox + 70, oy + 708, 6, 6);
|
|
grid.fill_rect(ox + 60, oy + 695, 20, 10, 2);
|
|
grid.fill_rect(ox + 350, oy + 680, 100, 60, 1);
|
|
grid.fill_rect(ox + 365, oy + 640, 70, 40, 1);
|
|
grid.fill_rect(ox + 380, oy + 610, 40, 30, 1);
|
|
grid.fill_rect(ox + 390, oy + 660, 20, 20, 10);
|
|
grid.fill_rect(ox + 370, oy + 700, 60, 40, 5);
|
|
grid.fill_circle(ox + 400, oy + 690, 8, 9);
|
|
grid.fill_rect(ox + 395, oy + 675, 10, 5, 9);
|
|
grid.fill_rect(ox + 750, oy + 640, 50, 100, 1);
|
|
grid.fill_rect(ox + 760, oy + 610, 30, 30, 1);
|
|
grid.fill_rect(ox + 770, oy + 590, 10, 20, 1);
|
|
grid.fill_circle(ox + 775, oy + 580, 8, 9);
|
|
grid.fill_rect(ox + 760, oy + 650, 30, 40, 5);
|
|
grid.fill_rect(ox + 180, oy + 420, 100, 20, 1);
|
|
grid.fill_rect(ox + 190, oy + 400, 80, 20, 2);
|
|
grid.fill_circle(ox + 230, oy + 390, 15, 3);
|
|
grid.fill_rect(ox + 200, oy + 380, 30, 20, 5);
|
|
grid.fill_circle(ox + 215, oy + 385, 6, 9);
|
|
grid.fill_rect(ox + 240, oy + 410, 10, 10, 10);
|
|
grid.fill_rect(ox + 620, oy + 350, 80, 18, 1);
|
|
grid.fill_rect(ox + 630, oy + 335, 60, 15, 2);
|
|
grid.fill_circle(ox + 660, oy + 325, 12, 3);
|
|
grid.fill_circle(ox + 640, oy + 340, 8, 11);
|
|
grid.fill_rect(ox, oy + 700, 100, 40, 4);
|
|
grid.fill_rect(ox + 10, oy + 680, 80, 20, 4);
|
|
grid.fill_rect(ox + 20, oy + 660, 60, 20, 4);
|
|
grid.fill_rect(ox + 880, oy + 700, 80, 40, 6);
|
|
grid.fill_rect(ox + 890, oy + 680, 60, 20, 6);
|
|
grid.fill_rect(ox + 900, oy + 660, 40, 20, 6);
|
|
grid.fill_circle(ox + 420, oy + 280, 30, 11);
|
|
grid.fill_circle(ox + 450, oy + 270, 20, 11);
|
|
grid.fill_circle(ox + 390, oy + 290, 18, 11);
|
|
grid.fill_rect(ox + 420, oy + 300, 20, 15, 11);
|
|
grid.fill_rect(ox + 100, oy + 720, 180, 20, 3);
|
|
grid.fill_circle(ox + 120, oy + 710, 25, 3);
|
|
grid.fill_circle(ox + 180, oy + 708, 30, 3);
|
|
grid.fill_circle(ox + 160, oy + 700, 18, 3);
|
|
grid.fill_circle(ox + 220, oy + 715, 20, 3);
|
|
grid.fill_circle(ox + 850, oy + 580, 22, 12);
|
|
grid.fill_circle(ox + 870, oy + 590, 14, 12);
|
|
grid.fill_rect(ox + 840, oy + 600, 40, 20, 12);
|
|
grid.fill_rect(ox + 470, oy + 660, 280, 10, 5);
|
|
grid.fill_rect(ox + 490, oy + 650, 40, 10, 5);
|
|
grid.fill_rect(ox + 710, oy + 650, 40, 10, 5);
|
|
grid.fill_rect(ox + 520, oy + 720, 180, 20, 1);
|
|
grid.fill_rect(ox + 540, oy + 710, 140, 10, 1);
|
|
grid.fill_circle(ox + 600, oy + 718, 15, 6);
|
|
grid.fill_circle(ox + 620, oy + 716, 10, 6);
|
|
grid.fill_rect(ox + 100, oy + 730, 40, 10, 13);
|
|
grid.fill_circle(ox + 120, oy + 732, 8, 13);
|
|
grid.fill_rect(ox + 280, oy + 640, 40, 40, 10);
|
|
grid.fill_rect(ox + 290, oy + 650, 20, 30, 1);
|
|
grid.fill_circle(ox + 300, oy + 670, 5, 9);
|
|
grid.fill_circle(ox + 550, oy + 520, 20, 2);
|
|
grid.fill_circle(ox + 570, oy + 530, 14, 2);
|
|
grid.fill_circle(ox + 200, oy + 520, 30, 1);
|
|
grid.fill_circle(ox + 220, oy + 500, 20, 1);
|
|
grid.fill_rect(ox + 300, oy + 580, 12, 20, 4);
|
|
grid.fill_rect(ox + 700, oy + 500, 10, 30, 4);
|
|
}
|
|
}
|
|
|
|
let cam_x = 400i32;
|
|
let cam_y = 630i32;
|
|
let zoom = 2.0f32;
|
|
|
|
let mut frame = 0;
|
|
let start = std::time::Instant::now();
|
|
|
|
loop {
|
|
physics.update(&mut grid, cam_x, cam_y, rw, rh, zoom);
|
|
rb.render(&grid, cam_x, cam_y, zoom);
|
|
frame += 1;
|
|
|
|
if frame % 60 == 0 {
|
|
let elapsed = start.elapsed();
|
|
let fps = frame as f64 / elapsed.as_secs_f64();
|
|
let (fire, wood, spark, smoke) = count_mats(&grid);
|
|
|
|
println!("--- {}s (frame {}) fps: {:.0} ---", frame / 60, frame, fps);
|
|
println!("fire: {}, wood: {}, spark: {}, smoke: {}", fire, wood, spark, smoke);
|
|
|
|
if fire == 0 {
|
|
let elapsed = start.elapsed();
|
|
let fps = frame as f64 / elapsed.as_secs_f64();
|
|
println!("Fire died at frame {}, avg fps: {:.0}", frame, fps);
|
|
break;
|
|
}
|
|
if frame >= 3600 {
|
|
println!("Timeout at 60s");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fn count_mats(grid: &Grid) -> (u32, u32, u32, u32) {
|
|
let mut fire = 0u32;
|
|
let mut wood = 0u32;
|
|
let mut spark = 0u32;
|
|
let mut smoke = 0u32;
|
|
for y in 0..grid.height {
|
|
for x in 0..grid.width {
|
|
match grid.get(x, y) {
|
|
5 => wood += 1,
|
|
9 => fire += 1,
|
|
14 => spark += 1,
|
|
15 => smoke += 1,
|
|
_ => {}
|
|
}
|
|
}
|
|
}
|
|
(fire, wood, spark, smoke)
|
|
}
|
|
|
|
fn temp_range(grid: &Grid) -> (u8, u8) {
|
|
let mut min = 255u8;
|
|
let mut max = 0u8;
|
|
for y in 0..grid.height {
|
|
for x in 0..grid.width {
|
|
let idx = grid.index(x, y);
|
|
let t = grid.temps[idx];
|
|
if t > 0 {
|
|
min = min.min(t);
|
|
max = max.max(t);
|
|
}
|
|
}
|
|
}
|
|
if min == 255 { min = 0; }
|
|
(min, max)
|
|
}
|
|
|
|
fn print_grid(grid: &Grid) {
|
|
for y in 0..grid.height {
|
|
for x in 0..grid.width {
|
|
let c = match grid.get(x, y) {
|
|
5 => 'W',
|
|
9 => 'F',
|
|
14 => '*',
|
|
15 => '%',
|
|
0 => '.',
|
|
1 => '#',
|
|
4 => '~',
|
|
6 => 'L',
|
|
8 => '\'',
|
|
_ => '?',
|
|
};
|
|
print!("{}", c);
|
|
}
|
|
println!();
|
|
}
|
|
}
|