diff --git a/soh/include/functions.h b/soh/include/functions.h index d7ba1a193..5631b417a 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -903,7 +903,6 @@ void KaleidoSetup_Init(PlayState* play); void KaleidoSetup_Destroy(PlayState* play); void func_8006EE50(Font* font, u16 arg1, u16 arg2); void Font_LoadChar(Font* font, u8 character, u16 codePointIndex); -void* Font_FetchCharTexture(u8 character); void Font_LoadMessageBoxIcon(Font* font, u16 icon); void Font_LoadOrderedFont(Font* font); s32 func_8006F0A0(s32 arg0); @@ -2418,7 +2417,6 @@ u8 Message_GetState(MessageContext* msgCtx); void Message_Draw(PlayState* play); void Message_Update(PlayState* play); void Message_SetTables(void); -f32 Message_GetCharacterWidth(unsigned char characterIndex); void GameOver_Init(PlayState* play); void GameOver_FadeInLights(PlayState* play); void GameOver_Update(PlayState* play); @@ -2454,7 +2452,6 @@ void Font_LoadOrderedFontNTSC(Font* font); // #region SOH [General] -void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH); void Interface_RandoRestoreSwordless(void); s32 Ship_CalcShouldDrawAndUpdate(PlayState* play, Actor* actor, Vec3f* projectedPos, f32 projectedW, bool* shouldDraw, bool* shouldUpdate); diff --git a/soh/soh/Enhancements/kaleido.cpp b/soh/soh/Enhancements/kaleido.cpp index 4cddeef43..449d1612d 100644 --- a/soh/soh/Enhancements/kaleido.cpp +++ b/soh/soh/Enhancements/kaleido.cpp @@ -1,6 +1,7 @@ #include "kaleido.h" #include "soh/frame_interpolation.h" +#include "soh/ShipUtils.h" extern "C" { #include "z64.h" @@ -86,8 +87,6 @@ namespace Rando { // text mEntryDl->push_back(gsDPSetPrimColor(0, 0, textColor.r, textColor.g, textColor.b, textColor.a)); for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { - uint16_t texIndex = mText[i] - 32; - // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters // handle loading groups of 16 chars at a time until there are no more left to load. // By this point 4 vertices have already been loaded for the preceding icon. @@ -97,18 +96,14 @@ namespace Rando { vtxGroup++; } - if (texIndex != 0) { - auto texture = reinterpret_cast(Font_FetchCharTexture(texIndex)); - auto vertexStart = static_cast(4 * (i % 16)); + auto texture = reinterpret_cast(Ship_GetCharFontTexture(mText[i])); + auto vertexStart = static_cast(4 * (i % 16)); - Gfx charTexture[] = {gsDPLoadTextureBlock_4b(texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, - FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, - G_TX_NOMIRROR | G_TX_CLAMP, - G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD)}; - mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); - mEntryDl->push_back( - gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); - } + Gfx charTexture[] = { gsDPLoadTextureBlock_4b( + texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); + mEntryDl->push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); } mEntryDl->push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); } @@ -303,15 +298,11 @@ namespace Rando { // 4 vertices per character, plus one for the preceding icon. Vtx* vertices = (Vtx*)calloc(sizeof(Vtx[4]), mText.length() + 1); // Vertex for the preceding icon. - Interface_CreateQuadVertexGroup(vertices, offsetX, offsetY, mIconWidth, mIconHeight, 0); + Ship_CreateQuadVertexGroup(vertices, offsetX, offsetY, mIconWidth, mIconHeight, 0); offsetX += 18; for (size_t i = 0; i < mText.length(); i++) { - auto charIndex = static_cast(mText[i] - 32); - int charWidth = 0; - if (charIndex >= 0) { - charWidth = static_cast(Message_GetCharacterWidth(charIndex) * (100.0f / R_TEXT_CHAR_SCALE)); - } - Interface_CreateQuadVertexGroup(&(vertices)[(i + 1) * 4], offsetX, offsetY, charWidth, 16, 0); + int charWidth = static_cast(Ship_GetCharFontWidth(mText[i])); + Ship_CreateQuadVertexGroup(&(vertices)[(i + 1) * 4], offsetX, offsetY, charWidth, 16, 0); offsetX += charWidth; } offsetY += FONT_CHAR_TEX_HEIGHT; @@ -436,7 +427,6 @@ namespace Rando { // text for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { mEntryDl->push_back(gsDPSetPrimColor(0, 0, mButtonColors[i].r, mButtonColors[i].g, mButtonColors[i].b, mButtonColors[i].a)); - uint16_t texIndex = mText[i] - 32; // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters // handle loading groups of 16 chars at a time until there are no more left to load. @@ -447,18 +437,14 @@ namespace Rando { vtxGroup++; } - if (texIndex != 0) { - auto texture = reinterpret_cast(Font_FetchCharTexture(texIndex)); - auto vertexStart = static_cast(4 * (i % 16)); + auto texture = reinterpret_cast(Ship_GetCharFontTexture(mText[i])); + auto vertexStart = static_cast(4 * (i % 16)); - Gfx charTexture[] = {gsDPLoadTextureBlock_4b(texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, - FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, - G_TX_NOMIRROR | G_TX_CLAMP, - G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD)}; - mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); - mEntryDl->push_back( - gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); - } + Gfx charTexture[] = { gsDPLoadTextureBlock_4b( + texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + mEntryDl->insert(mEntryDl->end(), std::begin(charTexture), std::end(charTexture)); + mEntryDl->push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); } mEntryDl->push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); } diff --git a/soh/soh/Enhancements/nametag.cpp b/soh/soh/Enhancements/nametag.cpp index 49b0891fa..131f9b724 100644 --- a/soh/soh/Enhancements/nametag.cpp +++ b/soh/soh/Enhancements/nametag.cpp @@ -118,8 +118,6 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) { } for (size_t i = 0, vtxGroup = 0; i < numChar; i++) { - uint16_t texIndex = nameTag->processedText[i] - 32; - // A maximum of 64 Vtx can be loaded at once by gSPVertex, or basically 16 characters // handle loading groups of 16 chars at a time until there are no more left to load if (i % 16 == 0) { @@ -128,18 +126,16 @@ void DrawNameTag(PlayState* play, const NameTag* nameTag) { vtxGroup++; } - if (texIndex != 0 && nameTag->processedText[i] != '\n') { - uintptr_t texture = (uintptr_t)Font_FetchCharTexture(texIndex); - int16_t vertexStart = 4 * (i % 16); + uintptr_t texture = (uintptr_t)Ship_GetCharFontTexture(nameTag->processedText[i]); + int16_t vertexStart = 4 * (i % 16); - // Multi-instruction macro, need to insert all to the dl buffer - Gfx charTexture[] = { gsDPLoadTextureBlock_4b( - texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, - G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; - nameTagDl.insert(nameTagDl.end(), std::begin(charTexture), std::end(charTexture)); + // Multi-instruction macro, need to insert all to the dl buffer + Gfx charTexture[] = { gsDPLoadTextureBlock_4b( + texture, G_IM_FMT_I, FONT_CHAR_TEX_WIDTH, FONT_CHAR_TEX_HEIGHT, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD) }; + nameTagDl.insert(nameTagDl.end(), std::begin(charTexture), std::end(charTexture)); - nameTagDl.push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); - } + nameTagDl.push_back(gsSP1Quadrangle(vertexStart, vertexStart + 2, vertexStart + 3, vertexStart + 1, 0)); } nameTagDl.push_back(gsSPPopMatrix(G_MTX_MODELVIEW)); @@ -220,14 +216,9 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te numLines++; } - int16_t charIndex = processedText[i] - 32; - int16_t charWidth = 0; - // Don't add width for newline chars - if (charIndex >= 0) { - charWidth = (int16_t)(Message_GetCharacterWidth(charIndex) * (100.0f / R_TEXT_CHAR_SCALE)); - } + int16_t charWidth = (int16_t)(Ship_GetCharFontWidth(processedText[i])); - Interface_CreateQuadVertexGroup(&(vertices)[(i + 1) * 4], offsetX, (numLines - 1) * 16, charWidth, 16, 0); + Ship_CreateQuadVertexGroup(&(vertices)[(i + 1) * 4], offsetX, (numLines - 1) * 16, charWidth, 16, 0); offsetX += charWidth; if (offsetX > maxOffsetX) { @@ -238,7 +229,7 @@ extern "C" void NameTag_RegisterForActorWithOptions(Actor* actor, const char* te // Vtx for textbox, add +/- 4 in all directions int16_t height = (numLines * 16) + 8; int16_t width = maxOffsetX + 8; - Interface_CreateQuadVertexGroup(vertices, -4, -4, width, height, 0); + Ship_CreateQuadVertexGroup(vertices, -4, -4, width, height, 0); // Update the texture coordinates to consume the full textbox texture size (including mirror region) vertices[1].v.tc[0] = 256 << 5; diff --git a/soh/soh/ShipUtils.cpp b/soh/soh/ShipUtils.cpp index 4760dbcd0..db1cb4acd 100644 --- a/soh/soh/ShipUtils.cpp +++ b/soh/soh/ShipUtils.cpp @@ -1,5 +1,6 @@ #include "ShipUtils.h" #include +#include "soh_assets.h" extern "C" { #include "z64.h" @@ -8,11 +9,8 @@ extern "C" { extern float OTRGetAspectRatio(); -//extern f32 sNESFontWidths[160]; -extern const char* fontTbl[156]; -//extern TexturePtr gItemIcons[131]; -//extern TexturePtr gQuestIcons[14]; -//extern TexturePtr gBombersNotebookPhotos[24]; +extern f32 sFontWidths[144]; +extern const char* fontTbl[140]; } constexpr f32 fourByThree = 4.0f / 3.0f; @@ -79,37 +77,22 @@ extern "C" void Ship_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, vtxList[3].v.tc[1] = height << 5; } -//extern "C" f32 Ship_GetCharFontWidthNES(u8 character) { -// u8 adjustedChar = character - ' '; -// -// if (adjustedChar >= ARRAY_COUNTU(sNESFontWidths)) { -// return 0.0f; -// } -// -// return sNESFontWidths[adjustedChar]; -//} +extern "C" f32 Ship_GetCharFontWidth(u8 character) { + u8 adjustedChar = character - ' '; -//extern "C" TexturePtr Ship_GetCharFontTextureNES(u8 character) { -// u8 adjustedChar = character - ' '; -// -// if (adjustedChar >= ARRAY_COUNTU(sNESFontWidths)) { -// return (TexturePtr)gEmptyTexture; -// } -// -// return (TexturePtr)fontTbl[adjustedChar]; -//} + if (adjustedChar >= ARRAY_COUNTU(sFontWidths)) { + return 0.0f; + } -//void LoadGuiTextures() { -// for (TexturePtr entry : gItemIcons) { -// const char* path = static_cast(entry); -// Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(path, path, ImVec4(1, 1, 1, 1)); -// } -// for (TexturePtr entry : gQuestIcons) { -// const char* path = static_cast(entry); -// Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(path, path, ImVec4(1, 1, 1, 1)); -// } -// for (TexturePtr entry : gBombersNotebookPhotos) { -// const char* path = static_cast(entry); -// Ship::Context::GetInstance()->GetWindow()->GetGui()->LoadGuiTexture(path, path, ImVec4(1, 1, 1, 1)); -// } -//} + return sFontWidths[adjustedChar]; +} + +extern "C" void* Ship_GetCharFontTexture(u8 character) { + u8 adjustedChar = character - ' '; + + if (adjustedChar >= ARRAY_COUNTU(fontTbl)) { + return (void*)gEmptyTexture; + } + + return (void*)fontTbl[adjustedChar]; +} diff --git a/soh/soh/ShipUtils.h b/soh/soh/ShipUtils.h index a1ac3081b..85fc89cc5 100644 --- a/soh/soh/ShipUtils.h +++ b/soh/soh/ShipUtils.h @@ -21,8 +21,8 @@ void Ship_ExtendedCullingActorRestoreProjectedPos(PlayState* play, Actor* actor) bool Ship_IsCStringEmpty(const char* str); void Ship_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH); -f32 Ship_GetCharFontWidthNES(u8 character); -//TexturePtr Ship_GetCharFontTextureNES(u8 character); +f32 Ship_GetCharFontWidth(u8 character); +void* Ship_GetCharFontTexture(u8 character); #ifdef __cplusplus } diff --git a/soh/src/code/z_kanfont.c b/soh/src/code/z_kanfont.c index b0b754b89..97ed4294c 100644 --- a/soh/src/code/z_kanfont.c +++ b/soh/src/code/z_kanfont.c @@ -7,7 +7,8 @@ #include "textures/kanji/kanji.h" #include "textures/message_static/message_static.h" -static const char* fntTbl[] = +// #region SOH [Port] Asset tables we can pull from instead of from ROM +const char* fontTbl[140] = { gMsgChar20SpaceTex, gMsgChar21ExclamationMarkTex, @@ -4138,6 +4139,7 @@ const char* msgStaticTbl[] = gMessageEndSquareTex, gMessageArrowTex }; +// #endregion void func_8006EE50(Font* font, u16 character, u16 codePointIndex) { // #region SOH [NTSC] @@ -4159,11 +4161,7 @@ void Font_LoadChar(Font* font, u8 character, u16 codePointIndex) { //__FILE__, __LINE__); if (character < 0x8B) - memcpy(&font->charTexBuf[codePointIndex], fntTbl[character], strlen(fntTbl[character]) + 1); -} - -void* Font_FetchCharTexture(u8 character) { - return fntTbl[character]; + memcpy(&font->charTexBuf[codePointIndex], fontTbl[character], strlen(fontTbl[character]) + 1); } /** @@ -4207,7 +4205,7 @@ void Font_LoadOrderedFont(Font* font) { osSyncPrintf("nes_mes_buf[%d]=%d\n", codePointIndex, font->msgBuf[codePointIndex]); offset = (font->msgBuf[codePointIndex] - '\x20') * FONT_CHAR_TEX_SIZE; - memcpy(fontBuf, fntTbl[offset / FONT_CHAR_TEX_SIZE], strlen(fntTbl[offset / FONT_CHAR_TEX_SIZE]) + 1); + memcpy(fontBuf, fontTbl[offset / FONT_CHAR_TEX_SIZE], strlen(fontTbl[offset / FONT_CHAR_TEX_SIZE]) + 1); //DmaMgr_SendRequest1(fontBuf, fontStatic + offset, FONT_CHAR_TEX_SIZE, __FILE__, __LINE__); fontBufIndex += FONT_CHAR_TEX_SIZE / 8; } diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 4ab76a93b..317f317ca 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -831,10 +831,6 @@ f32 sFontWidths[144] = { 14.0f, // ? }; -f32 Message_GetCharacterWidth(unsigned char characterIndex) { - return sFontWidths[characterIndex] * (R_TEXT_CHAR_SCALE / 100.0f); -} - u16 Message_DrawItemIcon(PlayState* play, u16 itemId, Gfx** p, u16 i) { s32 pad; Gfx* gfx = *p; diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 6df6665ed..a221e570f 100644 --- a/soh/src/code/z_parameter.c +++ b/soh/src/code/z_parameter.c @@ -12,6 +12,7 @@ #include "soh/Enhancements/custom-message/CustomMessageInterfaceAddon.h" #include "soh/Enhancements/cosmetics/cosmeticsTypes.h" #include "soh/Enhancements/enhancementTypes.h" +#include "soh/ShipUtils.h" #include #include @@ -3591,31 +3592,6 @@ void Interface_DrawMagicBar(PlayState* play) { static Vtx sEnemyHealthVtx[16]; static Mtx sEnemyHealthMtx[2]; -// Build vertex coordinates for a quad command -// In order of top left, top right, bottom left, then bottom right -// Supports flipping the texture horizontally -void Interface_CreateQuadVertexGroup(Vtx* vtxList, s32 xStart, s32 yStart, s32 width, s32 height, u8 flippedH) { - vtxList[0].v.ob[0] = xStart; - vtxList[0].v.ob[1] = yStart; - vtxList[0].v.tc[0] = (flippedH ? width : 0) << 5; - vtxList[0].v.tc[1] = 0 << 5; - - vtxList[1].v.ob[0] = xStart + width; - vtxList[1].v.ob[1] = yStart; - vtxList[1].v.tc[0] = (flippedH ? width * 2 : width) << 5; - vtxList[1].v.tc[1] = 0 << 5; - - vtxList[2].v.ob[0] = xStart; - vtxList[2].v.ob[1] = yStart + height; - vtxList[2].v.tc[0] = (flippedH ? width : 0) << 5; - vtxList[2].v.tc[1] = height << 5; - - vtxList[3].v.ob[0] = xStart + width; - vtxList[3].v.ob[1] = yStart + height; - vtxList[3].v.tc[0] = (flippedH ? width * 2 : width) << 5; - vtxList[3].v.tc[1] = height << 5; -} - // Draws an enemy health bar using the magic bar textures and positions it in a similar way to Z-Targeting void Interface_DrawEnemyHealthBar(TargetContext* targetCtx, PlayState* play) { InterfaceContext* interfaceCtx = &play->interfaceCtx; @@ -3675,16 +3651,17 @@ void Interface_DrawEnemyHealthBar(TargetContext* targetCtx, PlayState* play) { } // Health bar border end left - Interface_CreateQuadVertexGroup(&sEnemyHealthVtx[0], -floorf(halfBarWidth), -texHeight / 2, endTexWidth, texHeight, 0); + Ship_CreateQuadVertexGroup(&sEnemyHealthVtx[0], -floorf(halfBarWidth), -texHeight / 2, endTexWidth, texHeight, + 0); // Health bar border middle - Interface_CreateQuadVertexGroup(&sEnemyHealthVtx[4], -floorf(halfBarWidth) + endTexWidth, -texHeight / 2, - healthbar_fillWidth, texHeight, 0); + Ship_CreateQuadVertexGroup(&sEnemyHealthVtx[4], -floorf(halfBarWidth) + endTexWidth, -texHeight / 2, + healthbar_fillWidth, texHeight, 0); // Health bar border end right - Interface_CreateQuadVertexGroup(&sEnemyHealthVtx[8], ceilf(halfBarWidth) - endTexWidth, -texHeight / 2, endTexWidth, - texHeight, 1); + Ship_CreateQuadVertexGroup(&sEnemyHealthVtx[8], ceilf(halfBarWidth) - endTexWidth, -texHeight / 2, endTexWidth, + texHeight, 1); // Health bar fill - Interface_CreateQuadVertexGroup(&sEnemyHealthVtx[12], -floorf(halfBarWidth) + endTexWidth, (-texHeight / 2) + 3, - healthBarFill, 7, 0); + Ship_CreateQuadVertexGroup(&sEnemyHealthVtx[12], -floorf(halfBarWidth) + endTexWidth, (-texHeight / 2) + 3, + healthBarFill, 7, 0); if (((!(player->stateFlags1 & PLAYER_STATE1_TALKING)) || (actor != player->focusActor)) && targetCtx->unk_44 < 500.0f) { f32 slideInOffsetY = 0; @@ -6713,11 +6690,12 @@ uint16_t Interface_DrawTextLine(GraphicsContext* gfx, char text[], int16_t x, in textureIndex = processedText[i] - 32; if (textureIndex != 0) { - texture = Font_FetchCharTexture(textureIndex); + texture = Ship_GetCharFontTexture(processedText[i]); Interface_DrawTextCharacter(gfx, x + kerningOffset, y + lineOffset, texture, colorR, colorG, colorB, colorA, textScale, textShadow); } - kerningOffset += (uint16_t)(Message_GetCharacterWidth(textureIndex) * textScale); + kerningOffset += + (uint16_t)(Ship_GetCharFontWidth(processedText[i]) * (R_TEXT_CHAR_SCALE / 100.0f) * textScale); } }