From eef15506347455593d0daf1159eaa1b2c5097802 Mon Sep 17 00:00:00 2001 From: 0undefined Date: Thu, 19 Feb 2026 02:39:46 +0100 Subject: Add chunking --- state_mainstate/src/worldgen.c | 107 +++++++++++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 25 deletions(-) (limited to 'state_mainstate/src/worldgen.c') diff --git a/state_mainstate/src/worldgen.c b/state_mainstate/src/worldgen.c index 0155fc6..6e5b9c1 100644 --- a/state_mainstate/src/worldgen.c +++ b/state_mainstate/src/worldgen.c @@ -1,43 +1,100 @@ #include +#include #include -void gen_terrain(u8 *world, usize height, usize length, usize width) { +// Store the xyz position given an index +static void global_position(ivec3 *pos, usize idx) { + const isize chunk_idx = idx / CHUNK_SIZE; + const isize local_idx = idx % CHUNK_SIZE; + const isize local_x = local_idx % CHUNK_WIDTH; + const isize local_y = local_idx / (CHUNK_LENGTH * CHUNK_WIDTH); + const isize local_z = (local_idx - (CHUNK_LENGTH * CHUNK_WIDTH * local_y)) / CHUNK_WIDTH; + + const isize chunk_x = chunk_idx % WORLD_WIDTH; + const isize chunk_z = chunk_idx / WORLD_WIDTH; + + const isize y = local_y; // height + const isize z = local_z + chunk_z * CHUNK_LENGTH; // length + const isize x = local_x + chunk_x * CHUNK_WIDTH; // width + + *pos[0] = x; + *pos[1] = y; + *pos[2] = z; +} + +// Return the index from xyz position +static usize global_idx(ivec3 pos) { + int x = pos[0]; + int y = pos[1]; + int z = pos[2]; + + usize chunk_x = x / CHUNK_WIDTH; + usize chunk_z = z / CHUNK_LENGTH; + usize chunk_idx = chunk_z * WORLD_WIDTH + chunk_x; + + usize local_x = x % CHUNK_WIDTH; + usize local_y = y; + usize local_z = z % CHUNK_LENGTH; + usize local_idx = local_y * CHUNK_LENGTH * CHUNK_WIDTH + + local_z * CHUNK_WIDTH + + local_x; + + return chunk_idx * CHUNK_SIZE + local_idx; +} + +// Chunks are laid out in worldspace as [c1, ..., cN] +static void gen_chunk(u8 *chunk, usize z, usize x) { + // Flat chunks + for (usize yy = 0; yy < CHUNK_HEIGHT / 4; yy++) { + for (usize zz = 0; zz < CHUNK_LENGTH; zz++) { + for (usize xx = 0; xx < CHUNK_WIDTH; xx++) { + chunk[yy * CHUNK_LENGTH * CHUNK_WIDTH + + zz * CHUNK_WIDTH + + xx] = BLOCK_grass; + } + } + } +} + +void gen_terrain(u8 *world) { if (world == NULL) { - world = calloc(width * length * height, sizeof(u8)); + world = calloc(WORLD_SIZE * CHUNK_SIZE, sizeof(u8)); + } + + for (usize z = 0; z < WORLD_WIDTH; z++) { + for (usize x = 0; x < WORLD_LENGTH; x++) { + gen_chunk(&world[ + z * WORLD_LENGTH * CHUNK_SIZE + + x * CHUNK_SIZE + ], z, x); + } } // y: height // z: depth/length // x: width - // This is pretty cache unfriendly - for (usize y = 0; y < height / 2; y++) { - for (usize z = 0; z < length; z++) { - for (usize x = 0; x < width; x++) { - world[y * width * length - + z * width - + x] = BLOCK_grass; - } - } - } - + // "house" for (usize y = 0; y < 4; y++) { - for (usize z = 0; z < 8; z++) { - for (usize x = 0; x < 8; x++) { - if (z > 0 && z < 7 && x > 0 && x < 7) continue; - world[((height / 2 + 1) + y) * width * length - + (z + (length / 2 - 4)) * width - + (x + (width / 2 - 4))] = BLOCK_rock; + for (usize z = 0; z < 7; z++) { + for (usize x = 0; x < 9; x++) { + if (z > 0 && z < 6 && x > 0 && x < 8) continue; + ivec3 pos = { CHUNK_WIDTH * WORLD_WIDTH / 2 + x - 4 + , ((CHUNK_HEIGHT / 4) + y) + , CHUNK_LENGTH * WORLD_LENGTH / 2 + z - 4 + }; + world[global_idx(pos)] = BLOCK_rock; } } } // Doorway - world[(height / 2 + 1) * width * length - + (length / 2) * width - + (width / 2 - 4)] = BLOCK_none; - world[((height / 2 + 1) + 1) * width * length - + (length / 2) * width - + (width / 2 - 4)] = BLOCK_none; + ivec3 pos = { CHUNK_WIDTH * WORLD_WIDTH / 2 + , (CHUNK_HEIGHT / 4) + , CHUNK_LENGTH * WORLD_LENGTH / 2 + 2 + }; + world[global_idx(pos)] = BLOCK_none; + pos[1]++; + world[global_idx(pos)] = BLOCK_none; } -- cgit v1.3