175 lines
No EOL
3.8 KiB
C
175 lines
No EOL
3.8 KiB
C
#include "gen.h"
|
|
#include "cubes.h"
|
|
#include "noise.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
struct chunk *chunks = NULL;
|
|
int lastI = 0;
|
|
int prevExists = 0;
|
|
|
|
void gen_save(struct chunk chunk) {
|
|
char fname[1024];
|
|
snprintf(fname, 1023, "./db/chunk_%i_%i_%i.dat", chunk.x, chunk.y, chunk.z);
|
|
if (chunk.exists == 0)
|
|
return;
|
|
|
|
FILE *fp = fopen(fname, "wb");
|
|
if (!fp) {
|
|
return;
|
|
}
|
|
|
|
fwrite(&chunk, sizeof(struct chunk), 1, fp);
|
|
fclose(fp);
|
|
|
|
return;
|
|
}
|
|
|
|
struct chunk gen_find(int x, int y, int z) {
|
|
struct chunk chunk;
|
|
for (int j = 0; j < CBUF_ALL; j++) {
|
|
int i = j;
|
|
chunk = chunks[i];
|
|
if ((chunk).x == x && (chunk).y == y && (chunk).z == z &&
|
|
(chunk).exists != 0) {
|
|
return chunk;
|
|
}
|
|
}
|
|
chunk = (gen_chunk(x, y, z, 0, 0));
|
|
return chunk;
|
|
}
|
|
|
|
struct chunk gen_chunk(int x, int y, int z, int ci, int h) {
|
|
|
|
struct chunk *chunks2 = chunks; // &chunks[CBUF_ALL * ci];
|
|
|
|
struct chunk chunk;
|
|
|
|
if (x < 0 || y < 0 || z < 0) {
|
|
chunk.exists = 0;
|
|
return chunk;
|
|
}
|
|
|
|
int cbuf2 = CHUNK_ALL; // CBUF_ALL * (CHUNK_DIAMETER_H + (MAX_R * 2));
|
|
|
|
int i, j;
|
|
int r = (h == 0);
|
|
|
|
h = h * 16;
|
|
|
|
for (j = 0; j < (r ? 16 : 1) && h; j++) {
|
|
i = (j + h + cbuf2) % cbuf2;
|
|
chunk = chunks2[i];
|
|
if (chunk.x == x && chunk.y == y && chunk.z == z && chunk.exists != 0) {
|
|
|
|
chunk.exists = i / 16;
|
|
if (chunk.exists == 0)
|
|
chunk.exists = 1;
|
|
return chunk;
|
|
}
|
|
}
|
|
|
|
// printf("fail\n");
|
|
for (j = 0; j < cbuf2; j += 16) {
|
|
i = (j + h + cbuf2) % cbuf2;
|
|
chunk = chunks2[i];
|
|
if (chunk.exists == 0) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (chunk.exists == 1 && chunk.x != x && chunk.y != y && chunk.z != z) {
|
|
//gen_save(chunk);
|
|
}
|
|
|
|
char fname[1024];
|
|
snprintf(fname, 1023, "./db/chunk_%i_%i_%i.dat", x, y, z);
|
|
|
|
FILE *fp = fopen(fname, "rb+");
|
|
|
|
int code = (fp) ? fread(&chunk, sizeof(struct chunk), 1, fp) : 0;
|
|
if (code != 0) {
|
|
fclose(fp);
|
|
fp = 0;
|
|
if (chunk.exists != 0) {
|
|
chunk.exists = i / 16;
|
|
if (chunk.exists == 0)
|
|
chunk.exists = 1;
|
|
return chunk;
|
|
}
|
|
} else if (fp) {
|
|
fclose(fp);
|
|
}
|
|
|
|
lastI = i;
|
|
|
|
chunk.exists = i / 16;
|
|
if (chunk.exists == 0)
|
|
chunk.exists = 1;
|
|
chunk.x = x;
|
|
chunk.y = y;
|
|
chunk.z = z;
|
|
|
|
int c = 0;
|
|
|
|
chunk = noise_chunk(chunk, x, y, z);
|
|
|
|
chunks2[i] = chunk;
|
|
|
|
gen_save(chunk);
|
|
|
|
return chunk;
|
|
}
|
|
|
|
void gen_init() {
|
|
if (chunks == NULL) {
|
|
chunks = calloc(CHUNK_ALL, sizeof(struct chunk));
|
|
}
|
|
}
|
|
|
|
void gen_free() {
|
|
for (int i = 0; i < CHUNK_ALL; i++) {
|
|
gen_save(chunks[i]);
|
|
}
|
|
free(chunks);
|
|
}
|
|
|
|
int gen_cube(int x, int y, int z, struct chunk dat, int ci, int val) {
|
|
if (x < 0 || y < 0 || z < 0)
|
|
return 0;
|
|
|
|
if (val != -1) {
|
|
dat = gen_find((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), (z / CHUNK_LENGTH));
|
|
} else if (dat.exists == 0 || dat.x != (x / CHUNK_LENGTH) ||
|
|
dat.y != (y / CHUNK_LENGTH) || dat.z != (z / CHUNK_LENGTH)) {
|
|
dat = gen_chunk((x / CHUNK_LENGTH), (y / CHUNK_LENGTH), (z / CHUNK_LENGTH),
|
|
ci, dat.exists);
|
|
prevExists = dat.exists;
|
|
}
|
|
|
|
int *h = &dat.blocks[(y % CHUNK_LENGTH) + (z % CHUNK_LENGTH) * CHUNK_LENGTH +
|
|
(x % CHUNK_LENGTH) * CHUNK_LENGTH * CHUNK_LENGTH];
|
|
|
|
if (val != -1) {
|
|
*h = val;
|
|
|
|
cubes_refresh(x / CHUNK_LENGTH, y / CHUNK_LENGTH, z / CHUNK_LENGTH, dat, 0);
|
|
for (int a = x - 1; a <= x + 1; a++) {
|
|
for (int b = y - 1; b <= y + 1; b++) {
|
|
for (int c = z - 1; c <= z + 1; c++) {
|
|
if (a / CHUNK_LENGTH == x / CHUNK_LENGTH &&
|
|
b / CHUNK_LENGTH == y / CHUNK_LENGTH &&
|
|
c / CHUNK_LENGTH == z / CHUNK_LENGTH)
|
|
continue;
|
|
printf("%i %i %i\n",a,b,c);
|
|
|
|
cubes_refresh(a / CHUNK_LENGTH, b / CHUNK_LENGTH, c / CHUNK_LENGTH,
|
|
dat, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return *h;
|
|
} |