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_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}"
+1 -1
View File
@@ -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"
docker run --rm -v "$(pwd):/workdir" dusk-psp /bin/bash -c "./scripts/build-psp.sh"
+1 -1
View File
@@ -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
+6 -2
View File
@@ -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
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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;
+2
View File
@@ -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];
+74 -38
View File
@@ -12,6 +12,7 @@
#include "asset/loader/assetloader.h"
#include "rpg/entity/entity.h"
#include "util/string.h"
#include <unistd.h>
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();
}
+12 -2
View File
@@ -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.
*
+5 -4
View File
@@ -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
+2
View File
@@ -77,6 +77,8 @@ errorret_t rpgUpdate(void) {
}
#endif
errorChain(mapWaitForChunks());
// TODO: Do not update if the scene is not the map scene?
mapUpdate();
+4 -2
View File
@@ -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;
+2 -2
View File
@@ -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
);
+9
View File
@@ -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.
*
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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;