Map refactoring to prep for loading
This commit is contained in:
@@ -11,7 +11,11 @@ add_subdirectory(palette)
|
|||||||
# Languages need to be added before anything that uses text.
|
# Languages need to be added before anything that uses text.
|
||||||
add_subdirectory(locale)
|
add_subdirectory(locale)
|
||||||
|
|
||||||
|
# Rest, order doesn't matter
|
||||||
|
add_asset(SCRIPT init.lua)
|
||||||
|
|
||||||
|
# Subdirs
|
||||||
add_subdirectory(entity)
|
add_subdirectory(entity)
|
||||||
add_subdirectory(script)
|
|
||||||
add_subdirectory(map)
|
add_subdirectory(map)
|
||||||
add_subdirectory(ui)
|
add_subdirectory(ui)
|
||||||
|
add_subdirectory(scene)
|
||||||
@@ -3,4 +3,4 @@
|
|||||||
# This software is released under the MIT License.
|
# This software is released under the MIT License.
|
||||||
# https://opensource.org/licenses/MIT
|
# https://opensource.org/licenses/MIT
|
||||||
|
|
||||||
add_asset(SCRIPT init.lua)
|
add_asset(SCRIPT map.lua)
|
||||||
1
assets/scene/map.lua
Normal file
1
assets/scene/map.lua
Normal file
@@ -0,0 +1 @@
|
|||||||
|
print('map')
|
||||||
@@ -41,7 +41,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
|
|||||||
// Run the initial script.
|
// Run the initial script.
|
||||||
scriptcontext_t ctx;
|
scriptcontext_t ctx;
|
||||||
errorChain(scriptContextInit(&ctx));
|
errorChain(scriptContextInit(&ctx));
|
||||||
errorChain(scriptContextExecFile(&ctx, "script/init.dsf"));
|
errorChain(scriptContextExecFile(&ctx, "init.dsf"));
|
||||||
scriptContextDispose(&ctx);
|
scriptContextDispose(&ctx);
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ void rpgCameraInit(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorret_t rpgCameraUpdate(void) {
|
errorret_t rpgCameraUpdate(void) {
|
||||||
|
if(!mapIsLoaded()) errorOk();
|
||||||
|
|
||||||
chunkpos_t chunkPos;
|
chunkpos_t chunkPos;
|
||||||
|
|
||||||
switch(RPG_CAMERA.mode) {
|
switch(RPG_CAMERA.mode) {
|
||||||
|
|||||||
@@ -10,32 +10,66 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "asset/asset.h"
|
#include "asset/asset.h"
|
||||||
#include "rpg/entity/entity.h"
|
#include "rpg/entity/entity.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
map_t MAP;
|
map_t MAP;
|
||||||
|
|
||||||
errorret_t mapInit() {
|
errorret_t mapInit() {
|
||||||
memoryZero(&MAP, sizeof(map_t));
|
memoryZero(&MAP, sizeof(map_t));
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
// Init the first chunks.
|
bool_t mapIsLoaded() {
|
||||||
chunkindex_t index = 0;
|
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;
|
||||||
|
|
||||||
|
// 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 z = 0; z < MAP_CHUNK_DEPTH; z++) {
|
||||||
for(chunkunit_t y = 0; y < MAP_CHUNK_HEIGHT; y++) {
|
for(chunkunit_t y = 0; y < MAP_CHUNK_HEIGHT; y++) {
|
||||||
for(chunkunit_t x = 0; x < MAP_CHUNK_WIDTH; x++) {
|
for(chunkunit_t x = 0; x < MAP_CHUNK_WIDTH; x++) {
|
||||||
chunk_t *chunk = &MAP.chunks[index];
|
chunk_t *chunk = &MAP.chunks[i];
|
||||||
chunk->position.x = x;
|
chunk->position.x = x + position.x;
|
||||||
chunk->position.y = y;
|
chunk->position.y = y + position.y;
|
||||||
chunk->position.z = z;
|
chunk->position.z = z + position.z;
|
||||||
MAP.chunkOrder[index] = chunk;
|
MAP.chunkOrder[i] = chunk;
|
||||||
errorChain(mapChunkLoad(chunk));
|
errorChain(mapChunkLoad(chunk));
|
||||||
index++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute map script.
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
errorret_t mapPositionSet(const chunkpos_t newPos) {
|
errorret_t mapPositionSet(const chunkpos_t newPos) {
|
||||||
|
if(!mapIsLoaded()) errorThrow("No map loaded");
|
||||||
|
|
||||||
const chunkpos_t curPos = MAP.chunkPosition;
|
const chunkpos_t curPos = MAP.chunkPosition;
|
||||||
if(chunkPositionIsEqual(curPos, newPos)) {
|
if(chunkPositionIsEqual(curPos, newPos)) {
|
||||||
errorOk();
|
errorOk();
|
||||||
@@ -131,6 +165,7 @@ void mapChunkUnload(chunk_t* chunk) {
|
|||||||
entity_t *entity = &ENTITIES[chunk->entities[i]];
|
entity_t *entity = &ENTITIES[chunk->entities[i]];
|
||||||
entity->type = ENTITY_TYPE_NULL;
|
entity->type = ENTITY_TYPE_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(uint8_t i = 0; i < chunk->meshCount; i++) {
|
for(uint8_t i = 0; i < chunk->meshCount; i++) {
|
||||||
if(chunk->meshes[i].vertexCount == 0) continue;
|
if(chunk->meshes[i].vertexCount == 0) continue;
|
||||||
meshDispose(&chunk->meshes[i]);
|
meshDispose(&chunk->meshes[i]);
|
||||||
@@ -138,28 +173,37 @@ void mapChunkUnload(chunk_t* chunk) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
errorret_t mapChunkLoad(chunk_t* chunk) {
|
errorret_t mapChunkLoad(chunk_t* chunk) {
|
||||||
|
if(!mapIsLoaded()) errorThrow("No map loaded");
|
||||||
|
|
||||||
char_t buffer[64];
|
char_t buffer[64];
|
||||||
|
|
||||||
|
// TODO: Can probably move this to asset load logic?
|
||||||
chunk->meshCount = 0;
|
chunk->meshCount = 0;
|
||||||
memoryZero(chunk->meshes, sizeof(chunk->meshes));
|
memoryZero(chunk->meshes, sizeof(chunk->meshes));
|
||||||
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
|
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.x,
|
||||||
chunk->position.y,
|
chunk->position.y,
|
||||||
chunk->position.z
|
chunk->position.z
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Chunk available?
|
||||||
if(!assetFileExists(buffer)) {
|
if(!assetFileExists(buffer)) {
|
||||||
memoryZero(chunk->tiles, sizeof(chunk->tiles));
|
memoryZero(chunk->tiles, sizeof(chunk->tiles));
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load.
|
||||||
errorChain(assetLoad(buffer, chunk));
|
errorChain(assetLoad(buffer, chunk));
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
|
chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
|
||||||
|
if(!mapIsLoaded()) return -1;
|
||||||
|
|
||||||
chunkpos_t relPos = {
|
chunkpos_t relPos = {
|
||||||
position.x - MAP.chunkPosition.x,
|
position.x - MAP.chunkPosition.x,
|
||||||
position.y - MAP.chunkPosition.y,
|
position.y - MAP.chunkPosition.y,
|
||||||
@@ -180,10 +224,13 @@ chunkindex_t mapGetChunkIndexAt(const chunkpos_t position) {
|
|||||||
|
|
||||||
chunk_t* mapGetChunk(const uint8_t index) {
|
chunk_t* mapGetChunk(const uint8_t index) {
|
||||||
if(index >= MAP_CHUNK_COUNT) return NULL;
|
if(index >= MAP_CHUNK_COUNT) return NULL;
|
||||||
|
if(!mapIsLoaded()) return NULL;
|
||||||
return MAP.chunkOrder[index];
|
return MAP.chunkOrder[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
tile_t mapGetTile(const worldpos_t position) {
|
tile_t mapGetTile(const worldpos_t position) {
|
||||||
|
if(!mapIsLoaded()) return TILE_SHAPE_NULL;
|
||||||
|
|
||||||
chunkpos_t chunkPos;
|
chunkpos_t chunkPos;
|
||||||
worldPosToChunkPos(&position, &chunkPos);
|
worldPosToChunkPos(&position, &chunkPos);
|
||||||
chunkindex_t chunkIndex = mapGetChunkIndexAt(chunkPos);
|
chunkindex_t chunkIndex = mapGetChunkIndexAt(chunkPos);
|
||||||
|
|||||||
@@ -8,7 +8,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "rpg/world/chunk.h"
|
#include "rpg/world/chunk.h"
|
||||||
|
|
||||||
|
#define MAP_FILE_PATH_MAX 128
|
||||||
|
|
||||||
typedef struct map_s {
|
typedef struct map_s {
|
||||||
|
char_t filePath[MAP_FILE_PATH_MAX];
|
||||||
chunk_t chunks[MAP_CHUNK_COUNT];
|
chunk_t chunks[MAP_CHUNK_COUNT];
|
||||||
chunk_t *chunkOrder[MAP_CHUNK_COUNT];
|
chunk_t *chunkOrder[MAP_CHUNK_COUNT];
|
||||||
chunkpos_t chunkPosition;
|
chunkpos_t chunkPosition;
|
||||||
@@ -23,6 +26,25 @@ extern map_t MAP;
|
|||||||
*/
|
*/
|
||||||
errorret_t mapInit();
|
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.
|
* Updates the map.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ void sceneMapEntityGetPosition(const entity_t *entity, vec3 outPosition) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sceneMapRender(scenedata_t *data) {
|
void sceneMapRender(scenedata_t *data) {
|
||||||
|
if(!mapIsLoaded()) return;
|
||||||
|
|
||||||
// Look at target.
|
// Look at target.
|
||||||
vec3 cameraTarget;
|
vec3 cameraTarget;
|
||||||
switch(RPG_CAMERA.mode) {
|
switch(RPG_CAMERA.mode) {
|
||||||
@@ -166,6 +168,8 @@ void sceneMapRenderEntity(entity_t *entity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sceneMapRenderMap() {
|
void sceneMapRenderMap() {
|
||||||
|
assertTrue(mapIsLoaded(), "No map loaded to render");
|
||||||
|
|
||||||
// For each chunk.
|
// For each chunk.
|
||||||
for(uint32_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
for(uint32_t i = 0; i < MAP_CHUNK_COUNT; i++) {
|
||||||
chunk_t *chunk = MAP.chunkOrder[i];
|
chunk_t *chunk = MAP.chunkOrder[i];
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "display/framebuffer.h"
|
#include "display/framebuffer.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
#include "asset/asset.h"
|
||||||
|
#include "script/scriptmanager.h"
|
||||||
|
|
||||||
scenemanager_t SCENE_MANAGER;
|
scenemanager_t SCENE_MANAGER;
|
||||||
|
|
||||||
@@ -60,9 +62,20 @@ errorret_t sceneManagerSetScene(scene_t *scene) {
|
|||||||
|
|
||||||
SCENE_MANAGER.current = scene;
|
SCENE_MANAGER.current = scene;
|
||||||
|
|
||||||
if(scene && scene->init) {
|
if(scene && (scene->flags & SCENE_FLAG_INITIALIZED) == 0) {
|
||||||
scene->flags |= SCENE_FLAG_INITIALIZED;
|
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();
|
errorOk();
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ int32_t moduleSceneSetScene(lua_State *L) {
|
|||||||
|
|
||||||
errorret_t err = sceneManagerSetScene(scene);
|
errorret_t err = sceneManagerSetScene(scene);
|
||||||
if(err.code != ERROR_OK) {
|
if(err.code != ERROR_OK) {
|
||||||
|
|
||||||
luaL_error(L, "Failed to set scene '%s'", sceneName);
|
luaL_error(L, "Failed to set scene '%s'", sceneName);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user