1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#include "ui.hpp"
#include "ogl.hpp"
#include "sandbox.hpp"
#include <imgui.h>
#include <memory>
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<Sandbox> make_sandbox() const {
return std::make_unique<Sandbox>(width, height);
}
};
void ShowEverything() {
ImGui::Begin("Sandbox");
static SandboxCfg cfg;
static std::unique_ptr<Sandbox> 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<const char*>(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();
}
|