/* main.c * Created: 2023-08-25 * Author: Aryadev Chavali * Description: Entry point of program */ #include #include #include #include #include #include #include #include "./lib.h" void step(state_t *state) { state->data[((state->dwidth / 2) * state->dwidth) + (state->dwidth / 2)]++; for (size_t i = 0; i < state->dwidth; ++i) for (size_t j = 0; j < state->dwidth; ++j) if (state->data[(i * state->dwidth) + j] >= 4) { unsigned char *references[] = { (j == 0) ? NULL : &state->data[((i)*state->dwidth) + j - 1], (i == state->dwidth - 1) ? NULL : &state->data[((i + 1) * state->dwidth) + j], (j == state->dwidth - 1) ? NULL : &state->data[(i * state->dwidth) + j + 1], (i == 0) ? NULL : &state->data[((i - 1) * state->dwidth) + j]}; for (size_t k = 0; k < 4; ++k) if (references[k]) *references[k] += 1; state->data[(i * state->dwidth) + j] = 0; } } void *compute_thread(void *input) { state_t *state = input; while (state->thread_alive) step(state); return NULL; } int main(void) { state_t state = {NULL, 512, 512, 0, true}; state.data = calloc(state.dwidth * state.dwidth, sizeof(*state.data)); state.multiplier = state.window_len / state.dwidth; const float zoom = 0.125f; Camera2D camera = {0}; camera.zoom = 1.0f; pthread_t step_thread; pthread_create(&step_thread, NULL, &compute_thread, &state); InitWindow(state.window_len, state.window_len, "Abelian sand pile"); SetTargetFPS(60); while (!WindowShouldClose()) { if (IsKeyPressed(KEY_UP) || IsKeyDown(KEY_UP)) { Vector2 centre = {state.window_len / 2, state.window_len / 2}; Vector2 world_pos = GetScreenToWorld2D(centre, camera); camera.offset = centre; camera.target = world_pos; camera.zoom += zoom; if (camera.zoom < zoom) camera.zoom = zoom; } if (IsKeyPressed(KEY_DOWN) || IsKeyDown(KEY_DOWN)) { Vector2 centre = {state.window_len / 2, state.window_len / 2}; Vector2 world_pos = GetScreenToWorld2D(centre, camera); camera.offset = centre; camera.target = world_pos; camera.zoom -= zoom; if (camera.zoom < zoom) camera.zoom = zoom; } if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) { Vector2 delta = Vector2Scale(GetMouseDelta(), -1.0f / camera.zoom); camera.target = Vector2Add(camera.target, delta); } BeginDrawing(); ClearBackground(BLACK); BeginMode2D(camera); for (size_t i = 0; i < state.dwidth; ++i) for (size_t j = 0; j < state.dwidth; ++j) { Color c = {0}; unsigned char sandpile = state.data[(i * state.dwidth) + j]; if (sandpile == 0) c = BLACK; else if (sandpile == 1) c = GREEN; else if (sandpile == 2) c = PURPLE; else if (sandpile == 3) c = YELLOW; DrawRectangle(i * state.multiplier, j * state.multiplier, state.multiplier, state.multiplier, c); } EndMode2D(); EndDrawing(); } if (state.thread_alive) pthread_cancel(step_thread); CloseWindow(); return 0; }