Chunk loading improvements
This commit is contained in:
@@ -167,6 +167,14 @@ errorret_t assetInit(void) {
|
|||||||
errorOk();
|
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) {
|
errorret_t assetLoad(const char_t *filename, void *output) {
|
||||||
assertStrLenMax(filename, FILENAME_MAX, "Filename too long.");
|
assertStrLenMax(filename, FILENAME_MAX, "Filename too long.");
|
||||||
assertNotNull(output, "Output pointer cannot be NULL.");
|
assertNotNull(output, "Output pointer cannot be NULL.");
|
||||||
|
|||||||
@@ -69,6 +69,14 @@ static asset_t ASSET;
|
|||||||
*/
|
*/
|
||||||
errorret_t assetInit(void);
|
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.
|
* 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");
|
assertNotNull(custom.zipFile, "Zip file pointer cannot be NULL");
|
||||||
|
|
||||||
chunk_t *chunk = (chunk_t *)custom.output;
|
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
|
// Read header
|
||||||
assetchunkheader_t header;
|
assetchunkheader_t header;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ errorret_t engineUpdate(void) {
|
|||||||
timeUpdate();
|
timeUpdate();
|
||||||
inputUpdate();
|
inputUpdate();
|
||||||
|
|
||||||
rpgUpdate();
|
errorChain(rpgUpdate());
|
||||||
uiUpdate();
|
uiUpdate();
|
||||||
sceneManagerUpdate();
|
sceneManagerUpdate();
|
||||||
errorChain(displayUpdate());
|
errorChain(displayUpdate());
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ errorret_t rpgInit(void) {
|
|||||||
// Init cutscene subsystem
|
// Init cutscene subsystem
|
||||||
cutsceneSystemInit();
|
cutsceneSystemInit();
|
||||||
|
|
||||||
mapInit();
|
errorChain(mapInit());
|
||||||
|
|
||||||
rpgCameraInit();
|
rpgCameraInit();
|
||||||
rpgTextboxInit();
|
rpgTextboxInit();
|
||||||
@@ -41,9 +41,11 @@ errorret_t rpgInit(void) {
|
|||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpgUpdate(void) {
|
errorret_t rpgUpdate(void) {
|
||||||
#if TIME_FIXED == 0
|
#if TIME_FIXED == 0
|
||||||
if(TIME.dynamicUpdate) return;
|
if(TIME.dynamicUpdate) {
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: Do not update if the scene is not the map scene?
|
// TODO: Do not update if the scene is not the map scene?
|
||||||
@@ -57,9 +59,10 @@ void rpgUpdate(void) {
|
|||||||
} while(++ent < &ENTITIES[ENTITY_COUNT]);
|
} while(++ent < &ENTITIES[ENTITY_COUNT]);
|
||||||
|
|
||||||
cutsceneSystemUpdate();
|
cutsceneSystemUpdate();
|
||||||
rpgCameraUpdate();
|
errorChain(rpgCameraUpdate());
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpgDispose(void) {
|
void rpgDispose(void) {
|
||||||
|
mapDispose();
|
||||||
}
|
}
|
||||||
@@ -21,8 +21,10 @@ errorret_t rpgInit(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the RPG subsystem.
|
* Update the RPG subsystem.
|
||||||
|
*
|
||||||
|
* @return An error code.
|
||||||
*/
|
*/
|
||||||
void rpgUpdate(void);
|
errorret_t rpgUpdate(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispose of the RPG subsystem.
|
* Dispose of the RPG subsystem.
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ void rpgCameraInit(void) {
|
|||||||
memoryZero(&RPG_CAMERA, sizeof(rpgcamera_t));
|
memoryZero(&RPG_CAMERA, sizeof(rpgcamera_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void rpgCameraUpdate(void) {
|
errorret_t rpgCameraUpdate(void) {
|
||||||
chunkpos_t chunkPos;
|
chunkpos_t chunkPos;
|
||||||
|
|
||||||
switch(RPG_CAMERA.mode) {
|
switch(RPG_CAMERA.mode) {
|
||||||
@@ -27,7 +27,9 @@ void rpgCameraUpdate(void) {
|
|||||||
|
|
||||||
case RPG_CAMERA_MODE_FOLLOW_ENTITY: {
|
case RPG_CAMERA_MODE_FOLLOW_ENTITY: {
|
||||||
entity_t *entity = &ENTITIES[RPG_CAMERA.followEntity.followEntityId];
|
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
|
// 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
|
// 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");
|
assertUnreachable("Invalid RPG camera mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
mapPositionSet((chunkpos_t){
|
errorChain(mapPositionSet((chunkpos_t){
|
||||||
.x = chunkPos.x - (MAP_CHUNK_WIDTH / 2),
|
.x = chunkPos.x - (MAP_CHUNK_WIDTH / 2),
|
||||||
.y = chunkPos.y - (MAP_CHUNK_HEIGHT / 2),
|
.y = chunkPos.y - (MAP_CHUNK_HEIGHT / 2),
|
||||||
.z = chunkPos.z - (MAP_CHUNK_DEPTH / 2)
|
.z = chunkPos.z - (MAP_CHUNK_DEPTH / 2)
|
||||||
});
|
}));
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "rpg/world/worldpos.h"
|
#include "rpg/world/worldpos.h"
|
||||||
|
#include "error/error.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RPG_CAMERA_MODE_FREE,
|
RPG_CAMERA_MODE_FREE,
|
||||||
@@ -33,5 +34,7 @@ void rpgCameraInit(void);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the RPG camera.
|
* Updates the RPG camera.
|
||||||
|
*
|
||||||
|
* @return An error code.
|
||||||
*/
|
*/
|
||||||
void rpgCameraUpdate(void);
|
errorret_t rpgCameraUpdate(void);
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
map_t MAP;
|
map_t MAP;
|
||||||
|
|
||||||
void mapInit() {
|
errorret_t mapInit() {
|
||||||
memoryZero(&MAP, sizeof(map_t));
|
memoryZero(&MAP, sizeof(map_t));
|
||||||
|
|
||||||
// Init the default chunks. In future I'll probably make this based on where
|
// 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.y = y;
|
||||||
chunk->position.z = z;
|
chunk->position.z = z;
|
||||||
MAP.chunkOrder[index] = chunk;
|
MAP.chunkOrder[index] = chunk;
|
||||||
mapChunkLoad(chunk);
|
errorChain(mapChunkLoad(chunk));
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapPositionSet(const chunkpos_t newPos) {
|
errorret_t mapPositionSet(const chunkpos_t newPos) {
|
||||||
const chunkpos_t curPos = MAP.chunkPosition;
|
const chunkpos_t curPos = MAP.chunkPosition;
|
||||||
if(chunkPositionIsEqual(curPos, newPos)) return;
|
if(chunkPositionIsEqual(curPos, newPos)) {
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
// Determine which chunks remain loaded
|
// Determine which chunks remain loaded
|
||||||
chunkindex_t chunksRemaining[MAP_CHUNK_COUNT] = {0};
|
chunkindex_t chunksRemaining[MAP_CHUNK_COUNT] = {0};
|
||||||
@@ -97,7 +101,7 @@ void mapPositionSet(const chunkpos_t newPos) {
|
|||||||
chunkIndex = chunksFreed[--freedCount];
|
chunkIndex = chunksFreed[--freedCount];
|
||||||
chunk_t *chunk = &MAP.chunks[chunkIndex];
|
chunk_t *chunk = &MAP.chunks[chunkIndex];
|
||||||
chunk->position = newChunkPos;
|
chunk->position = newChunkPos;
|
||||||
mapChunkLoad(chunk);
|
errorChain(mapChunkLoad(chunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
MAP.chunkOrder[orderIndex++] = &MAP.chunks[chunkIndex];
|
MAP.chunkOrder[orderIndex++] = &MAP.chunks[chunkIndex];
|
||||||
@@ -107,22 +111,44 @@ void mapPositionSet(const chunkpos_t newPos) {
|
|||||||
|
|
||||||
// Update map position
|
// Update map position
|
||||||
MAP.chunkPosition = newPos;
|
MAP.chunkPosition = newPos;
|
||||||
|
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mapUpdate() {
|
void mapUpdate() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mapDispose() {
|
||||||
|
for(chunkindex_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
||||||
|
mapChunkUnload(&MAP.chunks[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void mapChunkUnload(chunk_t* chunk) {
|
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.x,
|
||||||
chunk->position.y,
|
chunk->position.y,
|
||||||
chunk->position.z
|
chunk->position.z
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
void mapChunkLoad(chunk_t* chunk) {
|
if(!assetFileExists(buffer)) {
|
||||||
errorCatch(errorPrint(assetLoad("map/map/0_0.dcf", chunk)));
|
memoryZero(chunk->tiles, sizeof(chunk->tiles));
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorChain(assetLoad(buffer, chunk));
|
||||||
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
|
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
|
||||||
|
|||||||
@@ -18,20 +18,28 @@ extern map_t MAP;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the map.
|
* Initializes the map.
|
||||||
|
*
|
||||||
|
* @return An error code.
|
||||||
*/
|
*/
|
||||||
void mapInit();
|
errorret_t mapInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the map.
|
* Updates the map.
|
||||||
*/
|
*/
|
||||||
void mapUpdate();
|
void mapUpdate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disposes of the map.
|
||||||
|
*/
|
||||||
|
void mapDispose();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the map position and updates chunks accordingly.
|
* Sets the map position and updates chunks accordingly.
|
||||||
*
|
*
|
||||||
* @param newPos The new chunk position.
|
* @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.
|
* Unloads a chunk.
|
||||||
@@ -44,8 +52,9 @@ void mapChunkUnload(chunk_t* chunk);
|
|||||||
* Loads a chunk.
|
* Loads a chunk.
|
||||||
*
|
*
|
||||||
* @param chunk The chunk to load.
|
* @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.
|
* 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_HEIGHT = 16.0
|
||||||
TILE_DEPTH = 11.36
|
TILE_DEPTH = 11.36
|
||||||
|
|
||||||
def createQuadForTile(tileIndex, x=0, y=0, z=0):
|
def processTile(tileIndex, x=0, y=0, z=0):
|
||||||
vertices = []
|
vertices = []
|
||||||
indices = []
|
indices = []
|
||||||
|
|
||||||
# Tile 0, nothing
|
# Tile 0, nothing
|
||||||
if tileIndex == 0:
|
if tileIndex == 0:
|
||||||
return {
|
return None
|
||||||
'vertices': vertices,
|
|
||||||
'indices': indices
|
|
||||||
}
|
|
||||||
|
|
||||||
# Determine color for checkerboard pattern
|
# Determine color for checkerboard pattern
|
||||||
color = (255,255,255) if (x + y) % 2 == 0 else (0,0,0)
|
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)
|
z = i // (CHUNK_WIDTH * CHUNK_HEIGHT)
|
||||||
|
|
||||||
# Add tile 3D model
|
# Add tile 3D model
|
||||||
result = createQuadForTile(tile, x, y, z)
|
result = processTile(tile, x, y, z)
|
||||||
if len(result['vertices']) > 0:
|
if result is not None and len(result['vertices']) > 0:
|
||||||
base = len(baseModel['vertices'])
|
base = len(baseModel['vertices'])
|
||||||
quad_indices = [base + idx for idx in result['indices']]
|
quad_indices = [base + idx for idx in result['indices']]
|
||||||
baseModel['vertices'].extend(result['vertices'])
|
baseModel['vertices'].extend(result['vertices'])
|
||||||
|
|||||||
Reference in New Issue
Block a user