1
0
mirror of https://github.com/p2r3/bareiron.git synced 2025-10-01 23:25:09 +02:00

initial code dump

This commit is contained in:
p2r3
2025-08-12 03:51:57 +03:00
parent 94b568d2ac
commit 269e8346eb
17 changed files with 5134 additions and 0 deletions

159
src/worldgen.c Normal file
View File

@@ -0,0 +1,159 @@
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "globals.h"
#include "tools.h"
#include "registries.h"
uint32_t getHash (const void *data, size_t len) {
const uint8_t *bytes = data;
uint32_t hash = 2166136261u;
for (size_t i = 0; i < len; i ++) {
hash ^= bytes[i];
hash *= 16777619u;
}
return hash;
}
int sapling (short x, short y, short z) {
uint8_t buf[10];
memcpy(buf, &x, 2);
memcpy(buf + 2, &y, 2);
memcpy(buf + 4, &z, 2);
memcpy(buf + 6, &world_seed, 4);
if (getHash(buf, sizeof(buf)) % 20 == 0) return B_oak_sapling;
return B_air;
}
uint32_t getChunkHash (short x, short z) {
uint8_t buf[8];
memcpy(buf, &x, 2);
memcpy(buf + 2, &z, 2);
memcpy(buf + 4, &world_seed, 4);
return getHash(buf, sizeof(buf));
}
int getCornerHeight (uint32_t hash) {
int height = 60 + hash % 8 + (hash >> 8) % 5;
if (height < 64) height -= (hash >> 16) % 5;
return height;
}
#define chunk_size 8
int interpolate (int a, int b, int c, int d, int x, int z) {
int top = a * (chunk_size - x) + b * x;
int bottom = c * (chunk_size - x) + d * x;
return (top * (chunk_size - z) + bottom * z) / (chunk_size * chunk_size);
}
int getHeightAt (int x, int z, uint32_t chunk_hash) {
int _x = x / chunk_size;
int _z = z / chunk_size;
int rx = x % chunk_size;
int rz = z % chunk_size;
if (rx < 0) { rx += chunk_size; _x -= 1; }
if (rz < 0) { rz += chunk_size; _z -= 1; }
if (rx == 0 && rz == 0) {
int height = getCornerHeight(chunk_hash);
if (height > 67) return height - 1;
} else {
return interpolate(
getCornerHeight(chunk_hash),
getCornerHeight(getChunkHash(_x + 1, _z)),
getCornerHeight(getChunkHash(_x, _z + 1)),
getCornerHeight(getChunkHash(_x + 1, _z + 1)),
rx, rz
);
}
}
uint8_t getBlockAt (int x, int y, int z) {
uint8_t block_change = getBlockChange(x, y, z);
if (block_change != 0xFF) return block_change;
if (y > 80) return B_air;
int _x = x / chunk_size;
int _z = z / chunk_size;
int rx = x % chunk_size;
int rz = z % chunk_size;
int height;
// make remainders positive and move the cell index when negative
if (rx < 0) { rx += chunk_size; _x -= 1; }
if (rz < 0) { rz += chunk_size; _z -= 1; }
uint32_t chunk_hash = getChunkHash(_x, _z);
if (rx == 0 && rz == 0) {
height = getCornerHeight(chunk_hash);
if (height > 67) height -= 1;
} else {
height = interpolate(
getCornerHeight(chunk_hash),
getCornerHeight(getChunkHash(_x + 1, _z)),
getCornerHeight(getChunkHash(_x, _z + 1)),
getCornerHeight(getChunkHash(_x + 1, _z + 1)),
rx, rz
);
}
if (y >= 64 && y > height) {
uint8_t tree_position = chunk_hash % (chunk_size * chunk_size);
short tree_x = tree_position % chunk_size;
if (tree_x < 3 || tree_x > chunk_size - 3) goto skip_tree;
tree_x += _x * chunk_size;
short tree_z = tree_position / chunk_size;
if (tree_z < 3 || tree_z > chunk_size - 3) goto skip_tree;
tree_z += _z * chunk_size;
uint8_t tree_y = getHeightAt(tree_x, tree_z, chunk_hash) + 1;
if (tree_y < 64) goto skip_tree;
if (x == tree_x && z == tree_z && y >= tree_y && y < tree_y + 6)
return B_oak_log;
uint8_t dx = x > tree_x ? x - tree_x : tree_x - x;
uint8_t dz = z > tree_z ? z - tree_z : tree_z - z;
if (dx < 3 && dz < 3 && y > tree_y + 2 && y < tree_y + 5) {
if (y == tree_y + 4 && dx == 2 && dz == 2 && (chunk_hash >> (x + z + y)) & 1) return B_air;
return B_oak_leaves;
}
if (dx < 2 && dz < 2 && y >= tree_y + 5 && y <= tree_y + 6) {
if (y == tree_y + 6 && dx == 1 && dz == 1 && (chunk_hash >> (x + z + y)) & 1) return B_air;
return B_oak_leaves;
}
}
skip_tree:
if (y >= 63 && y == height) return B_grass_block;
if (y < height - 3) return B_stone;
if (y <= height) return B_dirt;
if (y < 64) return B_water;
return B_air;
}