From 2451d73a7cecb6d16d3e32daa5093811c601301d Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 17 Apr 2026 23:49:39 -0500 Subject: [PATCH] Improved Wii aspect ratio significantly --- src/dusk/display/display.c | 2 +- src/dusk/display/framebuffer/framebuffer.c | 11 ++++ src/dusk/display/framebuffer/framebuffer.h | 10 ++++ src/dusk/display/screen/screen.c | 8 +-- src/dusk/engine/engine.c | 54 +++++++++---------- .../display/framebuffer/framebufferdolphin.c | 18 ++++++- .../display/framebuffer/framebufferdolphin.h | 9 ++++ .../display/framebuffer/framebufferplatform.h | 3 +- .../display/shader/shaderdolphin.c | 15 +++--- src/duskdolphin/system/systemdolphin.c | 8 +++ src/duskdolphin/system/systemdolphin.h | 27 +++++++++- 11 files changed, 122 insertions(+), 43 deletions(-) diff --git a/src/dusk/display/display.c b/src/dusk/display/display.c index 0cab3c60..644f1d61 100644 --- a/src/dusk/display/display.c +++ b/src/dusk/display/display.c @@ -64,7 +64,7 @@ errorret_t displayInit(void) { glm_perspective( glm_rad(45.0f), - (float_t)SCREEN.width / (float_t)SCREEN.height, + SCREEN.aspect, 0.1f, 100.0f, proj diff --git a/src/dusk/display/framebuffer/framebuffer.c b/src/dusk/display/framebuffer/framebuffer.c index f7ef5444..12ba40a2 100644 --- a/src/dusk/display/framebuffer/framebuffer.c +++ b/src/dusk/display/framebuffer/framebuffer.c @@ -40,6 +40,17 @@ uint32_t frameBufferGetHeight(const framebuffer_t *framebuffer) { return frameBufferPlatformGetHeight(framebuffer); } +float_t frameBufferGetAspect(const framebuffer_t *framebuffer) { + #ifdef frameBufferPlatformGetAspect + return frameBufferPlatformGetAspect(framebuffer); + #endif + + uint32_t width = frameBufferGetWidth(framebuffer); + uint32_t height = frameBufferGetHeight(framebuffer); + if(height == 0) return 1.0f; // Avoid divide by zero, just return 1:1 aspect. + return (float_t)width / (float_t)height; +} + void frameBufferClear(const uint8_t flags, const color_t color) { frameBufferPlatformClear(flags, color); } diff --git a/src/dusk/display/framebuffer/framebuffer.h b/src/dusk/display/framebuffer/framebuffer.h index 033948ee..3670e437 100644 --- a/src/dusk/display/framebuffer/framebuffer.h +++ b/src/dusk/display/framebuffer/framebuffer.h @@ -58,6 +58,16 @@ uint32_t frameBufferGetWidth(const framebuffer_t *framebuffer); */ uint32_t frameBufferGetHeight(const framebuffer_t *framebuffer); +/** + * Returns the aspect ratio of the framebuffer. This is ALMOST always just + * the width / height, however some platforms may choose to override this if + * they have stretched styled back buffers, e.g. 640x480 stretched. + * + * @param framebuffer The framebuffer to get the aspect ratio of. + * @return The aspect ratio of the framebuffer. + */ +float_t frameBufferGetAspect(const framebuffer_t *framebuffer); + /** * Binds the framebuffer for rendering, or the backbuffer if the framebuffer * provided is NULL. diff --git a/src/dusk/display/screen/screen.c b/src/dusk/display/screen/screen.c index 3c45fe9b..88121925 100644 --- a/src/dusk/display/screen/screen.c +++ b/src/dusk/display/screen/screen.c @@ -52,7 +52,7 @@ errorret_t screenBind() { // Screen mode backbuffer uses the full display size SCREEN.width = frameBufferGetWidth(FRAMEBUFFER_BOUND); SCREEN.height = frameBufferGetHeight(FRAMEBUFFER_BOUND); - SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height; + SCREEN.aspect = frameBufferGetAspect(FRAMEBUFFER_BOUND); // No needd for a framebuffer. #ifdef DUSK_DISPLAY_SIZE_DYNAMIC @@ -100,8 +100,7 @@ errorret_t screenBind() { int32_t fbWidth, fbHeight; fbWidth = frameBufferGetWidth(FRAMEBUFFER_BOUND); fbHeight = frameBufferGetHeight(FRAMEBUFFER_BOUND); - - float_t currentAspect = (float_t)fbWidth / (float_t)fbHeight; + float_t currentAspect = frameBufferGetAspect(FRAMEBUFFER_BOUND); if(currentAspect == SCREEN.aspectRatio.ratio) { // No need to use framebuffer. SCREEN.width = fbWidth; @@ -129,13 +128,14 @@ errorret_t screenBind() { if(SCREEN.framebufferReady) { // Is current framebuffer the correct size? int32_t curFbWidth, curFbHeight; + float_t curFbAspect = frameBufferGetAspect(&SCREEN.framebuffer); curFbWidth = frameBufferGetWidth(&SCREEN.framebuffer); curFbHeight = frameBufferGetHeight(&SCREEN.framebuffer); if(curFbWidth == newFbWidth && curFbHeight == newFbHeight) { // Correct size, nothing to do. SCREEN.width = newFbWidth; SCREEN.height = newFbHeight; - SCREEN.aspect = (float_t)SCREEN.width / (float_t)SCREEN.height; + SCREEN.aspect = curFbAspect; errorChain(frameBufferBind(&SCREEN.framebuffer)); errorOk(); } diff --git a/src/dusk/engine/engine.c b/src/dusk/engine/engine.c index 954e3c30..55181161 100644 --- a/src/dusk/engine/engine.c +++ b/src/dusk/engine/engine.c @@ -113,8 +113,8 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { errorChain(networkInit()); errorChain(gameInit()); - printf("Init done, going to queue online in 3 seconds...\n"); - onlineSwapTime = TIME.time + 3.0f; + // printf("Init done, going to queue online in 3 seconds...\n"); + // onlineSwapTime = TIME.time + 3.0f; // Camera entityid_t cam = entityManagerAdd(); @@ -130,35 +130,35 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) { entityCameraSetZFar(cam, camCam, 100.0f); // Floor - entityid_t floorEnt = entityManagerAdd(); - componentid_t floorPos = entityAddComponent(floorEnt, COMPONENT_TYPE_POSITION); - componentid_t floorMesh = entityAddComponent(floorEnt, COMPONENT_TYPE_MESH); - componentid_t floorMat = entityAddComponent(floorEnt, COMPONENT_TYPE_MATERIAL); - componentid_t floorPhys = entityAddComponent(floorEnt, COMPONENT_TYPE_PHYSICS); + // entityid_t floorEnt = entityManagerAdd(); + // componentid_t floorPos = entityAddComponent(floorEnt, COMPONENT_TYPE_POSITION); + // componentid_t floorMesh = entityAddComponent(floorEnt, COMPONENT_TYPE_MESH); + // componentid_t floorMat = entityAddComponent(floorEnt, COMPONENT_TYPE_MATERIAL); + // componentid_t floorPhys = entityAddComponent(floorEnt, COMPONENT_TYPE_PHYSICS); - entityPositionSetPosition(floorEnt, floorPos, (vec3){ -5.0f, 0.0f, -5.0f }); - entityPositionSetScale(floorEnt, floorPos, (vec3){ 10.0f, 1.0f, 10.0f }); - entityMeshSetMesh(floorEnt, floorMesh, &PLANE_MESH_SIMPLE); - entityMaterialGetShaderMaterial(floorEnt, floorMat)->unlit.color = COLOR_GREEN; + // entityPositionSetPosition(floorEnt, floorPos, (vec3){ -5.0f, 0.0f, -5.0f }); + // entityPositionSetScale(floorEnt, floorPos, (vec3){ 10.0f, 1.0f, 10.0f }); + // entityMeshSetMesh(floorEnt, floorMesh, &PLANE_MESH_SIMPLE); + // entityMaterialGetShaderMaterial(floorEnt, floorMat)->unlit.color = COLOR_GREEN; - entityphysics_t *floorPhysData = entityPhysicsGet(floorEnt, floorPhys); - floorPhysData->type = PHYSICS_BODY_STATIC; - floorPhysData->shape.type = PHYSICS_SHAPE_PLANE; - floorPhysData->shape.data.plane.normal[0] = 0.0f; - floorPhysData->shape.data.plane.normal[1] = 1.0f; - floorPhysData->shape.data.plane.normal[2] = 0.0f; - floorPhysData->shape.data.plane.distance = 0.0f; + // entityphysics_t *floorPhysData = entityPhysicsGet(floorEnt, floorPhys); + // floorPhysData->type = PHYSICS_BODY_STATIC; + // floorPhysData->shape.type = PHYSICS_SHAPE_PLANE; + // floorPhysData->shape.data.plane.normal[0] = 0.0f; + // floorPhysData->shape.data.plane.normal[1] = 1.0f; + // floorPhysData->shape.data.plane.normal[2] = 0.0f; + // floorPhysData->shape.data.plane.distance = 0.0f; - /* ---- Dynamic box ---- */ + // Box phBoxEnt = entityManagerAdd(); componentid_t boxPos = entityAddComponent(phBoxEnt, COMPONENT_TYPE_POSITION); componentid_t boxMesh = entityAddComponent(phBoxEnt, COMPONENT_TYPE_MESH); componentid_t boxMat = entityAddComponent(phBoxEnt, COMPONENT_TYPE_MATERIAL); - phBoxPhys = entityAddComponent(phBoxEnt, COMPONENT_TYPE_PHYSICS); + // phBoxPhys = entityAddComponent(phBoxEnt, COMPONENT_TYPE_PHYSICS); entityMeshSetMesh(phBoxEnt, boxMesh, &CUBE_MESH_SIMPLE); entityMaterialGetShaderMaterial(phBoxEnt, boxMat)->unlit.color = COLOR_RED; - entityPositionSetPosition(phBoxEnt, boxPos, (vec3){ 0.0f, 4.0f, 0.0f }); + entityPositionSetPosition(phBoxEnt, boxPos, (vec3){ 0.0f, 0.0f, 0.0f }); /* Run the init script. */ scriptcontext_t ctx; @@ -178,12 +178,12 @@ errorret_t engineUpdate(void) { uiUpdate(); errorChain(sceneUpdate()); - /* Reset the box to its start position on demand. */ - if(inputIsDown(INPUT_ACTION_ACCEPT)) { - componentid_t posComp = entityGetComponent(phBoxEnt, COMPONENT_TYPE_POSITION); - entityPositionSetPosition(phBoxEnt, posComp, (vec3){ 0.0f, 4.0f, 0.0f }); - entityPhysicsSetVelocity(phBoxEnt, phBoxPhys, (vec3){ 0.0f, 0.0f, 0.0f }); - } + // /* Reset the box to its start position on demand. */ + // if(inputIsDown(INPUT_ACTION_ACCEPT)) { + // componentid_t posComp = entityGetComponent(phBoxEnt, COMPONENT_TYPE_POSITION); + // entityPositionSetPosition(phBoxEnt, posComp, (vec3){ 0.0f, 4.0f, 0.0f }); + // entityPhysicsSetVelocity(phBoxEnt, phBoxPhys, (vec3){ 0.0f, 0.0f, 0.0f }); + // } /* Step physics: positions are updated directly on POSITION components. */ physicsManagerUpdate(); diff --git a/src/duskdolphin/display/framebuffer/framebufferdolphin.c b/src/duskdolphin/display/framebuffer/framebufferdolphin.c index 34e48b37..42860c31 100644 --- a/src/duskdolphin/display/framebuffer/framebufferdolphin.c +++ b/src/duskdolphin/display/framebuffer/framebufferdolphin.c @@ -8,6 +8,7 @@ #include "display/framebuffer/framebuffer.h" #include "display/display.h" #include "assert/assert.h" +#include "system/systemdolphin.h" errorret_t frameBufferInitBackBufferDolphin(void) { errorOk(); @@ -15,16 +16,29 @@ errorret_t frameBufferInitBackBufferDolphin(void) { uint32_t frameBufferGetWidthDolphin(const framebufferdolphin_t *framebuffer) { assertNotNull(framebuffer, "Cannot get width of NULL framebuffer."); - return DISPLAY.screenMode->fbWidth; } uint32_t frameBufferGetHeightDolphin(const framebufferdolphin_t *framebuffer) { assertNotNull(framebuffer, "Cannot get height of NULL framebuffer."); - return DISPLAY.screenMode->efbHeight; } +float_t frameBufferGetAspectDolphin(const framebufferdolphin_t *framebuffer) { + assertNotNull(framebuffer, "Cannot get aspect of NULL framebuffer."); + switch(systemGetAspectRatioDolphin()) { + case CONF_ASPECT_16_9: + return 16.0f / 9.0f; + case CONF_ASPECT_4_3: + return 4.0f / 3.0f; + default: + return ( + (float_t)DISPLAY.screenMode->fbWidth / + (float_t)DISPLAY.screenMode->efbHeight + ); + } +} + errorret_t frameBufferBindDolphin(framebufferdolphin_t *framebuffer) { assertNotNull(framebuffer, "Cannot bind NULL framebuffer."); assertTrue( diff --git a/src/duskdolphin/display/framebuffer/framebufferdolphin.h b/src/duskdolphin/display/framebuffer/framebufferdolphin.h index 258a05af..fd6616ec 100644 --- a/src/duskdolphin/display/framebuffer/framebufferdolphin.h +++ b/src/duskdolphin/display/framebuffer/framebufferdolphin.h @@ -38,6 +38,15 @@ uint32_t frameBufferGetWidthDolphin(const framebufferdolphin_t *framebuffer); */ uint32_t frameBufferGetHeightDolphin(const framebufferdolphin_t *framebuffer); +/** + * Gets the aspect ratio of the framebuffer. (Dolphin implementation). Taking + * the Wii aspect setting into consideration. + * + * @param framebuffer The framebuffer to get the aspect ratio of. + * @return The aspect ratio of the framebuffer. + */ +float_t frameBufferGetAspectDolphin(const framebufferdolphin_t *framebuffer); + /** * Binds the framebuffer for rendering. (Dolphin implementation). * diff --git a/src/duskdolphin/display/framebuffer/framebufferplatform.h b/src/duskdolphin/display/framebuffer/framebufferplatform.h index 65bad6bb..3e491f8a 100644 --- a/src/duskdolphin/display/framebuffer/framebufferplatform.h +++ b/src/duskdolphin/display/framebuffer/framebufferplatform.h @@ -13,5 +13,6 @@ typedef framebufferdolphin_t framebufferplatform_t; #define frameBufferPlatformInitBackBuffer frameBufferInitBackBufferDolphin #define frameBufferPlatformGetWidth frameBufferGetWidthDolphin #define frameBufferPlatformGetHeight frameBufferGetHeightDolphin +#define frameBufferPlatformGetAspect frameBufferGetAspectDolphin #define frameBufferPlatformBind frameBufferBindDolphin -#define frameBufferPlatformClear frameBufferClearDolphin \ No newline at end of file +#define frameBufferPlatformClear frameBufferClearDolphin diff --git a/src/duskdolphin/display/shader/shaderdolphin.c b/src/duskdolphin/display/shader/shaderdolphin.c index e1142a10..f51b1f81 100644 --- a/src/duskdolphin/display/shader/shaderdolphin.c +++ b/src/duskdolphin/display/shader/shaderdolphin.c @@ -228,12 +228,13 @@ errorret_t shaderUpdateMVPDolphin() { // Set Model/View Matrix if(mvDirt) { - guMtxConcat( - SHADER_BOUND->matrixView, - SHADER_BOUND->matrixModel, - SHADER_BOUND->matrixModelView - ); - GX_LoadPosMtxImm(SHADER_BOUND->matrixModelView, GX_PNMTX0); + // guMtxConcat( + // SHADER_BOUND->matrixView, + // SHADER_BOUND->matrixModel, + // SHADER_BOUND->matrixModelView + // ); + // GX_LoadPosMtxImm(SHADER_BOUND->matrixModelView, GX_PNMTX0); + GX_LoadPosMtxImm(SHADER_BOUND->matrixView, GX_PNMTX0); } SHADER_BOUND->dirtyMatrix = 0; @@ -255,7 +256,7 @@ void shaderMat4ToMtx(const mat4 inGlmMatrix, Mtx outGXMatrix) { assertNotNull(inGlmMatrix, "Input matrix cannot be null"); assertNotNull(outGXMatrix, "Output matrix cannot be null"); - for(int row = 0; row < 3; ++row) { + for(int row = 0; row < 4; ++row) {// Can perhaps be 3. for(int col = 0; col < 4; ++col) { outGXMatrix[row][col] = inGlmMatrix[col][row]; } diff --git a/src/duskdolphin/system/systemdolphin.c b/src/duskdolphin/system/systemdolphin.c index dfebeb9c..1adfd1f6 100644 --- a/src/duskdolphin/system/systemdolphin.c +++ b/src/duskdolphin/system/systemdolphin.c @@ -16,4 +16,12 @@ errorret_t systemInitDolphin(void) { systemdialogtype_t systemGetActiveDialogTypeDolphin(void) { return SYSTEM_DIALOG_TYPE_NONE; +} + +int32_t systemGetAspectRatioDolphin(void) { + return CONF_GetAspectRatio(); +} + +int32_t systemGetLanguageDolphin(void) { + return CONF_GetLanguage(); } \ No newline at end of file diff --git a/src/duskdolphin/system/systemdolphin.h b/src/duskdolphin/system/systemdolphin.h index 79c21663..1f31bc4b 100644 --- a/src/duskdolphin/system/systemdolphin.h +++ b/src/duskdolphin/system/systemdolphin.h @@ -20,4 +20,29 @@ errorret_t systemInitDolphin(void); * * @return Currently open system dialog type. */ -systemdialogtype_t systemGetActiveDialogTypeDolphin(void); \ No newline at end of file +systemdialogtype_t systemGetActiveDialogTypeDolphin(void); + +/** + * Returns either CONF_ASPECT_4_3 or CONF_ASPECT_16_9 depending on the aspect + * ratio of the system. I do believe that Gamecube will only ever return 4:3. + * + * Refer to; + * https://github.com/devkitPro/libogc/blob/20d90e944b83c8991538e88b00b1e5f309428e85/gc/ogc/conf.h#L190 + * + * @return Aspect ratio of the system. + */ +int32_t systemGetAspectRatioDolphin(void); + +/** + * Returns the language the system is set to. This is used for things like + * locale management, to try to match the system language if possible. + * + * Refer to; + * https://github.com/devkitPro/libogc/blob/20d90e944b83c8991538e88b00b1e5f309428e85/gc/ogc/conf.h#L190 + * + * @return System language. + */ +int32_t systemGetLanguageDolphin(void); + +// There's actually a tonne more things Wii can return, this is it for now +// though. \ No newline at end of file