210 lines
5.3 KiB
C++
210 lines
5.3 KiB
C++
#include <SDL3/SDL.h>
|
|
#include <SDL3/SDL_events.h>
|
|
#include <SDL3/SDL_mouse.h>
|
|
#include <SDL3/SDL_oldnames.h>
|
|
#include <SDL3/SDL_surface.h>
|
|
#include <SDL3/SDL_timer.h>
|
|
#include <SDL3/SDL_video.h>
|
|
#include <sand/sand.h>
|
|
|
|
#ifdef TRACY_ENABLE
|
|
#include <tracy/Tracy.hpp>
|
|
#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<uint8_t*>(surface->pixels)[3 * (i + j * WIDTH) + 0] = c.r;
|
|
static_cast<uint8_t*>(surface->pixels)[3 * (i + j * WIDTH) + 1] = c.g;
|
|
static_cast<uint8_t*>(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;
|
|
}
|