#include "ui.hpp" #include "ogl.hpp" #include "sandbox.hpp" #include #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 }); } } } struct ImRect { ImVec2 top_left; ImVec2 bottom_right; }; struct SandboxCfg { int width = 40, height = 100; float tile_size = 4.0f; ImVec2 tr_sandbox2screen(ImVec2 origin, Pt pt) const { return ImVec2(origin.x + tile_size * pt.x, origin.y - tile_size * pt.y); } // Assuming inclusive-inclusive rectangle ImRect tr_sandbox2screen(ImVec2 origin, Rect r) const { return { ImVec2(origin.x + tile_size * r.bl.x, origin.y - tile_size * (r.tr.y + 1)), ImVec2(origin.x + tile_size * (r.tr.x + 1), origin.y - tile_size * r.bl.y), }; } std::unique_ptr make_sandbox() const { return std::make_unique(width, height); } }; void ShowEverything() { ImGui::Begin("Sandbox"); static SandboxCfg cfg; static std::unique_ptr sandbox = cfg.make_sandbox(); 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(); } // TODO popup for changing these params? // TODO migrate existing content ImGui::InputInt("Sandbox width", &cfg.width); ImGui::InputInt("Sandbox height", &cfg.height); if (ImGui::Button("Recreate")) { sandbox = cfg.make_sandbox(); } ImGui::SameLine(); if (ImGui::Button("Add sand")) { AddSand(*sandbox); } ImVec2 img_size(cfg.tile_size * sandbox->width, cfg.tile_size * sandbox->height); auto img_topleft = ImGui::GetCursorScreenPos(); gl.upload(reinterpret_cast(sandbox->bitmap), sandbox->width, sandbox->height); ImGui::Image(gl.as_imgui(), img_size, ImVec2(0, 1), ImVec2(1, 0)); // bottom-left corner of the sandbox, in screen space auto origin = img_topleft; origin.y += img_size.y; if (show_dirty_rect) { auto dl = ImGui::GetWindowDrawList(); auto [top_left, bottom_right] = cfg.tr_sandbox2screen(origin, sandbox->dirty_writeto); dl->AddRect(top_left, bottom_right, IM_COL32(255, 0, 0, 255)); } ImGui::End(); ImGui::ShowDemoWindow(); }