summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaditya Dhruv <[email protected]>2026-01-27 20:10:55 -0600
committerAaditya Dhruv <[email protected]>2026-01-27 20:10:55 -0600
commitde3c9942416382aae0f2f2aac3b67c1e8b4d71f1 (patch)
tree3776e5ba74dd45ee7ce41bb397ec97e187dcc325 /src
parent6aabb8b3ca8284ac2d27af36459393321742d8f5 (diff)
Add support for chunk and world
- Chunk is a array of blocks - World is a array of chunks - Basic chunk plains generation based on simple linear functions - Bunch of functions still not implemented, in design phase
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/chunk.c107
-rw-r--r--src/chunk.h21
-rw-r--r--src/engine.c27
-rw-r--r--src/world.h13
5 files changed, 157 insertions, 12 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7b88ab5..34e23b2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -6,4 +6,5 @@ add_executable(junkcraft
util.c
window.c
engine.c
+ chunk.c
)
diff --git a/src/chunk.c b/src/chunk.c
new file mode 100644
index 0000000..77c2301
--- /dev/null
+++ b/src/chunk.c
@@ -0,0 +1,107 @@
+#include "chunk.h"
+#include "block.h"
+#include "cglm/io.h"
+#include "cglm/util.h"
+#include "cglm/vec2.h"
+#include "cglm/vec3.h"
+#include "world.h"
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+
+#define MIN(x, y) (x < y) ? x : y
+#define MAX(x, y) (x > y) ? x : y
+
+void _chunk_plains_gen(struct chunk* chunk);
+
+int chunk_gen(struct world* world, struct chunk *chunk) {
+ // struct chunk neighbor = {0};
+ // world_get_chunk(world, chunk->coord, &neighbor);
+ _chunk_plains_gen(chunk);
+ // switch (chunk->biome) {
+ // case JUNK_BIOME_PLAINS:
+ // _
+ // break;
+ // default:
+ // break;
+ // }
+ return 0;
+}
+
+float _chunk_plains_get_z(vec2 target, vec3 poi, float m, int base_z) {
+ vec2 unit = { (target[0] - poi[0]), (target[1] - poi[1]) };
+ glm_vec2_normalize(unit);
+ // Line direction vector
+ vec3 r = { unit[0], unit[1], m };
+ // r*t + poi = { x, y, z }, solve first for t, then get z
+ float t = 0;
+ // Parallel to X-axis
+ if (r[0] == 0.0f && r[1] != 0.0f) {
+ t = (target[1] - poi[1]) / r[1];
+ }
+ // Parallel to Y-axis
+ else if (r[1] == 0.0f && r[0] != 0.0f) {
+ t = (target[0] - poi[0]) / r[0];
+ }
+ else if (r[0] != 0.0f && r[1] != 0.0f) {
+ // Non-parallel line, either X or y works
+ t = (target[0] - poi[0]) / r[0];
+ }
+ else {
+ //Else we are POI itself, no need to do anything. t will be zero and
+ //the value of z == poi[2]. We subtract -1 from base_z because
+ //otherwise the POI will be a single block at it's z, all others will
+ //always be strictly less than it. This levels the plains
+ base_z -= 1;
+ }
+ float z_off = poi[2] + t * r[2];
+
+ return MAX(base_z, base_z + z_off);
+}
+
+/**
+ * Basic Plains chunk generation
+ * Algorithm: Pick 2 points of interest (POI). These points will either be elevations or depressions.
+ * Each block will get a invisible "offset" value based on their distance from the chosen point.
+ * Chosen point height itself will range from some non zero value to another, plus in negative.
+ * The offset value determines how block heights are created
+ *
+ */
+void _chunk_plains_gen(struct chunk* chunk) {
+ // ============ KNOBS ============
+ // Minimum ground
+ int z = 2;
+ // Min POI block height
+ int poi_min = 3;
+ // Max POI block height
+ int poi_max = 5;
+ // Descent/Ascent rate
+ float m = -.5;
+ memset(chunk->blocks, 0, CHUNK_HEIGHT * CHUNK_LENGTH * CHUNK_WIDTH * sizeof(struct block*));
+ // X, Y, POI Height
+ vec3 poi1 = { rand() % CHUNK_WIDTH, rand() % CHUNK_LENGTH, poi_min + (rand() % (poi_max - poi_min))};
+ vec3 poi2 = { rand() % CHUNK_WIDTH, rand() % CHUNK_LENGTH, -poi_min + (rand() % (poi_max - poi_min))};
+
+ for (int x = 0; x < CHUNK_LENGTH; x++) {
+ for (int y = 0; y < CHUNK_WIDTH; y++) {
+ // Minimum z height
+ // Interpolation formula - simple linear
+ vec2 target = { x, y };
+ float z1 = _chunk_plains_get_z(target, poi1, m, z);
+ float z2 = _chunk_plains_get_z(target, poi2, -m, z);
+ int z_final = (z1 + z2) / 2;
+ for (int h = 0; h < z_final; h++) {
+ struct block* blk = malloc(sizeof(struct block));
+ vec3 pos = {x, h, -y - 1};
+ block_init(pos, blk);
+ chunk->blocks[x][y][h] = blk;
+ }
+ }
+ }
+ fprintf(stderr, "POI Coords\n");
+ glm_vec3_print(poi1, stderr);
+ glm_vec3_print(poi2, stderr);
+}
diff --git a/src/chunk.h b/src/chunk.h
new file mode 100644
index 0000000..87c33fa
--- /dev/null
+++ b/src/chunk.h
@@ -0,0 +1,21 @@
+#pragma once
+#include "block.h"
+#include "world.h"
+#include "junk/vector.h"
+#include <stdint.h>
+enum biome {
+ JUNK_BIOME_PLAINS,
+};
+#define CHUNK_WIDTH 16
+#define CHUNK_LENGTH 16
+#define CHUNK_HEIGHT 128
+
+struct chunk {
+ struct block* blocks[CHUNK_WIDTH][CHUNK_LENGTH][CHUNK_HEIGHT];
+ enum biome biome;
+ vec2 coord;
+};
+
+int chunk_gen(struct world* world, struct chunk* chunk);
+int chunk_gen_structures(void* neighbor_data, struct chunk* chunk);
+int chunk_gen_terrain(void* neighbor_data, struct chunk* chunk);
diff --git a/src/engine.c b/src/engine.c
index ec1fdcd..d8df9b3 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -1,5 +1,6 @@
#include "engine.h"
#include "block.h"
+#include "chunk.h"
#include "window.h"
#include <junk/vector.h>
@@ -25,20 +26,22 @@ int engine_init(struct engine *engine) {
// Setup Objects to draw
vector_init(&engine->objects);
+ // Setup root chunk
+ struct chunk* chunk = malloc(sizeof(struct chunk));
+ chunk_gen(NULL, chunk);
- for (int i = 0; i < 3; i++) {
- for (int j = 0; j < 3; j++) {
- fprintf(stderr, "Creating block %d\n", i + j);
- struct block* blk = malloc(sizeof(struct block));
- memset(blk, 0, sizeof(struct block));
- vec3 pos = { 0.5f * ((float)i - 1), 0.5f * ((float)j - 1), 0.0f};
- if (block_init(pos, blk) != 0) {
- //TODO: Fix frees here
- return -1;
+ int counter = 0;
+ for (int i = 0; i < CHUNK_WIDTH; i++) {
+ for (int j = 0; j < CHUNK_LENGTH; j++) {
+ for (int k = 0; k < CHUNK_HEIGHT; k++) {
+ struct block* blk = chunk->blocks[i][j][k];
+ if (blk == NULL) {
+ continue;
+ }
+ if (VECTOR_INSERT(engine->objects, (void*)blk) == -1) exit(1);
+ // block_debug(blk);
+ counter += 1;
}
- fprintf(stderr, "Inserting block %d\n", i + j);
- if (VECTOR_INSERT(engine->objects, (void*)blk) == -1) exit(1);
- fprintf(stderr, "Done block %d\n", i + j);
}
}
diff --git a/src/world.h b/src/world.h
new file mode 100644
index 0000000..5be1cf2
--- /dev/null
+++ b/src/world.h
@@ -0,0 +1,13 @@
+#pragma once
+#include "chunk.h"
+#include <stdint.h>
+#define WORLD_LENGTH 32
+#define WORLD_WIDTH 32
+struct world {
+ struct chunk* chunks[WORLD_WIDTH][WORLD_LENGTH];
+ int32_t seed;
+};
+
+int world_init(int32_t seed);
+int world_save(int32_t seed);
+int world_get_chunk(struct world* world, vec2 coord, struct chunk* chunk);