From 55352805eeb68e5e13a1325a2cc06c2314211318 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Tue, 30 Jun 2026 20:00:34 -0500 Subject: [PATCH] Efficient loading of chunks now and PSP is slighty more optimized --- cmake/targets/psp.cmake | 7 ++ scripts/build-psp-docker.sh | 2 +- scripts/build-psp.sh | 2 +- src/dusk/display/display.h | 8 +- src/dusk/display/screen/screen.c | 3 +- src/dusk/display/screen/screen.h | 3 +- src/dusk/rpg/overworld/chunk.h | 2 + src/dusk/rpg/overworld/map.c | 112 ++++++++++++++-------- src/dusk/rpg/overworld/map.h | 14 ++- src/dusk/rpg/overworld/worldpos.h | 9 +- src/dusk/rpg/rpg.c | 2 + src/dusk/scene/overworld/sceneoverworld.c | 6 +- src/dusk/scene/scene.c | 4 +- src/dusk/util/math.h | 9 ++ src/duskdolphin/display/displayplatform.h | 3 +- src/duskpsp/display/displayplatform.h | 3 +- 16 files changed, 133 insertions(+), 56 deletions(-) diff --git a/cmake/targets/psp.cmake b/cmake/targets/psp.cmake index 242791d0..c1b33fda 100644 --- a/cmake/targets/psp.cmake +++ b/cmake/targets/psp.cmake @@ -55,8 +55,15 @@ target_compile_definitions(${DUSK_BINARY_TARGET_NAME} PUBLIC DUSK_DISPLAY_WIDTH=480 DUSK_DISPLAY_HEIGHT=272 DUSK_THREAD_PTHREAD + DUSK_TIME_DYNAMIC ) +if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + target_compile_definitions(${DUSK_BINARY_TARGET_NAME} PUBLIC + DUSK_ASSERTIONS_FAKED + ) +endif() + # Postbuild, create .pbp file for PSP. create_pbp_file( TARGET "${DUSK_BINARY_TARGET_NAME}" diff --git a/scripts/build-psp-docker.sh b/scripts/build-psp-docker.sh index 06cfd456..348fdce2 100755 --- a/scripts/build-psp-docker.sh +++ b/scripts/build-psp-docker.sh @@ -1,3 +1,3 @@ #!/bin/bash docker build -t dusk-psp -f docker/psp/Dockerfile . -docker run --rm -v "$(pwd):/workdir" dusk-psp /bin/bash -c "./scripts/build-psp.sh" \ No newline at end of file +docker run --rm -v "$(pwd):/workdir" dusk-psp /bin/bash -c "./scripts/build-psp.sh" \ No newline at end of file diff --git a/scripts/build-psp.sh b/scripts/build-psp.sh index 7cfa5a66..cef02d6a 100755 --- a/scripts/build-psp.sh +++ b/scripts/build-psp.sh @@ -6,7 +6,7 @@ fi mkdir -p build-psp cd build-psp -psp-cmake -DDUSK_TARGET_SYSTEM=psp -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake -DBUILD_PRX=1 .. +psp-cmake -DDUSK_TARGET_SYSTEM=psp -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake -DBUILD_PRX=1 .. CMAKE_BUILD_TYPE=Release make -j$(nproc) # psp-cmake -DDUSK_TARGET_SYSTEM=psp -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake -DBUILD_PRX=1 -DCMAKE_BUILD_TYPE=Debug .. # make \ No newline at end of file diff --git a/src/dusk/display/display.h b/src/dusk/display/display.h index e5bfde9a..4665f550 100644 --- a/src/dusk/display/display.h +++ b/src/dusk/display/display.h @@ -33,8 +33,12 @@ #endif #endif -#ifndef DUSK_DISPLAY_SCALE - #define DUSK_DISPLAY_SCALE 1 +#ifndef DUSK_DISPLAY_SCALE_UI + #define DUSK_DISPLAY_SCALE_UI 1 +#endif + +#ifndef DUSK_DISPLAY_SCALE_3D + #define DUSK_DISPLAY_SCALE_3D 1 #endif // Main Display Struct, platform-speicifc diff --git a/src/dusk/display/screen/screen.c b/src/dusk/display/screen/screen.c index 2bdf1082..c5437265 100644 --- a/src/dusk/display/screen/screen.c +++ b/src/dusk/display/screen/screen.c @@ -23,7 +23,8 @@ const screencropaspectinfo_t SCREEN_CROP_ASPECTS[SCREEN_CROP_ASPECT_COUNT] = { errorret_t screenInit() { memoryZero(&SCREEN, sizeof(screen_t)); - SCREEN.scale = DUSK_DISPLAY_SCALE; + SCREEN.scaleUi = DUSK_DISPLAY_SCALE_UI; + SCREEN.scale3d = DUSK_DISPLAY_SCALE_3D; SCREEN.background = COLOR_CORNFLOWER_BLUE; #ifdef DUSK_DISPLAY_SIZE_DYNAMIC diff --git a/src/dusk/display/screen/screen.h b/src/dusk/display/screen/screen.h index 09e6bab3..8d28536f 100644 --- a/src/dusk/display/screen/screen.h +++ b/src/dusk/display/screen/screen.h @@ -59,7 +59,8 @@ typedef enum { // } screenscalemode_t; typedef struct { - int32_t scale; + int32_t scaleUi; + int32_t scale3d; screenmode_t mode; // screenscalemode_t scaleMode; diff --git a/src/dusk/rpg/overworld/chunk.h b/src/dusk/rpg/overworld/chunk.h index 4aa602b2..d15bdcac 100644 --- a/src/dusk/rpg/overworld/chunk.h +++ b/src/dusk/rpg/overworld/chunk.h @@ -19,6 +19,8 @@ typedef struct chunk_s { chunkpos_t position; tile_t tiles[CHUNK_TILE_COUNT]; + assetentry_t *dcfEntry; + uint8_t meshCount; char_t meshNames[CHUNK_MESH_COUNT_MAX][CHUNK_MESH_NAME_MAX]; vec3 meshOffsets[CHUNK_MESH_COUNT_MAX]; diff --git a/src/dusk/rpg/overworld/map.c b/src/dusk/rpg/overworld/map.c index bbccccaa..a11bdcf0 100644 --- a/src/dusk/rpg/overworld/map.c +++ b/src/dusk/rpg/overworld/map.c @@ -12,6 +12,7 @@ #include "asset/loader/assetloader.h" #include "rpg/entity/entity.h" #include "util/string.h" +#include map_t MAP; @@ -139,6 +140,11 @@ void mapChunkUnload(chunk_t *chunk) { } } + if(chunk->dcfEntry != NULL) { + assetUnlockEntry(chunk->dcfEntry); + chunk->dcfEntry = NULL; + } + for(uint8_t m = 0; m < chunk->meshCount; m++) { if(chunk->meshEntries[m] == NULL) continue; assetUnlockEntry(chunk->meshEntries[m]); @@ -152,6 +158,7 @@ errorret_t mapChunkLoad(chunk_t *chunk) { memorySet(chunk->entities, 0xFF, sizeof(chunk->entities)); chunk->meshCount = 0; + chunk->dcfEntry = NULL; char_t name[64]; stringFormat( @@ -169,50 +176,79 @@ errorret_t mapChunkLoad(chunk_t *chunk) { assetentry_t *entry = assetLock(name, ASSET_LOADER_TYPE_CHUNK, NULL); assertNotNull(entry, "Failed to get chunk asset entry"); + chunk->dcfEntry = entry; + errorOk(); +} - errorret_t ret = assetRequireLoaded(entry); - if(errorIsNotOk(ret)) { - assetUnlockEntry(entry); - return ret; - } +errorret_t mapWaitForChunks() { + bool_t anyPending; + do { + anyPending = false; + errorChain(assetUpdate()); - memoryCopy(chunk->tiles, entry->data.chunk.tiles, sizeof(chunk->tiles)); - uint8_t meshCount = entry->data.chunk.meshCount; - for(uint8_t m = 0; m < meshCount; m++) { - stringCopy( - chunk->meshNames[m], - entry->data.chunk.meshNames[m], - CHUNK_MESH_NAME_MAX - ); - glm_vec3_copy(entry->data.chunk.meshOffsets[m], chunk->meshOffsets[m]); - } - assetUnlockEntry(entry); + for(chunkindex_t i = 0; i < MAP_CHUNK_COUNT; i++) { + chunk_t *chunk = &MAP.chunks[i]; - for(uint8_t m = 0; m < meshCount; m++) { - assetentry_t *meshEntry = assetLock( - chunk->meshNames[m], ASSET_LOADER_TYPE_DMF, NULL - ); - if(meshEntry == NULL) { - for(uint8_t j = 0; j < m; j++) { - assetUnlockEntry(chunk->meshEntries[j]); - chunk->meshEntries[j] = NULL; + if(chunk->dcfEntry != NULL) { + assetentrystate_t state = chunk->dcfEntry->state; + + if(state == ASSET_ENTRY_STATE_LOADED) { + uint8_t meshCount = chunk->dcfEntry->data.chunk.meshCount; + memoryCopy( + chunk->tiles, + chunk->dcfEntry->data.chunk.tiles, + sizeof(chunk->tiles) + ); + for(uint8_t m = 0; m < meshCount; m++) { + stringCopy( + chunk->meshNames[m], + chunk->dcfEntry->data.chunk.meshNames[m], + CHUNK_MESH_NAME_MAX + ); + glm_vec3_copy( + chunk->dcfEntry->data.chunk.meshOffsets[m], + chunk->meshOffsets[m] + ); + } + assetUnlockEntry(chunk->dcfEntry); + chunk->dcfEntry = NULL; + + for(uint8_t m = 0; m < meshCount; m++) { + chunk->meshEntries[m] = assetLock( + chunk->meshNames[m], ASSET_LOADER_TYPE_DMF, NULL + ); + if(chunk->meshEntries[m] == NULL) { + for(uint8_t j = 0; j < m; j++) { + assetUnlockEntry(chunk->meshEntries[j]); + chunk->meshEntries[j] = NULL; + } + errorThrow("Failed to lock mesh: %s", chunk->meshNames[m]); + } + } + chunk->meshCount = meshCount; + anyPending = true; + + } else if(state == ASSET_ENTRY_STATE_ERROR) { + assetUnlockEntry(chunk->dcfEntry); + chunk->dcfEntry = NULL; + memorySet(chunk->tiles, TILE_SHAPE_GROUND, sizeof(chunk->tiles)); + } else { + anyPending = true; + } + continue; + } + + for(uint8_t m = 0; m < chunk->meshCount; m++) { + if(chunk->meshEntries[m] == NULL) continue; + if(chunk->meshEntries[m]->state != ASSET_ENTRY_STATE_LOADED) { + anyPending = true; + break; + } } - errorThrow("Failed to lock mesh: %s", chunk->meshNames[m]); } - ret = assetRequireLoaded(meshEntry); - if(errorIsNotOk(ret)) { - assetUnlockEntry(meshEntry); - for(uint8_t j = 0; j < m; j++) { - assetUnlockEntry(chunk->meshEntries[j]); - chunk->meshEntries[j] = NULL; - } - return ret; - } - - chunk->meshEntries[m] = meshEntry; - } - chunk->meshCount = meshCount; + if(anyPending) usleep(1000); + } while(anyPending); errorOk(); } diff --git a/src/dusk/rpg/overworld/map.h b/src/dusk/rpg/overworld/map.h index 87f44e7d..0d89d94f 100644 --- a/src/dusk/rpg/overworld/map.h +++ b/src/dusk/rpg/overworld/map.h @@ -78,13 +78,23 @@ errorret_t mapPositionSet(const chunkpos_t newPos); void mapChunkUnload(chunk_t* chunk); /** - * Loads a chunk. - * + * Loads a chunk. Starts async loading without blocking; call + * mapWaitForChunks() to block until all pending chunks are ready. + * * @param chunk The chunk to load. * @return An error code. */ errorret_t mapChunkLoad(chunk_t* chunk); +/** + * Blocks the calling thread until every chunk in the active window has + * fully loaded its DCF data and all referenced DMF meshes. Intended to + * be called once at the start of each RPG update tick. + * + * @return An error code. + */ +errorret_t mapWaitForChunks(); + /** * Gets the index of a chunk, within the world, at the given position. * diff --git a/src/dusk/rpg/overworld/worldpos.h b/src/dusk/rpg/overworld/worldpos.h index 30430a80..dc8bd251 100644 --- a/src/dusk/rpg/overworld/worldpos.h +++ b/src/dusk/rpg/overworld/worldpos.h @@ -6,7 +6,8 @@ */ #pragma once -#include "dusk.h" +#include "display/display.h" +#include "util/math.h" #define TILE_SIZE_PIXELS 24 @@ -16,9 +17,9 @@ #define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH) -#define MAP_CHUNK_WIDTH 5 -#define MAP_CHUNK_HEIGHT 3 -#define MAP_CHUNK_DEPTH 1 +#define MAP_CHUNK_WIDTH mathCeilDiv(6, DUSK_DISPLAY_SCALE_3D) +#define MAP_CHUNK_HEIGHT mathCeilDiv(4, DUSK_DISPLAY_SCALE_3D) +#define MAP_CHUNK_DEPTH 2 #define MAP_CHUNK_COUNT (MAP_CHUNK_WIDTH * MAP_CHUNK_HEIGHT * MAP_CHUNK_DEPTH) #define ENTITY_COUNT 32 diff --git a/src/dusk/rpg/rpg.c b/src/dusk/rpg/rpg.c index a9448dd0..c29c8cde 100644 --- a/src/dusk/rpg/rpg.c +++ b/src/dusk/rpg/rpg.c @@ -77,6 +77,8 @@ errorret_t rpgUpdate(void) { } #endif + errorChain(mapWaitForChunks()); + // TODO: Do not update if the scene is not the map scene? mapUpdate(); diff --git a/src/dusk/scene/overworld/sceneoverworld.c b/src/dusk/scene/overworld/sceneoverworld.c index 540c4010..48e189a9 100644 --- a/src/dusk/scene/overworld/sceneoverworld.c +++ b/src/dusk/scene/overworld/sceneoverworld.c @@ -85,7 +85,7 @@ errorret_t sceneOverworldRender(scenedata_t *sceneData) { // Camera Eye float_t pixelsPerUnit = TILE_SIZE_PIXELS; - float_t worldH = (float_t)(SCREEN.height / SCREEN.scale) / pixelsPerUnit; + float_t worldH = (float_t)(SCREEN.height / SCREEN.scale3d) / pixelsPerUnit; float_t z = (worldH * 0.5f) / tanf(fov * 0.5f); vec3 worldPosVec; rpgCameraGetPosition(worldPosVec); @@ -116,11 +116,13 @@ errorret_t sceneOverworldRender(scenedata_t *sceneData) { spritebatchsprite_t sprite; glm_vec3_copy(ent->renderPosition, sprite.min); - glm_vec3_copy(ent->renderPosition, sprite.max); + glm_vec3_add(sprite.min, (vec3){ 0, 0, 0.05f }, sprite.min);// Stop Fight + glm_vec3_copy(sprite.min, sprite.max); glm_vec3_add(sprite.max, (vec3){ 1, 1, 0 }, sprite.max); glm_vec2_copy((vec2){ 0, 0 }, sprite.uvMin); glm_vec2_copy((vec2){ 1, 1 }, sprite.uvMax); + color_t color; switch(ent->direction) { case ENTITY_DIR_NORTH: color = COLOR_YELLOW; break; diff --git a/src/dusk/scene/scene.c b/src/dusk/scene/scene.c index e7d17d44..f078a8f7 100644 --- a/src/dusk/scene/scene.c +++ b/src/dusk/scene/scene.c @@ -73,8 +73,8 @@ errorret_t sceneRender(void) { errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, ident)); glm_ortho( - 0.0f, (float_t)(SCREEN.width / SCREEN.scale), - (float_t)(SCREEN.height / SCREEN.scale), 0.0f, + 0.0f, (float_t)(SCREEN.width / SCREEN.scaleUi), + (float_t)(SCREEN.height / SCREEN.scaleUi), 0.0f, 0.1f, 100.0f, proj ); diff --git a/src/dusk/util/math.h b/src/dusk/util/math.h index 53be2024..80239eca 100644 --- a/src/dusk/util/math.h +++ b/src/dusk/util/math.h @@ -46,6 +46,15 @@ uint32_t mathNextPowTwo(uint32_t value); */ #define mathClamp(x, lower, upper) (mathMin(upper, mathMax(lower, x))) +/** + * Integer ceiling division: ceil(n / d) using only integer arithmetic. + * + * @param n The dividend. + * @param d The divisor. + * @return The ceiling of n divided by d. + */ +#define mathCeilDiv(n, d) (((n) + (d) - 1) / (d)) + /** * Returns the absolute value of a number. * diff --git a/src/duskdolphin/display/displayplatform.h b/src/duskdolphin/display/displayplatform.h index d1db4e67..dc56a9d9 100644 --- a/src/duskdolphin/display/displayplatform.h +++ b/src/duskdolphin/display/displayplatform.h @@ -6,7 +6,8 @@ */ #pragma once -#define DUSK_DISPLAY_SCALE 2 +#define DUSK_DISPLAY_SCALE_UI 2 +#define DUSK_DISPLAY_SCALE_3D 2 #include "displaydolphin.h" #define displayPlatformInit displayInitDolphin diff --git a/src/duskpsp/display/displayplatform.h b/src/duskpsp/display/displayplatform.h index c13ba140..e243536d 100644 --- a/src/duskpsp/display/displayplatform.h +++ b/src/duskpsp/display/displayplatform.h @@ -6,7 +6,8 @@ */ #pragma once -#define DUSK_DISPLAY_SCALE 2 +#define DUSK_DISPLAY_SCALE_UI 1 +#define DUSK_DISPLAY_SCALE_3D 2 #include "display/displaysdl2.h" typedef displaysdl2_t displayplatform_t;