aboutsummaryrefslogtreecommitdiff
path: root/src/sandbox.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sandbox.cpp')
-rw-r--r--src/sandbox.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/sandbox.cpp b/src/sandbox.cpp
new file mode 100644
index 0000000..f71be9b
--- /dev/null
+++ b/src/sandbox.cpp
@@ -0,0 +1,89 @@
+#include "sandbox.hpp"
+#include "common.hpp"
+
+#include <utility>
+
+// 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<uint32_t> Sandbox::to_bitmap() const {
+// // TODO
+// }