From f07112bda6d62a13d3f17087e5c7e662d4231ea9 Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Thu, 28 Aug 2025 20:24:27 +0100 Subject: [PATCH] Text rendering optimizations (#7497) --- include/window.h | 2 +- src/international_string_util.c | 2 +- src/text.c | 51 +++++++++++++++++++++------------ 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/include/window.h b/include/window.h index 2dd67b123f..fc35f724d9 100644 --- a/include/window.h +++ b/include/window.h @@ -45,7 +45,7 @@ struct WindowTemplate struct Window { struct WindowTemplate window; - u8 *tileData; + ALIGNED(4) u8 *tileData; }; bool32 InitWindows(const struct WindowTemplate *templates); diff --git a/src/international_string_util.c b/src/international_string_util.c index feba03c97f..b5a904c773 100644 --- a/src/international_string_util.c +++ b/src/international_string_util.c @@ -220,7 +220,7 @@ void FillWindowTilesByRow(int windowId, int columnStart, int rowStart, int numFi fillSize = numFillTiles * TILE_SIZE_4BPP; windowRowSize = window->window.width * TILE_SIZE_4BPP; - windowTileData = window->tileData + (rowStart * windowRowSize) + (columnStart * TILE_SIZE_4BPP); + windowTileData = (u8 *)window->tileData + (rowStart * windowRowSize) + (columnStart * TILE_SIZE_4BPP); if (numRows > 0) { for (i = numRows; i != 0; i--) diff --git a/src/text.c b/src/text.c index 29ffc5ea3a..8166b35302 100644 --- a/src/text.c +++ b/src/text.c @@ -427,6 +427,13 @@ void GenerateFontHalfRowLookupTable(u8 fgColor, u8 bgColor, u8 shadowColor) u16 *current = sFontHalfRowLookupTable; + if (fgColor == sLastTextFgColor + && bgColor == sLastTextBgColor + && shadowColor == sLastTextShadowColor) + { + return; + } + sLastTextBgColor = bgColor; sLastTextFgColor = fgColor; sLastTextShadowColor = shadowColor; @@ -629,27 +636,35 @@ static u8 UNUSED GetLastTextColor(u8 colorType) } } -inline static void GLYPH_COPY(u8 *windowTiles, u32 widthOffset, u32 j, u32 i, u32 *glyphPixels, s32 width, s32 height) +inline static void GLYPH_COPY(u8 *windowTiles, u32 widthOffset, u32 x0, u32 y0, u32 *glyphPixels, s32 width, s32 height) { - u32 xAdd, yAdd, pixelData, bits, toOrr, dummyX; - u8 *dst; + if (width <= 0) + return; - xAdd = j + width; - yAdd = i + height; - dummyX = j; - for (; i < yAdd; i++) + u32 widthMask = (1 << (width * 4)) - 1; + + u32 shift0 = (x0 % 8) * 4, shift8 = 32 - shift0; + + u32 *alignedWindowTilesX = (u32 *)(windowTiles + ((x0 / 8) * TILE_SIZE_4BPP)); + + u32 y1 = y0 + height; + for (u32 y = y0; y < y1; y++) { - pixelData = *glyphPixels++; - for (j = dummyX; j < xAdd; j++) - { - if ((toOrr = pixelData & 0xF)) - { - dst = windowTiles + ((j / 8) * 32) + ((j % 8) / 2) + ((i / 8) * widthOffset) + ((i % 8) * 4); - bits = ((j & 1) * 4); - *dst = (toOrr << bits) | (*dst & (0xF0 >> bits)); - } - pixelData >>= 4; - } + u32 pixels = *glyphPixels++ & widthMask; + + u32 mask = pixels; + mask = mask | (mask >> 2); + mask = mask | (mask >> 1); + mask = mask & 0x11111111; + mask = mask * 0xF; + + u32 pixels0 = pixels << shift0, pixels8 = pixels >> shift8; + u32 mask0 = mask << shift0, mask8 = mask >> shift8; + + u32 *alignedWindowTiles = (u32 *)((u8 *)alignedWindowTilesX + ((y / 8) * widthOffset) + ((y % 8) * 4)); + + alignedWindowTiles[0] = (alignedWindowTiles[0] & ~mask0) | pixels0; + alignedWindowTiles[8] = (alignedWindowTiles[8] & ~mask8) | pixels8; } }