mirror of
https://github.com/xtreme8000/CavEX.git
synced 2025-01-22 09:11:55 -05:00
WIP mc beta world save loading
This commit is contained in:
parent
c8f3f33c22
commit
e18f31cdcf
6 changed files with 272 additions and 137 deletions
|
@ -238,7 +238,7 @@ static void chunk_mesher_rebuild(struct block_data* bd, w_coord_t cx,
|
|||
w_coord_t cy, w_coord_t cz,
|
||||
struct displaylist* d, uint8_t* light_data,
|
||||
bool count_only, size_t* vertices) {
|
||||
assert(bd && d && light_data && vertices);
|
||||
assert(bd && d && vertices);
|
||||
|
||||
for(int k = 0; k < 13; k++)
|
||||
vertices[k] = 0;
|
||||
|
@ -426,19 +426,14 @@ static void chunk_mesher_rebuild(struct block_data* bd, w_coord_t cx,
|
|||
}
|
||||
|
||||
static void chunk_mesher_build(struct chunk_mesher_rpc* req) {
|
||||
uint8_t* light_data
|
||||
= malloc((CHUNK_SIZE + 2) * (CHUNK_SIZE + 2) * (CHUNK_SIZE + 2) * 3);
|
||||
assert(light_data);
|
||||
|
||||
chunk_mesher_vertex_light(req->request.blocks, light_data);
|
||||
|
||||
for(int k = 0; k < 13; k++)
|
||||
req->result.has_displist[k] = false;
|
||||
|
||||
size_t vertices[13];
|
||||
chunk_mesher_rebuild(req->request.blocks, req->chunk->x, req->chunk->y,
|
||||
req->chunk->z, req->result.mesh, light_data, true,
|
||||
vertices);
|
||||
req->chunk->z, req->result.mesh, NULL, true, vertices);
|
||||
|
||||
bool has_any_vertices = false;
|
||||
|
||||
for(int k = 0; k < 13; k++) {
|
||||
if(vertices[k] > 0 && vertices[k] <= 0xFFFF * 4) {
|
||||
|
@ -447,14 +442,20 @@ static void chunk_mesher_build(struct chunk_mesher_rpc* req) {
|
|||
displaylist_begin(req->result.mesh + k, GX_QUADS, GX_VTXFMT0,
|
||||
vertices[k]);
|
||||
req->result.has_displist[k] = true;
|
||||
has_any_vertices = true;
|
||||
}
|
||||
}
|
||||
|
||||
chunk_mesher_rebuild(req->request.blocks, req->chunk->x, req->chunk->y,
|
||||
req->chunk->z, req->result.mesh, light_data, false,
|
||||
vertices);
|
||||
|
||||
free(light_data);
|
||||
if(has_any_vertices) {
|
||||
uint8_t* light_data = malloc((CHUNK_SIZE + 2) * (CHUNK_SIZE + 2)
|
||||
* (CHUNK_SIZE + 2) * 3);
|
||||
assert(light_data);
|
||||
chunk_mesher_vertex_light(req->request.blocks, light_data);
|
||||
chunk_mesher_rebuild(req->request.blocks, req->chunk->x, req->chunk->y,
|
||||
req->chunk->z, req->result.mesh, light_data, false,
|
||||
vertices);
|
||||
free(light_data);
|
||||
}
|
||||
|
||||
for(int k = 0; k < 13; k++) {
|
||||
if(req->result.has_displist[k])
|
||||
|
|
|
@ -20,20 +20,25 @@ void clin_chunk(w_coord_t x, w_coord_t y, w_coord_t z, w_coord_t sx,
|
|||
uint8_t* ids_t = ids;
|
||||
uint8_t* metadata_t = metadata;
|
||||
uint8_t* lighting_t = lighting;
|
||||
bool flip = true;
|
||||
|
||||
for(w_coord_t oy = y; oy < y + sy; oy++) {
|
||||
for(w_coord_t ox = x; ox < x + sx; ox++) {
|
||||
for(w_coord_t oz = z; oz < z + sz; oz++) {
|
||||
for(w_coord_t ox = x; ox < x + sx; ox++) {
|
||||
for(w_coord_t oy = y; oy < y + sy; oy++) {
|
||||
uint8_t md = flip ? (*metadata_t) & 0xF : (*metadata_t) >> 4;
|
||||
world_set_block(&gstate.world, ox, oy, oz,
|
||||
(struct block_data) {
|
||||
.type = *ids_t,
|
||||
.metadata = *metadata_t,
|
||||
.metadata = md,
|
||||
.sky_light = (*lighting_t) & 0xF,
|
||||
.torch_light = (*lighting_t) >> 4,
|
||||
});
|
||||
ids_t++;
|
||||
metadata_t++;
|
||||
lighting_t++;
|
||||
|
||||
flip = !flip;
|
||||
if(flip)
|
||||
metadata_t++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
162
source/network/region_archive.c
Normal file
162
source/network/region_archive.c
Normal file
|
@ -0,0 +1,162 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "../cNBT/nbt.h"
|
||||
|
||||
#include "region_archive.h"
|
||||
|
||||
bool region_archive_create(struct region_archive* ra, char* world_name,
|
||||
w_coord_t x, w_coord_t z) {
|
||||
assert(ra && world_name);
|
||||
|
||||
ra->offsets = malloc(sizeof(uint32_t) * REGION_SIZE * REGION_SIZE);
|
||||
|
||||
if(!ra->offsets)
|
||||
return false;
|
||||
|
||||
snprintf(ra->file_name, sizeof(ra->file_name), "%s/region/r.%i.%i.mcr",
|
||||
world_name, x, z); // TODO
|
||||
ra->x = x;
|
||||
ra->z = z;
|
||||
|
||||
FILE* f = fopen(ra->file_name, "rb");
|
||||
|
||||
if(!f) {
|
||||
free(ra->offsets);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!fread(ra->offsets, sizeof(uint32_t) * REGION_SIZE * REGION_SIZE, 1,
|
||||
f)) {
|
||||
free(ra->offsets);
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void region_archive_destroy(struct region_archive* ra) {
|
||||
assert(ra);
|
||||
|
||||
free(ra->offsets);
|
||||
}
|
||||
|
||||
bool region_archive_contains(struct region_archive* ra, w_coord_t x,
|
||||
w_coord_t z) {
|
||||
assert(ra);
|
||||
|
||||
if(CHUNK_REGION_COORD(x) != ra->x || CHUNK_REGION_COORD(z) != ra->z)
|
||||
return false;
|
||||
|
||||
int rx = x & (REGION_SIZE - 1);
|
||||
int rz = z & (REGION_SIZE - 1);
|
||||
|
||||
uint32_t offset = ra->offsets[rx + rz * REGION_SIZE] >> 8;
|
||||
uint32_t sectors = ra->offsets[rx + rz * REGION_SIZE] & 0xFF;
|
||||
|
||||
return offset >= 2 && sectors >= 1;
|
||||
}
|
||||
|
||||
bool region_archive_get_blocks(struct region_archive* ra, w_coord_t x,
|
||||
w_coord_t z, uint8_t** ids, uint8_t** metadata,
|
||||
uint8_t** lighting) {
|
||||
assert(ra && ids && metadata && lighting);
|
||||
assert(region_archive_contains(ra, x, z));
|
||||
|
||||
int rx = x & (REGION_SIZE - 1);
|
||||
int rz = z & (REGION_SIZE - 1);
|
||||
|
||||
uint32_t offset = ra->offsets[rx + rz * REGION_SIZE] >> 8;
|
||||
uint32_t sectors = ra->offsets[rx + rz * REGION_SIZE] & 0xFF;
|
||||
|
||||
// TODO: little endian
|
||||
|
||||
FILE* f = fopen(ra->file_name, "rb");
|
||||
|
||||
if(!f)
|
||||
return false;
|
||||
|
||||
if(fseek(f, offset * REGION_SECTOR_SIZE, SEEK_SET) != 0) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t length;
|
||||
if(!fread(&length, sizeof(uint32_t), 1, f)
|
||||
|| length + sizeof(uint32_t) > sectors * REGION_SECTOR_SIZE) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t type;
|
||||
if(!fread(&type, sizeof(uint8_t), 1, f) || type > 3) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
void* nbt_compressed = malloc(length - 1);
|
||||
|
||||
if(!nbt_compressed) {
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!fread(nbt_compressed, length - 1, 1, f)) {
|
||||
free(nbt_compressed);
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
nbt_node* chunk = nbt_parse_compressed(nbt_compressed, length - 1);
|
||||
|
||||
free(nbt_compressed);
|
||||
fclose(f);
|
||||
|
||||
if(!chunk)
|
||||
return false;
|
||||
|
||||
nbt_node* n_blocks = nbt_find_by_path(chunk, ".Level.Blocks");
|
||||
nbt_node* n_metadata = nbt_find_by_path(chunk, ".Level.Data");
|
||||
nbt_node* n_skyl = nbt_find_by_path(chunk, ".Level.SkyLight");
|
||||
nbt_node* n_torchl = nbt_find_by_path(chunk, ".Level.BlockLight");
|
||||
|
||||
if(!n_blocks || !n_metadata || !n_skyl || !n_torchl
|
||||
|| n_blocks->type != TAG_BYTE_ARRAY || n_metadata->type != TAG_BYTE_ARRAY
|
||||
|| n_skyl->type != TAG_BYTE_ARRAY || n_torchl->type != TAG_BYTE_ARRAY
|
||||
|| n_blocks->payload.tag_byte_array.length
|
||||
!= CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT
|
||||
|| n_metadata->payload.tag_byte_array.length
|
||||
!= CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT / 2
|
||||
|| n_skyl->payload.tag_byte_array.length
|
||||
!= CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT / 2
|
||||
|| n_torchl->payload.tag_byte_array.length
|
||||
!= CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT / 2) {
|
||||
nbt_free(chunk);
|
||||
return false;
|
||||
}
|
||||
|
||||
*ids = malloc(CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
|
||||
*metadata = malloc(CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT / 2);
|
||||
*lighting = malloc(CHUNK_SIZE * CHUNK_SIZE * WORLD_HEIGHT);
|
||||
|
||||
memcpy(*ids, n_blocks->payload.tag_byte_array.data,
|
||||
n_blocks->payload.tag_byte_array.length);
|
||||
|
||||
memcpy(*metadata, n_metadata->payload.tag_byte_array.data,
|
||||
n_metadata->payload.tag_byte_array.length);
|
||||
|
||||
for(size_t k = 0; k < (size_t)n_skyl->payload.tag_byte_array.length * 2;
|
||||
k++) {
|
||||
uint8_t a = (n_torchl->payload.tag_byte_array.data[k / 2] & 0xF0)
|
||||
| (n_skyl->payload.tag_byte_array.data[k / 2] >> 4);
|
||||
uint8_t b = (n_torchl->payload.tag_byte_array.data[k / 2] << 4)
|
||||
| (n_skyl->payload.tag_byte_array.data[k / 2] & 0xF);
|
||||
(*lighting)[k] = (k & 1) ? a : b;
|
||||
}
|
||||
|
||||
nbt_free(chunk);
|
||||
|
||||
return true;
|
||||
}
|
30
source/network/region_archive.h
Normal file
30
source/network/region_archive.h
Normal file
|
@ -0,0 +1,30 @@
|
|||
#ifndef REGION_ARCHIVE_H
|
||||
#define REGION_ARCHIVE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../world.h"
|
||||
|
||||
struct region_archive {
|
||||
w_coord_t x, z;
|
||||
uint32_t* offsets;
|
||||
char file_name[64];
|
||||
};
|
||||
|
||||
#define REGION_SIZE 32
|
||||
#define REGION_SIZE_BITS 5
|
||||
#define REGION_SECTOR_SIZE 4096
|
||||
|
||||
#define CHUNK_REGION_COORD(x) ((w_coord_t)floor(x / (float)REGION_SIZE))
|
||||
|
||||
bool region_archive_create(struct region_archive* ra, char* world_name,
|
||||
w_coord_t x, w_coord_t z);
|
||||
void region_archive_destroy(struct region_archive* ra);
|
||||
bool region_archive_contains(struct region_archive* ra, w_coord_t x,
|
||||
w_coord_t z);
|
||||
bool region_archive_get_blocks(struct region_archive* ra, w_coord_t x,
|
||||
w_coord_t z, uint8_t** ids, uint8_t** metadata,
|
||||
uint8_t** lighting);
|
||||
|
||||
#endif
|
|
@ -9,103 +9,37 @@
|
|||
#define CHUNK_DIST2(x1, x2, z1, z2) \
|
||||
(((x1) - (x2)) * ((x1) - (x2)) + ((z1) - (z2)) * ((z1) - (z2)))
|
||||
|
||||
static const char* chunk_files[] = {
|
||||
"x0 z-10.vc", "x-1 z-2.vc", "x-3 z-5.vc", "x-5 z-8.vc", "x-8 z-11.vc",
|
||||
"x0 z-11.vc", "x-1 z-3.vc", "x-3 z-6.vc", "x-5 z-9.vc", "x-8 z-1.vc",
|
||||
"x0 z-1.vc", "x-1 z-4.vc", "x-3 z-7.vc", "x-6 z-10.vc", "x-8 z-2.vc",
|
||||
"x0 z-2.vc", "x-1 z-5.vc", "x-3 z-8.vc", "x-6 z-11.vc", "x-8 z-3.vc",
|
||||
"x0 z-3.vc", "x-1 z-6.vc", "x-3 z-9.vc", "x-6 z-1.vc", "x-8 z-4.vc",
|
||||
"x0 z-4.vc", "x-1 z-7.vc", "x-4 z-10.vc", "x-6 z-2.vc", "x-8 z-5.vc",
|
||||
"x0 z-5.vc", "x-1 z-8.vc", "x-4 z-11.vc", "x-6 z-3.vc", "x-8 z-6.vc",
|
||||
"x0 z-6.vc", "x-1 z-9.vc", "x-4 z-1.vc", "x-6 z-4.vc", "x-8 z-7.vc",
|
||||
"x0 z-7.vc", "x-2 z-10.vc", "x-4 z-2.vc", "x-6 z-5.vc", "x-8 z-8.vc",
|
||||
"x0 z-8.vc", "x-2 z-11.vc", "x-4 z-3.vc", "x-6 z-6.vc", "x-8 z-9.vc",
|
||||
"x0 z-9.vc", "x-2 z-1.vc", "x-4 z-4.vc", "x-6 z-7.vc", "x-9 z-10.vc",
|
||||
"x-10 z-10.vc", "x-2 z-2.vc", "x-4 z-5.vc", "x-6 z-8.vc", "x-9 z-11.vc",
|
||||
"x-10 z-11.vc", "x-2 z-3.vc", "x-4 z-6.vc", "x-6 z-9.vc", "x-9 z-1.vc",
|
||||
"x-10 z-1.vc", "x-2 z-4.vc", "x-4 z-7.vc", "x-7 z-10.vc", "x-9 z-2.vc",
|
||||
"x-10 z-2.vc", "x-2 z-5.vc", "x-4 z-8.vc", "x-7 z-11.vc", "x-9 z-3.vc",
|
||||
"x-10 z-3.vc", "x-2 z-6.vc", "x-4 z-9.vc", "x-7 z-1.vc", "x-9 z-4.vc",
|
||||
"x-10 z-4.vc", "x-2 z-7.vc", "x-5 z-10.vc", "x-7 z-2.vc", "x-9 z-5.vc",
|
||||
"x-10 z-5.vc", "x-2 z-8.vc", "x-5 z-11.vc", "x-7 z-3.vc", "x-9 z-6.vc",
|
||||
"x-10 z-6.vc", "x-2 z-9.vc", "x-5 z-1.vc", "x-7 z-4.vc", "x-9 z-7.vc",
|
||||
"x-10 z-7.vc", "x-3 z-10.vc", "x-5 z-2.vc", "x-7 z-5.vc", "x-9 z-8.vc",
|
||||
"x-10 z-8.vc", "x-3 z-11.vc", "x-5 z-3.vc", "x-7 z-6.vc", "x-9 z-9.vc",
|
||||
"x-10 z-9.vc", "x-3 z-1.vc", "x-5 z-4.vc", "x-7 z-7.vc", "x-1 z-10.vc",
|
||||
"x-3 z-2.vc", "x-5 z-5.vc", "x-7 z-8.vc", "x-1 z-11.vc", "x-3 z-3.vc",
|
||||
"x-5 z-6.vc", "x-7 z-9.vc", "x-1 z-1.vc", "x-3 z-4.vc", "x-5 z-7.vc",
|
||||
"x-8 z-10.vc",
|
||||
};
|
||||
static bool has_chunk(struct server_local* s, w_coord_t x, w_coord_t z) {
|
||||
assert(s);
|
||||
|
||||
static w_coord_t chunk_files_lookup[sizeof(chunk_files) / sizeof(*chunk_files)]
|
||||
[2];
|
||||
|
||||
static const char* find_chunk(int x, int z) {
|
||||
for(size_t k = 0; k < sizeof(chunk_files) / sizeof(*chunk_files); k++) {
|
||||
if(chunk_files_lookup[k][0] == x && chunk_files_lookup[k][1] == z)
|
||||
return chunk_files[k];
|
||||
for(size_t k = 0; k < s->loaded_regions_length; k++) {
|
||||
if(region_archive_contains(s->loaded_regions + k, x, z))
|
||||
return true;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void find_chunk_cache() {
|
||||
for(size_t k = 0; k < sizeof(chunk_files) / sizeof(*chunk_files); k++) {
|
||||
int chunk_x, chunk_z;
|
||||
FILE* f = fopen(chunk_files[k], "rb");
|
||||
assert(f);
|
||||
fread((uint8_t*)&chunk_x + 3, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)&chunk_x + 2, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)&chunk_x + 1, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)&chunk_x + 0, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)&chunk_z + 3, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)&chunk_z + 2, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)&chunk_z + 1, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)&chunk_z + 0, sizeof(uint8_t), 1, f);
|
||||
fclose(f);
|
||||
|
||||
chunk_files_lookup[k][0] = chunk_x;
|
||||
chunk_files_lookup[k][1] = chunk_z;
|
||||
}
|
||||
}
|
||||
|
||||
static void load_chunk(const char* file, int* chunk_x, int* chunk_z,
|
||||
uint8_t** ids, uint8_t** metadata, uint8_t** lighting) {
|
||||
uint8_t* chunk_data = malloc(16 * 16 * 128 * 3);
|
||||
|
||||
FILE* f = fopen(file, "rb");
|
||||
assert(f);
|
||||
fread((uint8_t*)chunk_x + 3, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)chunk_x + 2, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)chunk_x + 1, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)chunk_x + 0, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)chunk_z + 3, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)chunk_z + 2, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)chunk_z + 1, sizeof(uint8_t), 1, f);
|
||||
fread((uint8_t*)chunk_z + 0, sizeof(uint8_t), 1, f);
|
||||
fread(chunk_data, 1, 16 * 16 * 128 * 3, f);
|
||||
fclose(f);
|
||||
|
||||
*ids = malloc(16 * 16 * 128);
|
||||
*metadata = malloc(16 * 16 * 128);
|
||||
*lighting = malloc(16 * 16 * 128);
|
||||
|
||||
#define CHUNK_INDEX(x, y, z) ((x) + ((z) + (y)*16) * 16)
|
||||
|
||||
for(int y = 0; y < 128; y++) {
|
||||
for(int z = 0; z < 16; z++) {
|
||||
for(int x = 0; x < 16; x++) {
|
||||
(*ids)[CHUNK_INDEX(x, y, z)]
|
||||
= chunk_data[CHUNK_INDEX(x, y, z) * 3 + 0];
|
||||
(*metadata)[CHUNK_INDEX(x, y, z)]
|
||||
= chunk_data[CHUNK_INDEX(x, y, z) * 3 + 1];
|
||||
(*lighting)[CHUNK_INDEX(x, y, z)]
|
||||
= chunk_data[CHUNK_INDEX(x, y, z) * 3 + 2];
|
||||
}
|
||||
if(s->loaded_regions_length < MAX_REGIONS) {
|
||||
if(region_archive_create(s->loaded_regions + s->loaded_regions_length,
|
||||
"world", CHUNK_REGION_COORD(x),
|
||||
CHUNK_REGION_COORD(z))) {
|
||||
s->loaded_regions_length++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
free(chunk_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool load_chunk(struct server_local* s, w_coord_t x, w_coord_t z,
|
||||
uint8_t** ids, uint8_t** metadata, uint8_t** lighting) {
|
||||
assert(s && ids && metadata && lighting);
|
||||
|
||||
for(size_t k = 0; k < s->loaded_regions_length; k++) {
|
||||
if(region_archive_contains(s->loaded_regions + k, x, z))
|
||||
return region_archive_get_blocks(s->loaded_regions + k, x, z, ids,
|
||||
metadata, lighting);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void server_local_process(struct server_rpc* call, void* user) {
|
||||
|
@ -118,6 +52,7 @@ static void server_local_process(struct server_rpc* call, void* user) {
|
|||
s->player.x = call->payload.player_pos.x;
|
||||
s->player.y = call->payload.player_pos.y;
|
||||
s->player.z = call->payload.player_pos.z;
|
||||
s->player.has_pos = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -127,6 +62,9 @@ static void server_local_update(struct server_local* s) {
|
|||
|
||||
svin_process_messages(server_local_process, s, false);
|
||||
|
||||
if(!s->player.has_pos)
|
||||
return;
|
||||
|
||||
s->last_chunk_load = time_get();
|
||||
|
||||
w_coord_t px = WCOORD_CHUNK_OFFSET(floor(s->player.x));
|
||||
|
@ -176,7 +114,7 @@ static void server_local_update(struct server_local* s) {
|
|||
|
||||
w_coord_t d = CHUNK_DIST2(px, x, pz, z);
|
||||
if(!loaded && (d < c_nearest_dist2 || !c_nearest)
|
||||
&& find_chunk(x, z)) {
|
||||
&& has_chunk(s, x, z)) {
|
||||
c_nearest_dist2 = d;
|
||||
c_nearest_x = x;
|
||||
c_nearest_z = z;
|
||||
|
@ -187,39 +125,31 @@ static void server_local_update(struct server_local* s) {
|
|||
}
|
||||
|
||||
// load just one chunk
|
||||
if(c_nearest) {
|
||||
const char* str = find_chunk(c_nearest_x, c_nearest_z);
|
||||
if(str) {
|
||||
s->loaded_chunks[s->loaded_chunks_length++]
|
||||
= (struct loaded_chunk) {.x = c_nearest_x, .z = c_nearest_z};
|
||||
uint8_t *ids, *metadata, *lighting;
|
||||
if(c_nearest && has_chunk(s, c_nearest_x, c_nearest_z)
|
||||
&& load_chunk(s, c_nearest_x, c_nearest_z, &ids, &metadata, &lighting)) {
|
||||
s->loaded_chunks[s->loaded_chunks_length++]
|
||||
= (struct loaded_chunk) {.x = c_nearest_x, .z = c_nearest_z};
|
||||
|
||||
int x2, z2;
|
||||
uint8_t *ids, *metadata, *lighting;
|
||||
load_chunk(str, &x2, &z2, &ids, &metadata, &lighting);
|
||||
assert(x2 == c_nearest_x && z2 == c_nearest_z);
|
||||
|
||||
clin_rpc_send(&(struct client_rpc) {
|
||||
.type = CRPC_CHUNK,
|
||||
.payload.chunk.x = c_nearest_x * CHUNK_SIZE,
|
||||
.payload.chunk.y = 0,
|
||||
.payload.chunk.z = c_nearest_z * CHUNK_SIZE,
|
||||
.payload.chunk.sx = CHUNK_SIZE,
|
||||
.payload.chunk.sy = WORLD_HEIGHT,
|
||||
.payload.chunk.sz = CHUNK_SIZE,
|
||||
.payload.chunk.ids = ids,
|
||||
.payload.chunk.metadata = metadata,
|
||||
.payload.chunk.lighting = lighting,
|
||||
});
|
||||
}
|
||||
clin_rpc_send(&(struct client_rpc) {
|
||||
.type = CRPC_CHUNK,
|
||||
.payload.chunk.x = c_nearest_x * CHUNK_SIZE,
|
||||
.payload.chunk.y = 0,
|
||||
.payload.chunk.z = c_nearest_z * CHUNK_SIZE,
|
||||
.payload.chunk.sx = CHUNK_SIZE,
|
||||
.payload.chunk.sy = WORLD_HEIGHT,
|
||||
.payload.chunk.sz = CHUNK_SIZE,
|
||||
.payload.chunk.ids = ids,
|
||||
.payload.chunk.metadata = metadata,
|
||||
.payload.chunk.lighting = lighting,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void* server_local_thread(void* user) {
|
||||
find_chunk_cache();
|
||||
|
||||
while(1) {
|
||||
server_local_update(user);
|
||||
usleep(100 * 1000);
|
||||
usleep(20 * 1000);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -228,7 +158,9 @@ static void* server_local_thread(void* user) {
|
|||
void server_local_create(struct server_local* s) {
|
||||
assert(s);
|
||||
s->loaded_chunks_length = 0;
|
||||
s->loaded_regions_length = 0;
|
||||
s->last_chunk_load = time_get();
|
||||
s->player.has_pos = false;
|
||||
|
||||
lwp_t thread;
|
||||
LWP_CreateThread(&thread, server_local_thread, s, NULL, 0, 8);
|
||||
|
|
|
@ -5,19 +5,24 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include "../world.h"
|
||||
#include "region_archive.h"
|
||||
|
||||
#define MAX_VIEW_DISTANCE 3 // in chunks
|
||||
#define MAX_REGIONS 4
|
||||
#define MAX_VIEW_DISTANCE 5 // in chunks
|
||||
#define MAX_CHUNKS ((MAX_VIEW_DISTANCE * 2 + 2) * (MAX_VIEW_DISTANCE * 2 + 2))
|
||||
|
||||
struct server_local {
|
||||
struct {
|
||||
double x, y, z;
|
||||
bool has_pos;
|
||||
} player;
|
||||
struct loaded_chunk {
|
||||
w_coord_t x, z; // not!!! stored in multiples of CHUNK_SIZE
|
||||
bool modified;
|
||||
} loaded_chunks[MAX_CHUNKS];
|
||||
size_t loaded_chunks_length;
|
||||
struct region_archive loaded_regions[MAX_REGIONS];
|
||||
size_t loaded_regions_length;
|
||||
ptime_t last_chunk_load;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue