Chunk loading example
This commit is contained in:
@@ -7,17 +7,119 @@
|
||||
|
||||
#include "map.h"
|
||||
#include "util/memory.h"
|
||||
#include <stdio.h> // For printf
|
||||
|
||||
map_t MAP;
|
||||
|
||||
// Dummy functions for chunk loading/unloading
|
||||
void mapChunkUnload(chunk_t* chunk) {
|
||||
// Placeholder for unloading logic
|
||||
printf("Unloading chunk at (%d, %d, %d)\n", chunk->x, chunk->y, chunk->z);
|
||||
}
|
||||
|
||||
void mapChunkLoad(chunk_t* chunk) {
|
||||
// Placeholder for loading logic
|
||||
printf("Loading chunk at (%d, %d, %d)\n", chunk->x, chunk->y, chunk->z);
|
||||
}
|
||||
|
||||
void mapInit() {
|
||||
memoryZero(&MAP, sizeof(map_t));
|
||||
|
||||
for(uint32_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
||||
MAP.chunkOrder[i] = &MAP.chunks[i];
|
||||
uint32_t index = 0;
|
||||
for(uint32_t z = 0; z < MAP_CHUNK_DEPTH; z++) {
|
||||
for(uint32_t y = 0; y < MAP_CHUNK_HEIGHT; y++) {
|
||||
for(uint32_t x = 0; x < MAP_CHUNK_WIDTH; x++) {
|
||||
chunk_t *chunk = &MAP.chunks[index];
|
||||
chunk->x = x;
|
||||
chunk->y = y;
|
||||
chunk->z = z;
|
||||
MAP.chunkOrder[index] = chunk;
|
||||
mapChunkLoad(chunk);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mapPositionSet(const int16_t x, const int16_t y, const int16_t z) {
|
||||
const int16_t curX = MAP.x;
|
||||
const int16_t curY = MAP.y;
|
||||
const int16_t curZ = MAP.z;
|
||||
if(curX == x && curY == y && curZ == z) return;
|
||||
|
||||
// Determine which chunks remain loaded
|
||||
int32_t chunksRemaining[MAP_CHUNK_COUNT] = {0};
|
||||
int32_t chunksFreed[MAP_CHUNK_COUNT] = {0};
|
||||
|
||||
uint32_t remainingCount = 0;
|
||||
uint32_t freedCount = 0;
|
||||
|
||||
for(uint32_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
||||
// Will this chunk remain loaded?
|
||||
chunk_t *chunk = &MAP.chunks[i];
|
||||
if(
|
||||
chunk->x >= x && chunk->x < x + MAP_CHUNK_WIDTH &&
|
||||
chunk->y >= y && chunk->y < y + MAP_CHUNK_HEIGHT &&
|
||||
chunk->z >= z && chunk->z < z + MAP_CHUNK_DEPTH
|
||||
) {
|
||||
// Stays loaded
|
||||
chunksRemaining[remainingCount++] = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not remaining loaded
|
||||
chunksFreed[freedCount++] = i;
|
||||
}
|
||||
|
||||
// Unload the freed chunks
|
||||
for(uint32_t i = 0; i < freedCount; i++) {
|
||||
chunk_t *chunk = &MAP.chunks[chunksFreed[i]];
|
||||
mapChunkUnload(chunk);
|
||||
}
|
||||
|
||||
// This can probably be optimized later, for now we check each chunk and see
|
||||
// if it needs loading or not, and update the chunk order
|
||||
uint32_t orderIndex = 0;
|
||||
for(uint32_t zOff = 0; zOff < MAP_CHUNK_DEPTH; zOff++) {
|
||||
for(uint32_t yOff = 0; yOff < MAP_CHUNK_HEIGHT; yOff++) {
|
||||
for(uint32_t xOff = 0; xOff < MAP_CHUNK_WIDTH; xOff++) {
|
||||
const int16_t chunkX = x + xOff;
|
||||
const int16_t chunkY = y + yOff;
|
||||
const int16_t chunkZ = z + zOff;
|
||||
|
||||
// Is this chunk already loaded (was not unloaded earlier)?
|
||||
int32_t chunkIndex = -1;
|
||||
for(uint32_t i = 0; i < remainingCount; i++) {
|
||||
chunk_t *chunk = &MAP.chunks[chunksRemaining[i]];
|
||||
if(chunk->x != chunkX) continue;
|
||||
if(chunk->y != chunkY) continue;
|
||||
if(chunk->z != chunkZ) continue;
|
||||
chunkIndex = chunksRemaining[i];
|
||||
break;
|
||||
}
|
||||
|
||||
// Need to load this chunk
|
||||
if(chunkIndex == -1) {
|
||||
// Find a freed chunk to reuse
|
||||
chunkIndex = chunksFreed[--freedCount];
|
||||
chunk_t *chunk = &MAP.chunks[chunkIndex];
|
||||
chunk->x = chunkX;
|
||||
chunk->y = chunkY;
|
||||
chunk->z = chunkZ;
|
||||
mapChunkLoad(chunk);
|
||||
}
|
||||
|
||||
MAP.chunkOrder[orderIndex++] = &MAP.chunks[chunkIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update map position
|
||||
MAP.x = x;
|
||||
MAP.y = y;
|
||||
MAP.z = z;
|
||||
}
|
||||
|
||||
void mapUpdate() {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user