From c1d569c32bd1561338a2b97ff9a4c94f17ad4b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dar=C3=ADo?= Date: Sun, 28 Dec 2025 00:32:36 -0300 Subject: [PATCH] Fix text rendering in orthographic mode. (#27) --- lib/rt64 | 2 +- patches/camera_transform_tagging.c | 8 +++++++- patches/text_transform_tagging.c | 29 ++++++++++++++++++++++------- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/lib/rt64 b/lib/rt64 index 2fb9bd8..ad1cf39 160000 --- a/lib/rt64 +++ b/lib/rt64 @@ -1 +1 @@ -Subproject commit 2fb9bd809b169e12a97f8ab58438c6ca84ef70fd +Subproject commit ad1cf390c49b1ebe606666f93ad278665b63a0dd diff --git a/patches/camera_transform_tagging.c b/patches/camera_transform_tagging.c index 3c26b38..04915cc 100644 --- a/patches/camera_transform_tagging.c +++ b/patches/camera_transform_tagging.c @@ -116,9 +116,15 @@ float identity_matrix[4][4] = { RECOMP_PATCH void viewport_setRenderViewportAndOrthoMatrix(Gfx **gfx, Mtx **mtx) { gSPViewport((*gfx)++, &sViewportStack[sViewportStackIndex]); + // @recomp Use a high precision version of the projection matrix instead of the fixed precision one. This fixes accuracy issues when rendering text using the orthographic projection. + guOrthoF(*mtx, -(2 * (f32)gFramebufferWidth), (2 * (f32)gFramebufferWidth), -(2 * (f32)gFramebufferHeight), (2 * (f32)gFramebufferHeight), 1.0f, 20.0f, 1.0f); + gEXMatrixFloat((*gfx)++, OS_K0_TO_PHYSICAL((*mtx)++), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); + +#if 0 guOrtho(*mtx, -(2*(f32)gFramebufferWidth), (2*(f32)gFramebufferWidth), -(2*(f32)gFramebufferHeight), (2*(f32)gFramebufferHeight), 1.0f, 20.0f, 1.0f); gSPMatrix((*gfx)++, OS_K0_TO_PHYSICAL((*mtx)++), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_PROJECTION); - +#endif + guTranslate(*mtx, 0.0f, 0.0f, 0.0f); gSPMatrix((*gfx)++, OS_K0_TO_PHYSICAL((*mtx)++), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/patches/text_transform_tagging.c b/patches/text_transform_tagging.c index ad43bd3..4a02c9c 100644 --- a/patches/text_transform_tagging.c +++ b/patches/text_transform_tagging.c @@ -317,7 +317,8 @@ RECOMP_PATCH void _printbuffer_draw_letter(char letter, f32 *xPtr, f32 *yPtr, f3 }//L802F677C // @recomp Force orthographic projection rectangles to be used for all letters as it allows them to be interpolated. - if (TRUE) { //if (D_80380AF4 != 0) { + //if (D_80380AF4 != 0) { + if (TRUE) { f32 temp_f24; f32 spD0; f32 ix; @@ -328,7 +329,10 @@ RECOMP_PATCH void _printbuffer_draw_letter(char letter, f32 *xPtr, f32 *yPtr, f3 temp_f24 = (sp214->x - 1.0); spD0 = sp214->y - 1.0; temp_f26 = (f64)sp200 - (f32)gFramebufferWidth * 0.5; - spC0 = (f64)f28 - (f32)gFramebufferHeight * 0.5 - 0.5f; + + // @recomp Remove the incorrect half pixel offset that was applied. + //spC0 = (f64)f28 - (f32)gFramebufferHeight * 0.5 - 0.5f; + spC0 = (f64)f28 - (f32)gFramebufferHeight * 0.5; // @recomp Assign a unique matrix and group to each letter drawn if an ID is currently assigned. if (cur_drawn_text_transform_id != 0) { @@ -343,18 +347,29 @@ RECOMP_PATCH void _printbuffer_draw_letter(char letter, f32 *xPtr, f32 *yPtr, f3 cur_drawn_text_transform_id++; } - + gSPVertex((*gfx)++, *vtx, 4, 0); for (iy = 0.0f; iy < 2.0; iy += 1.0) { for (ix = 0.0f; ix < 2.0; ix += 1.0) { s32 s = (ix * temp_f24 * 64.0f); - (*vtx)->v.ob[0] = (s16)(s32)((f64)(temp_f26 + (temp_f24 * arg3 * ix)) * 4.0); + // @recomp Add one pixel to the right of the rectangle. + //(*vtx)->v.ob[0] = (s16)(s32)((f64)(temp_f26 + (temp_f24 * arg3 * ix)) * 4.0); + s32 x = (s32)((f64)(temp_f26 + (temp_f24 * arg3 * ix)) * 4.0) + (ix * 4); + (*vtx)->v.ob[0] = (s16)(x); + { s32 t = (iy * spD0 * 64.0f); - (*vtx)->v.ob[1] = (s16)(s32)((f64)(spC0 + (spD0 * arg3 * iy)) * -4.0); + // @recomp Add one pixel to the bottom of the rectangle. + //(*vtx)->v.ob[1] = (s16)(s32)((f64)(spC0 + (spD0 * arg3 * iy)) * -4.0); + s32 y = (s32)((f64)(spC0 + (spD0 * arg3 * iy)) * -4.0) - iy * 4; + (*vtx)->v.ob[1] = (s16)(y); (*vtx)->v.ob[2] = -0x14; - (*vtx)->v.tc[0] = s; - (*vtx)->v.tc[1] = t; + + // @recomp Add one pixel to the texture coordinates. + //(*vtx)->v.tc[0] = s; + //(*vtx)->v.tc[1] = t; + (*vtx)->v.tc[0] = s + ix * 64; + (*vtx)->v.tc[1] = t + iy * 64; } (*vtx)->v.cn[3] = (iy != 0.0f) ? print_sCurrentPtr->unk6 : print_sCurrentPtr->unk4;