Map refactoring to prep for loading
Some checks failed
Build Dusk / build-linux (push) Successful in 1m35s
Build Dusk / build-psp (push) Failing after 1m46s

This commit is contained in:
2025-12-26 15:01:43 +10:00
parent b16dbaceec
commit 7940f4c487
11 changed files with 108 additions and 16 deletions

View File

@@ -41,7 +41,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
// Run the initial script.
scriptcontext_t ctx;
errorChain(scriptContextInit(&ctx));
errorChain(scriptContextExecFile(&ctx, "script/init.dsf"));
errorChain(scriptContextExecFile(&ctx, "init.dsf"));
scriptContextDispose(&ctx);
errorOk();

View File

@@ -18,6 +18,8 @@ void rpgCameraInit(void) {
}
errorret_t rpgCameraUpdate(void) {
if(!mapIsLoaded()) errorOk();
chunkpos_t chunkPos;
switch(RPG_CAMERA.mode) {

View File

@@ -10,32 +10,66 @@
#include "assert/assert.h"
#include "asset/asset.h"
#include "rpg/entity/entity.h"
#include "util/string.h"
map_t MAP;
errorret_t mapInit() {
memoryZero(&MAP, sizeof(map_t));
errorOk();
}
bool_t mapIsLoaded() {
return MAP.filePath[0] != '\0';
}
errorret_t mapLoad(const char_t *path, const chunkpos_t position) {
assertStrLenMin(path, 1, "Map file path cannot be empty");
assertStrLenMax(path, MAP_FILE_PATH_MAX - 1, "Map file path too long");
if(stringCompare(MAP.filePath, path) == 0) {
// Same map, no need to reload
errorOk();
}
chunkindex_t i;
// Init the first chunks.
chunkindex_t index = 0;
// Unload all loaded chunks
if(mapIsLoaded()) {
for(i = 0; i < MAP_CHUNK_COUNT; i++) {
mapChunkUnload(&MAP.chunks[i]);
}
}
// Store the map file path
stringCopy(MAP.filePath, path, MAP_FILE_PATH_MAX);
// Reset map position
MAP.chunkPosition = position;
// Perform "initial load"
i = 0;
for(chunkunit_t z = 0; z < MAP_CHUNK_DEPTH; z++) {
for(chunkunit_t y = 0; y < MAP_CHUNK_HEIGHT; y++) {
for(chunkunit_t x = 0; x < MAP_CHUNK_WIDTH; x++) {
chunk_t *chunk = &MAP.chunks[index];
chunk->position.x = x;
chunk->position.y = y;
chunk->position.z = z;
MAP.chunkOrder[index] = chunk;
chunk_t *chunk = &MAP.chunks[i];
chunk->position.x = x + position.x;
chunk->position.y = y + position.y;
chunk->position.z = z + position.z;
MAP.chunkOrder[i] = chunk;
errorChain(mapChunkLoad(chunk));
index++;
i++;
}
}
}
// Execute map script.
errorOk();
}
errorret_t mapPositionSet(const chunkpos_t newPos) {
if(!mapIsLoaded()) errorThrow("No map loaded");
const chunkpos_t curPos = MAP.chunkPosition;
if(chunkPositionIsEqual(curPos, newPos)) {
errorOk();
@@ -131,6 +165,7 @@ void mapChunkUnload(chunk_t* chunk) {
entity_t *entity = &ENTITIES[chunk->entities[i]];
entity->type = ENTITY_TYPE_NULL;
}
for(uint8_t i = 0; i < chunk->meshCount; i++) {
if(chunk->meshes[i].vertexCount == 0) continue;
meshDispose(&chunk->meshes[i]);
@@ -138,28 +173,37 @@ void mapChunkUnload(chunk_t* chunk) {
}
errorret_t mapChunkLoad(chunk_t* chunk) {
if(!mapIsLoaded()) errorThrow("No map loaded");
char_t buffer[64];
// TODO: Can probably move this to asset load logic?
chunk->meshCount = 0;
memoryZero(chunk->meshes, sizeof(chunk->meshes));
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
snprintf(buffer, sizeof(buffer), "map/map/%d_%d_%d.dcf",
// Get chunk filepath.
snprintf(buffer, sizeof(buffer), "%s/%d_%d_%d.dcf",
MAP.filePath,
chunk->position.x,
chunk->position.y,
chunk->position.z
);
// Chunk available?
if(!assetFileExists(buffer)) {
memoryZero(chunk->tiles, sizeof(chunk->tiles));
errorOk();
}
// Load.
errorChain(assetLoad(buffer, chunk));
errorOk();
}
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
if(!mapIsLoaded()) return -1;
chunkpos_t relPos = {
position.x - MAP.chunkPosition.x,
position.y - MAP.chunkPosition.y,
@@ -180,10 +224,13 @@ chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
chunk_t* mapGetChunk(const uint8_t index) {
if(index >= MAP_CHUNK_COUNT) return NULL;
if(!mapIsLoaded()) return NULL;
return MAP.chunkOrder[index];
}
tile_t mapGetTile(const worldpos_t position) {
if(!mapIsLoaded()) return TILE_SHAPE_NULL;
chunkpos_t chunkPos;
worldPosToChunkPos(&position, &chunkPos);
chunkindex_t chunkIndex = mapGetChunkIndexAt(chunkPos);

View File

@@ -8,7 +8,10 @@
#pragma once
#include "rpg/world/chunk.h"
#define MAP_FILE_PATH_MAX 128
typedef struct map_s {
char_t filePath[MAP_FILE_PATH_MAX];
chunk_t chunks[MAP_CHUNK_COUNT];
chunk_t *chunkOrder[MAP_CHUNK_COUNT];
chunkpos_t chunkPosition;
@@ -23,6 +26,25 @@ extern map_t MAP;
*/
errorret_t mapInit();
/**
* Checks if a map is loaded.
*
* @return true if a map is loaded, false otherwise.
*/
bool_t mapIsLoaded();
/**
* Loads a map from the given file path.
*
* @param path The file path.
* @param position The initial chunk position.
* @return An error code.
*/
errorret_t mapLoad(
const char_t *path,
const chunkpos_t position
);
/**
* Updates the map.
*/

View File

@@ -89,6 +89,8 @@ void sceneMapEntityGetPosition(const entity_t *entity, vec3 outPosition) {
}
void sceneMapRender(scenedata_t *data) {
if(!mapIsLoaded()) return;
// Look at target.
vec3 cameraTarget;
switch(RPG_CAMERA.mode) {
@@ -166,6 +168,8 @@ void sceneMapRenderEntity(entity_t *entity) {
}
void sceneMapRenderMap() {
assertTrue(mapIsLoaded(), "No map loaded to render");
// For each chunk.
for(uint32_t i = 0; i < MAP_CHUNK_COUNT; i++) {
chunk_t *chunk = MAP.chunkOrder[i];

View File

@@ -10,6 +10,8 @@
#include "assert/assert.h"
#include "display/framebuffer.h"
#include "util/string.h"
#include "asset/asset.h"
#include "script/scriptmanager.h"
scenemanager_t SCENE_MANAGER;
@@ -60,9 +62,20 @@ errorret_t sceneManagerSetScene(scene_t *scene) {
SCENE_MANAGER.current = scene;
if(scene && scene->init) {
if(scene && (scene->flags & SCENE_FLAG_INITIALIZED) == 0) {
scene->flags |= SCENE_FLAG_INITIALIZED;
errorChain(scene->init(&SCENE_MANAGER.sceneData));
if(scene->init) errorChain(scene->init(&SCENE_MANAGER.sceneData));
// Execute scene script if it exists
char_t buffer[256];
snprintf(buffer, sizeof(buffer), "scene/%s.dsf", scene->name);
if(assetFileExists(buffer)) {
scriptcontext_t ctx;
scriptContextInit(&ctx);
errorChain(scriptContextExecFile(&ctx, buffer));
scriptContextDispose(&ctx);
}
}
errorOk();

View File

@@ -28,7 +28,6 @@ int32_t moduleSceneSetScene(lua_State *L) {
errorret_t err = sceneManagerSetScene(scene);
if(err.code != ERROR_OK) {
luaL_error(L, "Failed to set scene '%s'", sceneName);
return 0;
}