Efficient loading of chunks now and PSP is slighty more optimized

This commit is contained in:
2026-06-30 20:00:34 -05:00
parent c0a3f2e16a
commit 55352805ee
16 changed files with 133 additions and 56 deletions
+7
View File
@@ -55,8 +55,15 @@ target_compile_definitions(${DUSK_BINARY_TARGET_NAME} PUBLIC
DUSK_DISPLAY_WIDTH=480 DUSK_DISPLAY_WIDTH=480
DUSK_DISPLAY_HEIGHT=272 DUSK_DISPLAY_HEIGHT=272
DUSK_THREAD_PTHREAD 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. # Postbuild, create .pbp file for PSP.
create_pbp_file( create_pbp_file(
TARGET "${DUSK_BINARY_TARGET_NAME}" TARGET "${DUSK_BINARY_TARGET_NAME}"
+1 -1
View File
@@ -6,7 +6,7 @@ fi
mkdir -p build-psp mkdir -p build-psp
cd 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) make -j$(nproc)
# psp-cmake -DDUSK_TARGET_SYSTEM=psp -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake -DBUILD_PRX=1 -DCMAKE_BUILD_TYPE=Debug .. # psp-cmake -DDUSK_TARGET_SYSTEM=psp -DCMAKE_TOOLCHAIN_FILE=$PSPDEV/psp/share/pspdev.cmake -DBUILD_PRX=1 -DCMAKE_BUILD_TYPE=Debug ..
# make # make
+6 -2
View File
@@ -33,8 +33,12 @@
#endif #endif
#endif #endif
#ifndef DUSK_DISPLAY_SCALE #ifndef DUSK_DISPLAY_SCALE_UI
#define DUSK_DISPLAY_SCALE 1 #define DUSK_DISPLAY_SCALE_UI 1
#endif
#ifndef DUSK_DISPLAY_SCALE_3D
#define DUSK_DISPLAY_SCALE_3D 1
#endif #endif
// Main Display Struct, platform-speicifc // Main Display Struct, platform-speicifc
+2 -1
View File
@@ -23,7 +23,8 @@ const screencropaspectinfo_t SCREEN_CROP_ASPECTS[SCREEN_CROP_ASPECT_COUNT] = {
errorret_t screenInit() { errorret_t screenInit() {
memoryZero(&SCREEN, sizeof(screen_t)); 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; SCREEN.background = COLOR_CORNFLOWER_BLUE;
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC #ifdef DUSK_DISPLAY_SIZE_DYNAMIC
+2 -1
View File
@@ -59,7 +59,8 @@ typedef enum {
// } screenscalemode_t; // } screenscalemode_t;
typedef struct { typedef struct {
int32_t scale; int32_t scaleUi;
int32_t scale3d;
screenmode_t mode; screenmode_t mode;
// screenscalemode_t scaleMode; // screenscalemode_t scaleMode;
+2
View File
@@ -19,6 +19,8 @@ typedef struct chunk_s {
chunkpos_t position; chunkpos_t position;
tile_t tiles[CHUNK_TILE_COUNT]; tile_t tiles[CHUNK_TILE_COUNT];
assetentry_t *dcfEntry;
uint8_t meshCount; uint8_t meshCount;
char_t meshNames[CHUNK_MESH_COUNT_MAX][CHUNK_MESH_NAME_MAX]; char_t meshNames[CHUNK_MESH_COUNT_MAX][CHUNK_MESH_NAME_MAX];
vec3 meshOffsets[CHUNK_MESH_COUNT_MAX]; vec3 meshOffsets[CHUNK_MESH_COUNT_MAX];
+60 -24
View File
@@ -12,6 +12,7 @@
#include "asset/loader/assetloader.h" #include "asset/loader/assetloader.h"
#include "rpg/entity/entity.h" #include "rpg/entity/entity.h"
#include "util/string.h" #include "util/string.h"
#include <unistd.h>
map_t MAP; 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++) { for(uint8_t m = 0; m < chunk->meshCount; m++) {
if(chunk->meshEntries[m] == NULL) continue; if(chunk->meshEntries[m] == NULL) continue;
assetUnlockEntry(chunk->meshEntries[m]); assetUnlockEntry(chunk->meshEntries[m]);
@@ -152,6 +158,7 @@ errorret_t mapChunkLoad(chunk_t *chunk) {
memorySet(chunk->entities, 0xFF, sizeof(chunk->entities)); memorySet(chunk->entities, 0xFF, sizeof(chunk->entities));
chunk->meshCount = 0; chunk->meshCount = 0;
chunk->dcfEntry = NULL;
char_t name[64]; char_t name[64];
stringFormat( stringFormat(
@@ -169,50 +176,79 @@ errorret_t mapChunkLoad(chunk_t *chunk) {
assetentry_t *entry = assetLock(name, ASSET_LOADER_TYPE_CHUNK, NULL); assetentry_t *entry = assetLock(name, ASSET_LOADER_TYPE_CHUNK, NULL);
assertNotNull(entry, "Failed to get chunk asset entry"); assertNotNull(entry, "Failed to get chunk asset entry");
chunk->dcfEntry = entry;
errorret_t ret = assetRequireLoaded(entry); errorOk();
if(errorIsNotOk(ret)) {
assetUnlockEntry(entry);
return ret;
} }
memoryCopy(chunk->tiles, entry->data.chunk.tiles, sizeof(chunk->tiles)); errorret_t mapWaitForChunks() {
uint8_t meshCount = entry->data.chunk.meshCount; bool_t anyPending;
do {
anyPending = false;
errorChain(assetUpdate());
for(chunkindex_t i = 0; i < MAP_CHUNK_COUNT; i++) {
chunk_t *chunk = &MAP.chunks[i];
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++) { for(uint8_t m = 0; m < meshCount; m++) {
stringCopy( stringCopy(
chunk->meshNames[m], chunk->meshNames[m],
entry->data.chunk.meshNames[m], chunk->dcfEntry->data.chunk.meshNames[m],
CHUNK_MESH_NAME_MAX CHUNK_MESH_NAME_MAX
); );
glm_vec3_copy(entry->data.chunk.meshOffsets[m], chunk->meshOffsets[m]); glm_vec3_copy(
chunk->dcfEntry->data.chunk.meshOffsets[m],
chunk->meshOffsets[m]
);
} }
assetUnlockEntry(entry); assetUnlockEntry(chunk->dcfEntry);
chunk->dcfEntry = NULL;
for(uint8_t m = 0; m < meshCount; m++) { for(uint8_t m = 0; m < meshCount; m++) {
assetentry_t *meshEntry = assetLock( chunk->meshEntries[m] = assetLock(
chunk->meshNames[m], ASSET_LOADER_TYPE_DMF, NULL chunk->meshNames[m], ASSET_LOADER_TYPE_DMF, NULL
); );
if(meshEntry == NULL) { if(chunk->meshEntries[m] == NULL) {
for(uint8_t j = 0; j < m; j++) { for(uint8_t j = 0; j < m; j++) {
assetUnlockEntry(chunk->meshEntries[j]); assetUnlockEntry(chunk->meshEntries[j]);
chunk->meshEntries[j] = NULL; chunk->meshEntries[j] = NULL;
} }
errorThrow("Failed to lock mesh: %s", chunk->meshNames[m]); 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; 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;
}
}
}
if(anyPending) usleep(1000);
} while(anyPending);
errorOk(); errorOk();
} }
+11 -1
View File
@@ -78,13 +78,23 @@ errorret_t mapPositionSet(const chunkpos_t newPos);
void mapChunkUnload(chunk_t* chunk); 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. * @param chunk The chunk to load.
* @return An error code. * @return An error code.
*/ */
errorret_t mapChunkLoad(chunk_t* chunk); 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. * Gets the index of a chunk, within the world, at the given position.
* *
+5 -4
View File
@@ -6,7 +6,8 @@
*/ */
#pragma once #pragma once
#include "dusk.h" #include "display/display.h"
#include "util/math.h"
#define TILE_SIZE_PIXELS 24 #define TILE_SIZE_PIXELS 24
@@ -16,9 +17,9 @@
#define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH) #define CHUNK_TILE_COUNT (CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH)
#define MAP_CHUNK_WIDTH 5 #define MAP_CHUNK_WIDTH mathCeilDiv(6, DUSK_DISPLAY_SCALE_3D)
#define MAP_CHUNK_HEIGHT 3 #define MAP_CHUNK_HEIGHT mathCeilDiv(4, DUSK_DISPLAY_SCALE_3D)
#define MAP_CHUNK_DEPTH 1 #define MAP_CHUNK_DEPTH 2
#define MAP_CHUNK_COUNT (MAP_CHUNK_WIDTH * MAP_CHUNK_HEIGHT * MAP_CHUNK_DEPTH) #define MAP_CHUNK_COUNT (MAP_CHUNK_WIDTH * MAP_CHUNK_HEIGHT * MAP_CHUNK_DEPTH)
#define ENTITY_COUNT 32 #define ENTITY_COUNT 32
+2
View File
@@ -77,6 +77,8 @@ errorret_t rpgUpdate(void) {
} }
#endif #endif
errorChain(mapWaitForChunks());
// TODO: Do not update if the scene is not the map scene? // TODO: Do not update if the scene is not the map scene?
mapUpdate(); mapUpdate();
+4 -2
View File
@@ -85,7 +85,7 @@ errorret_t sceneOverworldRender(scenedata_t *sceneData) {
// Camera Eye // Camera Eye
float_t pixelsPerUnit = TILE_SIZE_PIXELS; 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); float_t z = (worldH * 0.5f) / tanf(fov * 0.5f);
vec3 worldPosVec; vec3 worldPosVec;
rpgCameraGetPosition(worldPosVec); rpgCameraGetPosition(worldPosVec);
@@ -116,11 +116,13 @@ errorret_t sceneOverworldRender(scenedata_t *sceneData) {
spritebatchsprite_t sprite; spritebatchsprite_t sprite;
glm_vec3_copy(ent->renderPosition, sprite.min); 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_vec3_add(sprite.max, (vec3){ 1, 1, 0 }, sprite.max);
glm_vec2_copy((vec2){ 0, 0 }, sprite.uvMin); glm_vec2_copy((vec2){ 0, 0 }, sprite.uvMin);
glm_vec2_copy((vec2){ 1, 1 }, sprite.uvMax); glm_vec2_copy((vec2){ 1, 1 }, sprite.uvMax);
color_t color; color_t color;
switch(ent->direction) { switch(ent->direction) {
case ENTITY_DIR_NORTH: color = COLOR_YELLOW; break; case ENTITY_DIR_NORTH: color = COLOR_YELLOW; break;
+2 -2
View File
@@ -73,8 +73,8 @@ errorret_t sceneRender(void) {
errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, ident)); errorChain(shaderSetMatrix(&SHADER_UNLIT, SHADER_UNLIT_MODEL, ident));
glm_ortho( glm_ortho(
0.0f, (float_t)(SCREEN.width / SCREEN.scale), 0.0f, (float_t)(SCREEN.width / SCREEN.scaleUi),
(float_t)(SCREEN.height / SCREEN.scale), 0.0f, (float_t)(SCREEN.height / SCREEN.scaleUi), 0.0f,
0.1f, 100.0f, 0.1f, 100.0f,
proj proj
); );
+9
View File
@@ -46,6 +46,15 @@ uint32_t mathNextPowTwo(uint32_t value);
*/ */
#define mathClamp(x, lower, upper) (mathMin(upper, mathMax(lower, x))) #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. * Returns the absolute value of a number.
* *
+2 -1
View File
@@ -6,7 +6,8 @@
*/ */
#pragma once #pragma once
#define DUSK_DISPLAY_SCALE 2 #define DUSK_DISPLAY_SCALE_UI 2
#define DUSK_DISPLAY_SCALE_3D 2
#include "displaydolphin.h" #include "displaydolphin.h"
#define displayPlatformInit displayInitDolphin #define displayPlatformInit displayInitDolphin
+2 -1
View File
@@ -6,7 +6,8 @@
*/ */
#pragma once #pragma once
#define DUSK_DISPLAY_SCALE 2 #define DUSK_DISPLAY_SCALE_UI 1
#define DUSK_DISPLAY_SCALE_3D 2
#include "display/displaysdl2.h" #include "display/displaysdl2.h"
typedef displaysdl2_t displayplatform_t; typedef displaysdl2_t displayplatform_t;