#include "ui.hpp" #include "ogl.hpp" #include "sandbox.hpp" #include static void AddSand(Sandbox& sb) { for (int y = 80; y <= 90; ++y) { for (int x = 10; x <= 13; ++x) { sb.set_sand(x, y, Tile{ .so = Tile::SAND }); } } } constexpr int kWidth = 40; constexpr int kHeight = 100; constexpr float kScale = 4.0f; constexpr ImVec2 kSize(kWidth* kScale, kHeight* kScale); static ImVec2 TrSandbox2Screen(ImVec2 origin, Pt pt) { return ImVec2(origin.x + kScale * pt.x, origin.y - kScale * pt.y); } struct ImRect { ImVec2 top_left; ImVec2 bottom_right; }; // Assuming inclusive-inclusive rectangle static ImRect TrSandbox2Screen(ImVec2 origin, Rect r) { return { ImVec2(origin.x + kScale * r.bl.x, origin.y - kScale * (r.tr.y+1)), ImVec2(origin.x + kScale * (r.tr.x + 1), origin.y - kScale * r.bl.y), }; } void ShowEverything() { ImGui::Begin("Sandbox"); static Sandbox sandbox(40, 100); static OglImage gl; static bool running = false; ImGui::Checkbox("Run", &running); static bool show_dirty_rect = true; ImGui::Checkbox("Show dirty rects", &show_dirty_rect); ImGui::Text("ncycle = %d", sandbox.ncycle); ImGui::SameLine(); bool step = ImGui::Button("Step"); if (step || running) { sandbox.simulate_step(); gl.upload(reinterpret_cast(sandbox.bitmap), kWidth, kHeight); } // TODO this makes things very wrong (no proper assignment operator) // if (ImGui::Button("Reset sandbox")) { // sandbox = Sandbox(40, 100); // } // ImGui::SameLine(); if (ImGui::Button("Add sand")) { AddSand(sandbox); } auto sandbox_topleft = ImGui::GetCursorScreenPos(); ImGui::Image(gl.as_imgui(), kSize, ImVec2(0, 1), ImVec2(1, 0)); // bottom-left corner of the sandbox, in screen space auto origin = sandbox_topleft; origin.y += kSize.y; if (show_dirty_rect) { auto dl = ImGui::GetWindowDrawList(); auto [top_left, bottom_right] = TrSandbox2Screen(origin, sandbox.dirty_writeto); dl->AddRect(top_left, bottom_right, IM_COL32(255, 0, 0, 255)); } ImGui::End(); ImGui::ShowDemoWindow(); }