#include "sandbox.hpp" #include "common.hpp" #include // Copied from IM_COL32 #define COL_U32(r, g, b, a) (((uint32_t)(A) << IM_COL32_A_SHIFT) | ((uint32_t)(B) << IM_COL32_B_SHIFT) | ((uint32_t)(G) << IM_COL32_G_SHIFT) | ((uint32_t)(R) << IM_COL32_R_SHIFT)) static constexpr uint32_t MAT_COLOR_LUT[] = { 0xffffff'ff, // AIR 0xababab'ff, // SOLID 0xfffca8'ff, // SAND 0x435bf7'ff, // WATER }; uint32_t Tile::get_color() const { return MAT_COLOR_LUT[std::to_underlying(mat)]; } Sandbox::Sandbox(int w, int h) : _bitmap(w * h) , _a(w * h) // TODO random seed , _pcg() , _solid_tile{ Tile::SOLID } , width{ w } , height{ h } // { } static void simulate_sand_tile(Sandbox& self, int x, int y) { auto& at0 = self.gs(x, y); switch (at0.mat) { case Tile::AIR: break; case Tile::SOLID: break; case Tile::SAND: { auto& below = self.gs(x, y - 1); if (below.mat == Tile::AIR) { below = at0; below.updated = true; at0 = {}; at0.updated = true; } else if (below.mat == Tile::WATER) { Pt neighs[]{ Pt(x - 1, y), Pt(x + 1, y), Pt(x, y + 1), Pt(x, y - 1) }; int max_pressure = 0; for (auto [x1, y1] : neighs) { auto& neigh = self.gs(x1, y1); if (neigh.mat == Tile::WATER) { auto p = neigh.pressure; max_pressure = max_pressure > p ? max_pressure : p; } } } else { // Try going to a side // TODO } } break; case Tile::WATER: { // TODO pressure system } break; } } void Sandbox::simulate_step() { for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { simulate_sand_tile(*this, x, y); } } ++ncycle; } Tile& Sandbox::gs(int x, int y) { if (x < 0 || x >= width || y < 0 || y >= height) return _solid_tile; return _a[y * width + x]; } void Sandbox::set_sand(int x, int y, Tile sand) { _a[y * width + x] = std::move(sand); _bitmap[y * width + x] = sand.get_color(); } // std::vector Sandbox::to_bitmap() const { // // TODO // }