From 653ca9a72d560d9c13c3ef4d44d05ab683b9baa4 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Thu, 21 May 2026 22:07:56 -0500 Subject: [PATCH] PSP rendering fix --- .../entity/component/display/entitycamera.c | 2 +- .../entity/component/display/entitycamera.h | 2 +- .../component/display/entityrenderable.c | 11 ++ .../component/display/entityrenderable.h | 15 ++- src/dusk/entity/entitybase.h | 4 +- src/dusk/entity/entitymanager.c | 2 +- src/dusk/scene/initial/initialscene.c | 124 +++++++++++++----- src/dusk/scene/initial/initialscene.h | 9 +- src/dusk/scene/scene.c | 2 +- src/dusk/ui/uielement.c | 2 + src/duskgl/display/shader/shadergl.c | 21 ++- 11 files changed, 142 insertions(+), 52 deletions(-) diff --git a/src/dusk/entity/component/display/entitycamera.c b/src/dusk/entity/component/display/entitycamera.c index 50479512..332e1af9 100644 --- a/src/dusk/entity/component/display/entitycamera.c +++ b/src/dusk/entity/component/display/entitycamera.c @@ -66,7 +66,7 @@ entityid_t entityCameraGetCurrent(void) { entityid_t count = componentGetEntitiesWithComponent( COMPONENT_TYPE_CAMERA, camEnts, camComps ); - if(count == 0) return ENTITY_COUNT_MAX; + if(count == 0) return ENTITY_ID_INVALID; return camEnts[0]; } diff --git a/src/dusk/entity/component/display/entitycamera.h b/src/dusk/entity/component/display/entitycamera.h index be8c510d..d11be6ae 100644 --- a/src/dusk/entity/component/display/entitycamera.h +++ b/src/dusk/entity/component/display/entitycamera.h @@ -55,7 +55,7 @@ void entityCameraGetProjection( ); /** - * Returns the entity ID of the first active camera, or ENTITY_COUNT_MAX if + * Returns the entity ID of the first active camera, or ENTITY_ID_INVALID if * none are active. */ entityid_t entityCameraGetCurrent(void); diff --git a/src/dusk/entity/component/display/entityrenderable.c b/src/dusk/entity/component/display/entityrenderable.c index 3e2102b5..94877930 100644 --- a/src/dusk/entity/component/display/entityrenderable.c +++ b/src/dusk/entity/component/display/entityrenderable.c @@ -34,6 +34,17 @@ void entityRenderableDispose( } +void entityRenderableSetDraw( + const entityid_t entityId, + const componentid_t componentId, + errorret_t (*draw)(void) +) { + entityrenderable_t *r = componentGetData( + entityId, componentId, COMPONENT_TYPE_RENDERABLE + ); + r->draw = draw; +} + errorret_t entityRenderableDraw( const entityid_t entityId, const componentid_t componentId diff --git a/src/dusk/entity/component/display/entityrenderable.h b/src/dusk/entity/component/display/entityrenderable.h index 5213627e..f7442517 100644 --- a/src/dusk/entity/component/display/entityrenderable.h +++ b/src/dusk/entity/component/display/entityrenderable.h @@ -38,9 +38,22 @@ void entityRenderableDispose( const componentid_t componentId ); +/** + * Sets the draw callback for the entity's renderable component. + * + * @param entityId The entity to configure. + * @param componentId The renderable component of the entity. + * @param draw The draw callback to assign. + */ +void entityRenderableSetDraw( + const entityid_t entityId, + const componentid_t componentId, + errorret_t (*draw)(void) +); + /** * Draws the entity using its renderable component data. - * + * * @param entityId The entity to draw. * @param componentId The renderable component of the entity. * @return Any error state that happened. diff --git a/src/dusk/entity/entitybase.h b/src/dusk/entity/entitybase.h index a61f1170..c05979b6 100644 --- a/src/dusk/entity/entitybase.h +++ b/src/dusk/entity/entitybase.h @@ -8,8 +8,8 @@ #pragma once #include "dusk.h" -#define ENTITY_COUNT_MAX 20 -#define ENTITY_COMPONENT_COUNT_MAX 8 +#define ENTITY_COUNT_MAX 100 +#define ENTITY_COMPONENT_COUNT_MAX 24 #define ENTITY_ID_INVALID 0xFF #define COMPONENT_ID_INVALID 0xFF diff --git a/src/dusk/entity/entitymanager.c b/src/dusk/entity/entitymanager.c index 10269223..838ad389 100644 --- a/src/dusk/entity/entitymanager.c +++ b/src/dusk/entity/entitymanager.c @@ -16,7 +16,7 @@ void entityManagerInit(void) { memoryZero(&ENTITY_MANAGER, sizeof(entitymanager_t)); memorySet( ENTITY_MANAGER.entitiesWithComponent, COMPONENT_ID_INVALID, - sizeof(entityid_t) * COMPONENT_TYPE_COUNT * ENTITY_COUNT_MAX + sizeof(componentid_t) * COMPONENT_TYPE_COUNT * ENTITY_COUNT_MAX ); consolePrint( diff --git a/src/dusk/scene/initial/initialscene.c b/src/dusk/scene/initial/initialscene.c index 099fe21d..1f2ab71c 100644 --- a/src/dusk/scene/initial/initialscene.c +++ b/src/dusk/scene/initial/initialscene.c @@ -1,6 +1,6 @@ /** * Copyright (c) 2026 Dominic Masters - * + * * This software is released under the MIT License. * https://opensource.org/licenses/MIT */ @@ -9,58 +9,116 @@ #include "console/console.h" #include "display/spritebatch/spritebatch.h" #include "display/screen/screen.h" +#include "display/text/text.h" #include "entity/entitymanager.h" #include "input/input.h" -void initialSceneCubeUpdate(const entityid_t entityId) { - vec3 pos; - componentid_t posComp = entityGetComponent(entityId, COMPONENT_TYPE_POSITION); +#define INITIAL_SCENE_TEST_ENTITY_MAX (ENTITY_COUNT_MAX - 1) - vec2 movement; - inputAngle2D( - INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT, - INPUT_ACTION_DOWN, INPUT_ACTION_UP, - movement - ); - if(movement[0] == 0.0f && movement[1] == 0.0f) return; +static entityid_t cameraEntityId; +static componentid_t cameraCompId; +static entityid_t testEntities[INITIAL_SCENE_TEST_ENTITY_MAX]; +static uint8_t testEntityCount = 0; - const float_t speed = 1.0f; +static void initialSceneSpawnTestEntity(void) { + if(testEntityCount >= INITIAL_SCENE_TEST_ENTITY_MAX) return; - entityPositionGetLocalPosition(entityId, posComp, pos); - pos[0] += movement[0] * TIME.delta * speed; - pos[2] -= movement[1] * TIME.delta * speed; - entityPositionSetLocalPosition(entityId, posComp, pos); + entityid_t entity = entityManagerAdd(); + componentid_t posComp = entityAddComponent(entity, COMPONENT_TYPE_POSITION); + (void)entityAddComponent(entity, COMPONENT_TYPE_RENDERABLE); + + const int32_t cols = 20; + const float_t spacing = 1.5f; + int32_t col = testEntityCount % cols; + int32_t row = testEntityCount / cols; + vec3 pos = { + ((float_t)col - (cols - 1) * 0.5f) * spacing, + 0.0f, + (float_t)row * spacing + }; + entityPositionSetLocalPosition(entity, posComp, pos); + + testEntities[testEntityCount++] = entity; +} + +static void initialSceneUpdateCamera(void) { + if(testEntityCount == 0) return; + + float_t minX = FLT_MAX, maxX = -FLT_MAX; + float_t minZ = FLT_MAX, maxZ = -FLT_MAX; + + for(entityid_t i = 0; i < testEntityCount; i++) { + componentid_t posComp = entityGetComponent( + testEntities[i], COMPONENT_TYPE_POSITION + ); + if(posComp == COMPONENT_ID_INVALID) continue; + vec3 pos; + entityPositionGetLocalPosition(testEntities[i], posComp, pos); + if(pos[0] < minX) minX = pos[0]; + if(pos[0] > maxX) maxX = pos[0]; + if(pos[2] < minZ) minZ = pos[2]; + if(pos[2] > maxZ) maxZ = pos[2]; + } + + float_t centerX = (minX + maxX) * 0.5f; + float_t centerZ = (minZ + maxZ) * 0.5f; + float_t extentX = (maxX - minX) * 0.5f + 0.5f; + float_t extentZ = (maxZ - minZ) * 0.5f + 0.5f; + float_t extent = extentX > extentZ ? extentX : extentZ; + float_t dist = extent * 1.5f + 2.0f; + + vec3 target = { centerX, 0.0f, centerZ }; + vec3 eye = { centerX + dist, dist, centerZ + dist }; + vec3 up = { 0.0f, 1.0f, 0.0f }; + entityPositionLookAt(cameraEntityId, cameraCompId, eye, target, up); } void initialSceneInit(void) { consolePrint("Initial scene initialized"); + testEntityCount = 0; - entityid_t camera = entityManagerAdd(); - componentid_t camPos = entityAddComponent(camera, COMPONENT_TYPE_POSITION); - componentid_t camCam = entityAddComponent(camera, COMPONENT_TYPE_CAMERA); + cameraEntityId = entityManagerAdd(); + cameraCompId = entityAddComponent(cameraEntityId, COMPONENT_TYPE_POSITION); + (void)entityAddComponent(cameraEntityId, COMPONENT_TYPE_CAMERA); - // entitycamera_t *camData = (entitycamera_t*)entityGetComponent(camera, camCam); - - entityid_t cube = entityManagerAdd(); - (void)entityAddComponent(cube, COMPONENT_TYPE_POSITION); - componentid_t cubeDraw = entityAddComponent(cube, COMPONENT_TYPE_RENDERABLE); - entityUpdateAdd(cube, initialSceneCubeUpdate); - // entityrenderable_t *cubeDrawData = ( - // (entityrenderable_t*)entityGetComponent(cube, cubeDraw) - // ); - - // Look at the cube. vec3 eye, target, up; glm_vec3_zero(target); glm_vec3_copy((vec3){ 3.0f, 3.0f, 3.0f }, eye); glm_vec3_copy((vec3){ 0.0f, 1.0f, 0.0f }, up); - entityPositionLookAt(camera, camPos, eye, target, up); + entityPositionLookAt(cameraEntityId, cameraCompId, eye, target, up); + + for(int i = 0; i < 5; i++) initialSceneSpawnTestEntity(); } errorret_t initialSceneUpdate(void) { + if(inputPressed(INPUT_ACTION_ACCEPT)) { + for(int i = 0; i < 5; i++) initialSceneSpawnTestEntity(); + } + + if(inputPressed(INPUT_ACTION_CANCEL)) { + for(int i = 0; i < 5 && testEntityCount > 0; i++) { + entityDispose(testEntities[--testEntityCount]); + } + } + + initialSceneUpdateCamera(); + errorOk(); } -void initialSceneDispose(void) { +errorret_t initialSceneEntityCountDraw(void) { + char_t buf[32]; + snprintf(buf, sizeof(buf), "Entities: %u", (uint32_t)testEntityCount); + errorChain(textDraw( + 0, (float_t)(SCREEN.height - FONT_DEFAULT.tileset.tileHeight), + buf, COLOR_WHITE, + &FONT_DEFAULT + )); + return spriteBatchFlush(); +} -} \ No newline at end of file +void initialSceneDispose(void) { + testEntityCount = 0; + cameraEntityId = ENTITY_ID_INVALID; + cameraCompId = COMPONENT_ID_INVALID; +} diff --git a/src/dusk/scene/initial/initialscene.h b/src/dusk/scene/initial/initialscene.h index 371d25f6..5af45e4b 100644 --- a/src/dusk/scene/initial/initialscene.h +++ b/src/dusk/scene/initial/initialscene.h @@ -27,4 +27,11 @@ errorret_t initialSceneUpdate(void); /** * Initial scene disposer. */ -void initialSceneDispose(void); \ No newline at end of file +void initialSceneDispose(void); + +/** + * Draws the entity count UI label for the initial scene. + * + * @return Any error state that happened. + */ +errorret_t initialSceneEntityCountDraw(void); \ No newline at end of file diff --git a/src/dusk/scene/scene.c b/src/dusk/scene/scene.c index 32bd7ebf..195de3b0 100644 --- a/src/dusk/scene/scene.c +++ b/src/dusk/scene/scene.c @@ -108,7 +108,7 @@ errorret_t sceneRender(void) { for(entityid_t i = 0; i < entCount; i++) { entityid_t entityId = entities[i]; componentid_t renderableComp = components[i]; - + // Has position? componentid_t posComp = entityGetComponent( entityId, COMPONENT_TYPE_POSITION diff --git a/src/dusk/ui/uielement.c b/src/dusk/ui/uielement.c index 2a307f3c..7efdfdf7 100644 --- a/src/dusk/ui/uielement.c +++ b/src/dusk/ui/uielement.c @@ -12,6 +12,7 @@ #include "engine/engine.h" #include "ui/uitextbox.h" #include "ui/uifullbox.h" +#include "scene/initial/initialscene.h" uielement_t UI_ELEMENTS[] = { // Fullbox under: above scene, below system UI. @@ -22,6 +23,7 @@ uielement_t UI_ELEMENTS[] = { { .type = UI_ELEMENT_TYPE_NATIVE, .draw = consoleDraw }, { .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFPSDraw }, { .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiTextboxDraw }, + { .type = UI_ELEMENT_TYPE_NATIVE, .draw = initialSceneEntityCountDraw }, // Fullbox over: above absolutely everything. { .type = UI_ELEMENT_TYPE_NATIVE, .draw = uiFullboxOverDraw }, diff --git a/src/duskgl/display/shader/shadergl.c b/src/duskgl/display/shader/shadergl.c index 480527aa..58c956a8 100644 --- a/src/duskgl/display/shader/shadergl.c +++ b/src/duskgl/display/shader/shadergl.c @@ -393,19 +393,18 @@ errorret_t shaderDisposeGL(shadergl_t *shader) { errorChain(errorGLCheck()); } - if((SHADER_LEGACY.dirty & SHADER_LEGACY_DIRTY_VIEW) != 0) { + if( + (SHADER_LEGACY.dirty & (SHADER_LEGACY_DIRTY_VIEW | SHADER_LEGACY_DIRTY_MODEL)) != 0 + ) { glMatrixMode(GL_MODELVIEW); errorChain(errorGLCheck()); - glLoadIdentity(); - errorChain(errorGLCheck()); - glMultMatrixf((const GLfloat *)SHADER_LEGACY.boundShader->view); - errorChain(errorGLCheck()); - } - - if((SHADER_LEGACY.dirty & SHADER_LEGACY_DIRTY_MODEL) != 0) { - glMatrixMode(GL_MODELVIEW); - errorChain(errorGLCheck()); - glMultMatrixf((const GLfloat *)SHADER_LEGACY.boundShader->model); + mat4 viewModel; + glm_mat4_mul( + SHADER_LEGACY.boundShader->view, + SHADER_LEGACY.boundShader->model, + viewModel + ); + glLoadMatrixf((const GLfloat *)viewModel); errorChain(errorGLCheck()); }