summaryrefslogtreecommitdiff
path: root/src/chunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/chunk.c')
-rw-r--r--src/chunk.c66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/chunk.c b/src/chunk.c
new file mode 100644
index 0000000..3212194
--- /dev/null
+++ b/src/chunk.c
@@ -0,0 +1,66 @@
+// SPDX-FileCopyrightText: 2024 Lizzy Fleckenstein <lizzy@vlhl.dev>
+//
+// SPDX-License-Identifier: AGPL-3.0-or-later
+
+#include <stdlib.h>
+#include <string.h>
+#include "chunk.h"
+
+node *chunk_col(chunk c, uint32_t x)
+{
+ return &c.data[c.pitch*x];
+}
+
+node *chunk_index(chunk c, uvec2 v)
+{
+ return &chunk_col(c, v.x)[v.y];
+}
+
+node *chunk_index_abs(chunk c, vec2 v)
+{
+ if (box2_contains(c.bounds, v))
+ return chunk_index(c, CUVEC2(vec2_sub(v, c.bounds.pos)));
+ else
+ return NULL;
+}
+
+chunk chunk_sub(chunk c, box2 area)
+{
+ return (chunk) {
+ .pitch = c.pitch,
+ .bounds = area,
+ .data = chunk_index(c, CUVEC2(vec2_sub(area.pos, c.bounds.pos))),
+ };
+}
+
+chunk chunk_alloc(box2 b)
+{
+ return (chunk) {
+ .pitch = b.size.y,
+ .bounds = b,
+ .data = calloc(b.size.x * b.size.y, sizeof(node)),
+ };
+}
+
+void chunk_copy(chunk dst, chunk src)
+{
+ box2 area = box2_overlap(dst.bounds, src.bounds);
+ if (box2_empty(area))
+ return;
+
+ chunk d = chunk_sub(dst, area);
+ chunk s = chunk_sub(src, area);
+
+ if (d.pitch == area.size.y && s.pitch == area.size.y)
+ memcpy(d.data, s.data, area.size.x * area.size.y * sizeof(node));
+ else for (uint32_t x = 0; x < area.size.x; x++)
+ memcpy(chunk_col(d, x), chunk_col(s, x), area.size.y * sizeof(node));
+}
+
+void chunk_clear(chunk c)
+{
+ if (c.bounds.size.y == c.pitch)
+ memset(c.data, 0, c.bounds.size.x * c.bounds.size.y * sizeof(node));
+ else for (uint32_t x = 0; x < c.bounds.size.x; x++)
+ memset(chunk_col(c, x), 0, c.bounds.size.y * sizeof(node));
+}