#include #include #include #include #include #include #include #include #ifdef TRACY_ENABLE #include #endif constexpr uint16_t WIDTH = 64; constexpr uint16_t HEIGHT = 64; constexpr int WINDOW_WIDTH = 1024; constexpr int WINDOW_HEIGHT = 1024; struct color { uint8_t r, g, b; }; int main(int argc, char** argv) { auto tb = sand::type::builder(); auto air = tb.assign(); auto sand1 = tb.assign(); auto sand2 = tb.assign(); auto sand3 = tb.assign(); tb.set_default_conversion(sand1, sand2); tb.set_default_conversion(sand2, sand1); auto rb = tb.build(); rb.add_rule(air, sand2).top([=](auto t) { return t == sand1; }); rb.add_rule(air, sand1).top([=](auto t) { return t == sand2; }); rb.add_rule(sand1, air).bottom([=](auto t) { return t == air; }); rb.add_rule(sand2, air).bottom([=](auto t) { return t == air; }); rb.add_rule(air, sand1) .top_right([=](auto t) { return t == sand2; }) .right([=](auto t) { return t != air; }) .top_left([=](auto t) { return t != sand1; }); rb.add_rule(air, sand2) .top_left([=](auto t) { return t == sand1; }) .left([=](auto t) { return t != air; }) .top_right([=](auto t) { return t != sand2; }); rb.add_rule(air, sand1) .top_right([=](auto t) { return t == sand2; }) .right([=](auto t) { return t != air; }) .left([=](auto t) { return t == air; }) .top([=](auto t) { return t == air; }); rb.add_rule(air, sand2) .top_left([=](auto t) { return t == sand1; }) .left([=](auto t) { return t != air; }) .right([=](auto t) { return t == air; }) .top([=](auto t) { return t == air; }); rb.add_rule(air, sand3) .top_right([=](auto t) { return t == sand2; }) .right([=](auto t) { return t != air; }) .top_left([=](auto t) { return t == sand1; }) .left([=](auto t) { return t != air; }) .top([=](auto t) { return t == air; }); rb.add_rule(sand3, sand1).top([=](auto t) { return t == air; }); rb.add_rule(air, sand1) .bottom([=](auto t) { return t == sand3; }) .top([=](auto t) { return t != sand1 && t != sand2; }); rb.add_rule(air, sand3) .bottom([=](auto t) { return t == sand3; }) .top([=](auto t) { return t == sand1 || t == sand2; }); rb.add_rule(sand1, air) .bottom_right([=](auto t) { return t == air; }) .bottom([=](auto t) { return t != air; }) .right([=](auto t) { return t == air; }); rb.add_rule(sand2, air) .bottom_left([=](auto t) { return t == air; }) .bottom([=](auto t) { return t != air; }) .left([=](auto t) { return t == air; }); rb.add_rule(sand1, sand3).bottom([=](auto t) { return t == sand3; }); rb.add_rule(sand2, sand3).bottom([=](auto t) { return t == sand3; }); rb.add_rule(sand3, sand1) .top([=](auto t) { return t == sand1 || t == sand2; }); auto s = rb.build(WIDTH, HEIGHT, air); const auto& cf = [=](sand::type t) -> color { if (t == air) { return { 0x40, 0x60, 0x80 }; } else if (t == sand1 || t == sand2 || t == sand3) { return { 0xB0, 0x90, 0x50 }; } else { return { 0, 0, 0 }; } }; SDL_Init(SDL_INIT_VIDEO); SDL_Window* window = SDL_CreateWindow("sand test", WINDOW_WIDTH, WINDOW_HEIGHT, 0); SDL_Surface* surface = SDL_CreateSurface(WIDTH, HEIGHT, SDL_PIXELFORMAT_RGB24); int prev_ms = SDL_GetTicks(); float time = 0; bool cont = true; int prev_count = 0; while (cont) { SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type == SDL_EVENT_QUIT) { cont = false; } } int ms = SDL_GetTicks(); float dt = (ms - prev_ms) / 1000.0f; prev_ms = ms; time += dt; float x, y; int state; if (time > 0) { time = 0; s.tick(); int count = 0; for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { if (s.get(i, j) == sand1 || s.get(i, j) == sand2) { count += 1; } else if (s.get(i, j) == sand3) { count += 2; } } } if (count != prev_count) { SDL_Log("%d\n", count); } prev_count = count; } if ((state = SDL_GetMouseState(&x, &y))) { int ix = x * WIDTH / WINDOW_WIDTH; int iy = y * HEIGHT / WINDOW_HEIGHT; if (ix >= 0 && ix < WIDTH && iy >= 0 && iy < HEIGHT) { if (state == SDL_BUTTON_LEFT) { s.set(ix, iy, sand1); } else { s.set(ix, iy, sand3); } } } SDL_LockSurface(surface); for (int i = 0; i < WIDTH; i++) { for (int j = 0; j < HEIGHT; j++) { color c = cf(s.get(i, j)); static_cast(surface->pixels)[3 * (i + j * WIDTH) + 0] = c.r; static_cast(surface->pixels)[3 * (i + j * WIDTH) + 1] = c.g; static_cast(surface->pixels)[3 * (i + j * WIDTH) + 2] = c.b; } } SDL_UnlockSurface(surface); SDL_BlitSurfaceScaled(surface, nullptr, SDL_GetWindowSurface(window), nullptr, SDL_SCALEMODE_NEAREST); SDL_UpdateWindowSurface(window); FrameMark; } SDL_DestroySurface(surface); SDL_DestroyWindow(window); SDL_Quit(); return 0; }