Chunk loading improvements
This commit is contained in:
@@ -167,6 +167,14 @@ errorret_t assetInit(void) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
bool_t assetFileExists(const char_t *filename) {
|
||||
assertStrLenMax(filename, FILENAME_MAX, "Filename too long.");
|
||||
|
||||
zip_int64_t idx = zip_name_locate(ASSET.zip, filename, 0);
|
||||
if(idx < 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
errorret_t assetLoad(const char_t *filename, void *output) {
|
||||
assertStrLenMax(filename, FILENAME_MAX, "Filename too long.");
|
||||
assertNotNull(output, "Output pointer cannot be NULL.");
|
||||
|
||||
@@ -69,6 +69,14 @@ static asset_t ASSET;
|
||||
*/
|
||||
errorret_t assetInit(void);
|
||||
|
||||
/**
|
||||
* Checks if an asset file exists.
|
||||
*
|
||||
* @param filename The filename of the asset to check.
|
||||
* @return true if the asset file exists, false otherwise.
|
||||
*/
|
||||
bool_t assetFileExists(const char_t *filename);
|
||||
|
||||
/**
|
||||
* Loads an asset by its filename, the output type depends on the asset type.
|
||||
*
|
||||
|
||||
@@ -32,6 +32,12 @@ errorret_t assetChunkLoad(assetcustom_t custom) {
|
||||
assertNotNull(custom.zipFile, "Zip file pointer cannot be NULL");
|
||||
|
||||
chunk_t *chunk = (chunk_t *)custom.output;
|
||||
printf(
|
||||
"Loading chunk asset at position (%d, %d, %d)...\n",
|
||||
chunk->position.x,
|
||||
chunk->position.y,
|
||||
chunk->position.z
|
||||
);
|
||||
|
||||
// Read header
|
||||
assetchunkheader_t header;
|
||||
|
||||
@@ -42,8 +42,8 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
|
||||
errorret_t engineUpdate(void) {
|
||||
timeUpdate();
|
||||
inputUpdate();
|
||||
|
||||
rpgUpdate();
|
||||
|
||||
errorChain(rpgUpdate());
|
||||
uiUpdate();
|
||||
sceneManagerUpdate();
|
||||
errorChain(displayUpdate());
|
||||
|
||||
@@ -20,7 +20,7 @@ errorret_t rpgInit(void) {
|
||||
// Init cutscene subsystem
|
||||
cutsceneSystemInit();
|
||||
|
||||
mapInit();
|
||||
errorChain(mapInit());
|
||||
|
||||
rpgCameraInit();
|
||||
rpgTextboxInit();
|
||||
@@ -41,9 +41,11 @@ errorret_t rpgInit(void) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void rpgUpdate(void) {
|
||||
errorret_t rpgUpdate(void) {
|
||||
#if TIME_FIXED == 0
|
||||
if(TIME.dynamicUpdate) return;
|
||||
if(TIME.dynamicUpdate) {
|
||||
errorOk();
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: Do not update if the scene is not the map scene?
|
||||
@@ -57,9 +59,10 @@ void rpgUpdate(void) {
|
||||
} while(++ent < &ENTITIES[ENTITY_COUNT]);
|
||||
|
||||
cutsceneSystemUpdate();
|
||||
rpgCameraUpdate();
|
||||
errorChain(rpgCameraUpdate());
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void rpgDispose(void) {
|
||||
|
||||
mapDispose();
|
||||
}
|
||||
@@ -21,8 +21,10 @@ errorret_t rpgInit(void);
|
||||
|
||||
/**
|
||||
* Update the RPG subsystem.
|
||||
*
|
||||
* @return An error code.
|
||||
*/
|
||||
void rpgUpdate(void);
|
||||
errorret_t rpgUpdate(void);
|
||||
|
||||
/**
|
||||
* Dispose of the RPG subsystem.
|
||||
|
||||
@@ -17,7 +17,7 @@ void rpgCameraInit(void) {
|
||||
memoryZero(&RPG_CAMERA, sizeof(rpgcamera_t));
|
||||
}
|
||||
|
||||
void rpgCameraUpdate(void) {
|
||||
errorret_t rpgCameraUpdate(void) {
|
||||
chunkpos_t chunkPos;
|
||||
|
||||
switch(RPG_CAMERA.mode) {
|
||||
@@ -27,7 +27,9 @@ void rpgCameraUpdate(void) {
|
||||
|
||||
case RPG_CAMERA_MODE_FOLLOW_ENTITY: {
|
||||
entity_t *entity = &ENTITIES[RPG_CAMERA.followEntity.followEntityId];
|
||||
if(entity->type == ENTITY_TYPE_NULL) return;
|
||||
if(entity->type == ENTITY_TYPE_NULL) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
// Update map position to match camera. By default map wants to know the
|
||||
// top left but we want to set the center, so we need to sub half map size
|
||||
@@ -39,9 +41,10 @@ void rpgCameraUpdate(void) {
|
||||
assertUnreachable("Invalid RPG camera mode");
|
||||
}
|
||||
|
||||
mapPositionSet((chunkpos_t){
|
||||
errorChain(mapPositionSet((chunkpos_t){
|
||||
.x = chunkPos.x - (MAP_CHUNK_WIDTH / 2),
|
||||
.y = chunkPos.y - (MAP_CHUNK_HEIGHT / 2),
|
||||
.z = chunkPos.z - (MAP_CHUNK_DEPTH / 2)
|
||||
});
|
||||
}));
|
||||
errorOk();
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "rpg/world/worldpos.h"
|
||||
#include "error/error.h"
|
||||
|
||||
typedef enum {
|
||||
RPG_CAMERA_MODE_FREE,
|
||||
@@ -33,5 +34,7 @@ void rpgCameraInit(void);
|
||||
|
||||
/**
|
||||
* Updates the RPG camera.
|
||||
*
|
||||
* @return An error code.
|
||||
*/
|
||||
void rpgCameraUpdate(void);
|
||||
errorret_t rpgCameraUpdate(void);
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
map_t MAP;
|
||||
|
||||
void mapInit() {
|
||||
errorret_t mapInit() {
|
||||
memoryZero(&MAP, sizeof(map_t));
|
||||
|
||||
// Init the default chunks. In future I'll probably make this based on where
|
||||
@@ -26,16 +26,20 @@ void mapInit() {
|
||||
chunk->position.y = y;
|
||||
chunk->position.z = z;
|
||||
MAP.chunkOrder[index] = chunk;
|
||||
mapChunkLoad(chunk);
|
||||
errorChain(mapChunkLoad(chunk));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void mapPositionSet(const chunkpos_t newPos) {
|
||||
errorret_t mapPositionSet(const chunkpos_t newPos) {
|
||||
const chunkpos_t curPos = MAP.chunkPosition;
|
||||
if(chunkPositionIsEqual(curPos, newPos)) return;
|
||||
if(chunkPositionIsEqual(curPos, newPos)) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
// Determine which chunks remain loaded
|
||||
chunkindex_t chunksRemaining[MAP_CHUNK_COUNT] = {0};
|
||||
@@ -97,7 +101,7 @@ void mapPositionSet(const chunkpos_t newPos) {
|
||||
chunkIndex = chunksFreed[--freedCount];
|
||||
chunk_t *chunk = &MAP.chunks[chunkIndex];
|
||||
chunk->position = newChunkPos;
|
||||
mapChunkLoad(chunk);
|
||||
errorChain(mapChunkLoad(chunk));
|
||||
}
|
||||
|
||||
MAP.chunkOrder[orderIndex++] = &MAP.chunks[chunkIndex];
|
||||
@@ -107,22 +111,44 @@ void mapPositionSet(const chunkpos_t newPos) {
|
||||
|
||||
// Update map position
|
||||
MAP.chunkPosition = newPos;
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void mapUpdate() {
|
||||
|
||||
}
|
||||
|
||||
void mapDispose() {
|
||||
for(chunkindex_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
||||
mapChunkUnload(&MAP.chunks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void mapChunkUnload(chunk_t* chunk) {
|
||||
printf("Unloading chunk at (%d, %d, %d)\n",
|
||||
for(uint8_t i = 0; i < chunk->meshCount; i++) {
|
||||
meshDispose(&chunk->meshes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
errorret_t mapChunkLoad(chunk_t* chunk) {
|
||||
char_t buffer[64];
|
||||
|
||||
chunk->meshCount = 0;
|
||||
|
||||
snprintf(buffer, sizeof(buffer), "map/map/%d_%d_%d.dcf",
|
||||
chunk->position.x,
|
||||
chunk->position.y,
|
||||
chunk->position.z
|
||||
);
|
||||
}
|
||||
|
||||
void mapChunkLoad(chunk_t* chunk) {
|
||||
errorCatch(errorPrint(assetLoad("map/map/0_0.dcf", chunk)));
|
||||
if(!assetFileExists(buffer)) {
|
||||
memoryZero(chunk->tiles, sizeof(chunk->tiles));
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorChain(assetLoad(buffer, chunk));
|
||||
errorOk();
|
||||
}
|
||||
|
||||
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
|
||||
|
||||
@@ -18,20 +18,28 @@ extern map_t MAP;
|
||||
|
||||
/**
|
||||
* Initializes the map.
|
||||
*
|
||||
* @return An error code.
|
||||
*/
|
||||
void mapInit();
|
||||
errorret_t mapInit();
|
||||
|
||||
/**
|
||||
* Updates the map.
|
||||
*/
|
||||
void mapUpdate();
|
||||
|
||||
/**
|
||||
* Disposes of the map.
|
||||
*/
|
||||
void mapDispose();
|
||||
|
||||
/**
|
||||
* Sets the map position and updates chunks accordingly.
|
||||
*
|
||||
* @param newPos The new chunk position.
|
||||
* @return An error code.
|
||||
*/
|
||||
void mapPositionSet(const chunkpos_t newPos);
|
||||
errorret_t mapPositionSet(const chunkpos_t newPos);
|
||||
|
||||
/**
|
||||
* Unloads a chunk.
|
||||
@@ -44,8 +52,9 @@ void mapChunkUnload(chunk_t* chunk);
|
||||
* Loads a chunk.
|
||||
*
|
||||
* @param chunk The chunk to load.
|
||||
* @return An error code.
|
||||
*/
|
||||
void mapChunkLoad(chunk_t* chunk);
|
||||
errorret_t mapChunkLoad(chunk_t* chunk);
|
||||
|
||||
/**
|
||||
* Gets the index of a chunk, within the world, at the given position.
|
||||
|
||||
@@ -14,16 +14,13 @@ TILE_WIDTH = 16.0
|
||||
TILE_HEIGHT = 16.0
|
||||
TILE_DEPTH = 11.36
|
||||
|
||||
def createQuadForTile(tileIndex, x=0, y=0, z=0):
|
||||
def processTile(tileIndex, x=0, y=0, z=0):
|
||||
vertices = []
|
||||
indices = []
|
||||
|
||||
# Tile 0, nothing
|
||||
if tileIndex == 0:
|
||||
return {
|
||||
'vertices': vertices,
|
||||
'indices': indices
|
||||
}
|
||||
return None
|
||||
|
||||
# Determine color for checkerboard pattern
|
||||
color = (255,255,255) if (x + y) % 2 == 0 else (0,0,0)
|
||||
@@ -82,8 +79,8 @@ def processChunk(path):
|
||||
z = i // (CHUNK_WIDTH * CHUNK_HEIGHT)
|
||||
|
||||
# Add tile 3D model
|
||||
result = createQuadForTile(tile, x, y, z)
|
||||
if len(result['vertices']) > 0:
|
||||
result = processTile(tile, x, y, z)
|
||||
if result is not None and len(result['vertices']) > 0:
|
||||
base = len(baseModel['vertices'])
|
||||
quad_indices = [base + idx for idx in result['indices']]
|
||||
baseModel['vertices'].extend(result['vertices'])
|
||||
|
||||
Reference in New Issue
Block a user