Files
wlgol/pattern.c
T
arek 7874a5f7c6 feat: implement keyboard and mouse input, pattern placement, and HiDPI scaling
Add configurable key bindings (TOML), modifier-aware dispatch, mouse-driven
pattern placement with preview and rotation, cell grid storage/rendering,
and fractional/integer HiDPI scaling. Archive the input-and-placement change
and sync its specs to main specs.

Tests: Hashtable, Config, Grid, Pattern (4/4 pass).
2026-11-08 14:46:04 +01:00

68 lines
1.8 KiB
C

#include "pattern.h"
#include <limits.h>
#include <stddef.h>
static const cell_offset_t glider_cells[] = {
{1,0},{2,1},{0,2},{1,2},{2,2}
};
static const cell_offset_t blinker_cells[] = {
{0,0},{1,0},{2,0}
};
static const cell_offset_t block_cells[] = {
{0,0},{1,0},{0,1},{1,1}
};
static const cell_offset_t toad_cells[] = {
{1,0},{2,0},{3,0},{0,1},{1,1},{2,1}
};
static const pattern_t patterns[] = {
{"glider", 5, glider_cells},
{"blinker", 3, blinker_cells},
{"block", 4, block_cells},
{"toad", 6, toad_cells},
};
int pattern_count(void) { return 4; }
const pattern_t *pattern_get(int index) {
if (index < 0 || index >= pattern_count()) return NULL;
return &patterns[index];
}
int pattern_rotated_offsets(int index, int rotation, int *out_dx, int *out_dy) {
const pattern_t *p = pattern_get(index);
if (!p) return 0;
rotation = ((rotation % 4) + 4) % 4;
int minx = INT_MAX, miny = INT_MAX;
int tx[16], ty[16];
for (int i = 0; i < p->count; i++) {
int x = p->cells[i].dx;
int y = p->cells[i].dy;
for (int r = 0; r < rotation; r++) {
int nx = y;
int ny = -x;
x = nx; y = ny;
}
tx[i] = x; ty[i] = y;
if (x < minx) minx = x;
if (y < miny) miny = y;
}
for (int i = 0; i < p->count; i++) {
out_dx[i] = tx[i] - minx;
out_dy[i] = ty[i] - miny;
}
return p->count;
}
void pattern_bounds(int index, int rotation, int *w, int *h) {
int dx[16], dy[16];
int n = pattern_rotated_offsets(index, rotation, dx, dy);
int maxx = 0, maxy = 0;
for (int i = 0; i < n; i++) {
if (dx[i] > maxx) maxx = dx[i];
if (dy[i] > maxy) maxy = dy[i];
}
if (w) *w = maxx + 1;
if (h) *h = maxy + 1;
}