From 7859b548bed3a64140bf62f229a296dcd36e6c9b Mon Sep 17 00:00:00 2001 From: Jerom Venneker Date: Tue, 22 Jul 2025 21:54:59 +0200 Subject: [PATCH] Added Archipelago connection status in game, todo refactor and clean up --- .../gArchipelagoOutline.rgba32.png | Bin 0 -> 3795 bytes soh/assets/soh_assets.h | 4 + soh/include/functions.h | 1 + soh/src/code/z_parameter.c | 110 ++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 soh/assets/custom/textures/parameter_static/gArchipelagoOutline.rgba32.png diff --git a/soh/assets/custom/textures/parameter_static/gArchipelagoOutline.rgba32.png b/soh/assets/custom/textures/parameter_static/gArchipelagoOutline.rgba32.png new file mode 100644 index 0000000000000000000000000000000000000000..ff2bddbcc367426bffce03ecb56a33274d7e91f8 GIT binary patch literal 3795 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 JPDHLkV1g?aK8gSU literal 0 HcmV?d00001 diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index 26799f8e7..aa50cb4a3 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -466,6 +466,10 @@ static const ALIGN_ASSET(2) char gShipLogoDL[] = dgShipLogoDL; #define dnintendo_rogo_static_Tex_LUS_000000 "__OTR__textures/nintendo_rogo_static/nintendo_rogo_static_Tex_LUS_000000" static const ALIGN_ASSET(2) char nintendo_rogo_static_Tex_LUS_000000[] = dnintendo_rogo_static_Tex_LUS_000000; +// Archipelago Item Icons +#define dgArchipelagoItemTex "__OTR__textures/parameter_static/gArchipelagoOutline" +static const ALIGN_ASSET(2) char gArchipelagoItemTex[] = dgArchipelagoItemTex; + // Archipelago Item Models #define dgArchipelagoItemDL "__OTR__objects/object_archipelago_item/gArchipelagoItemDL" static const ALIGN_ASSET(2) char gArchipelagoItemDL[] = dgArchipelagoItemDL; diff --git a/soh/include/functions.h b/soh/include/functions.h index 8deb36953..826c336e6 100644 --- a/soh/include/functions.h +++ b/soh/include/functions.h @@ -1069,6 +1069,7 @@ void Interface_LoadItemIcon1(PlayState* play, u16 button); void Interface_LoadItemIcon2(PlayState* play, u16 button); void func_80084BF4(PlayState* play, u16 flag); uint16_t Interface_DrawTextLine(GraphicsContext* gfx, char text[], int16_t x, int16_t y, uint16_t colorR, uint16_t colorG, uint16_t colorB, uint16_t colorA, float textScale, uint8_t textShadow); +uint16_t Interface_DrawTextLine_overlay(GraphicsContext* gfx, char text[], int16_t x, int16_t y, uint16_t colorR, uint16_t colorG, uint16_t colorB, uint16_t colorA, float textScale, uint8_t textShadow); u8 Item_Give(PlayState* play, u8 item); u16 Randomizer_Item_Give(PlayState* play, GetItemEntry giEntry); u8 Item_CheckObtainability(u8 item); diff --git a/soh/src/code/z_parameter.c b/soh/src/code/z_parameter.c index 0fc923070..3459d7d80 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/Enhancements/FileSelectEnhancements.h" #include "soh/ShipUtils.h" #include @@ -3424,6 +3425,45 @@ void Interface_DrawLineupTick(PlayState* play) { CLOSE_DISPS(play->state.gfxCtx); } +void Interface_DrawArchipelagoStatusString(PlayState* play) { + s16 posX = OTRGetRectDimensionFromLeftEdge(28); + s16 posY = SCREEN_HEIGHT - 15; + + int32_t scale = R_TEXT_CHAR_SCALE * 0.2f; + int32_t sTexSize = (scale / 100.0f) * 64.0f; + int32_t sTexScale = 1024.0f / (scale / 100.0f); + + gDPLoadTextureBlock(play->state.gfxCtx->overlay.p++, gArchipelagoItemTex, G_IM_FMT_RGBA, G_IM_SIZ_32b, 64, 64, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 0, 0, G_TX_NOLOD, G_TX_NOLOD); + + gSPWideTextureRectangle(play->state.gfxCtx->overlay.p++, posX << 2, posY << 2, (posX + sTexSize) << 2, + (posY + sTexSize) << 2, G_TX_RENDERTILE, 0, 0, sTexScale, sTexScale); + + //SPWideTextureRectangle(OVERLAY_DISP++, ((rMagicBarX + gSaveContext.magicCapacity) + 8) << 2, magicBarY << 2, + // ((rMagicBarX + gSaveContext.magicCapacity) + 16) << 2, (magicBarY + 16) << 2, + // G_TX_RENDERTILE, 256, 0, 1 << 10, 1 << 10); + posX += 13; + + uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language; + char* statusText = SohFileSelect_GetArchipelagoSettingText(ASM_NOT_CONNECTED, language); + switch(CVarGetInteger(CVAR_REMOTE_ARCHIPELAGO("ConnectionStatus"), 0)) { + case 0: // Not Connected + statusText = SohFileSelect_GetArchipelagoSettingText(ASM_NOT_CONNECTED, language); + break; + case 1: // Connecting + case 2: // Connection error, retrying + case 3: // Connected + statusText = SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTING, language); + break; + case 4: // Connected + Locations Scouted + statusText = SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTED, language); + break; + } + + + Interface_DrawTextLine_overlay(play->state.gfxCtx, statusText, posX, posY, 255, 255, 255, 255, 0.8f, true); +} + void Interface_DrawMagicBar(PlayState* play) { InterfaceContext* interfaceCtx = &play->interfaceCtx; s16 magicDrop = R_MAGIC_BAR_LARGE_Y - R_MAGIC_BAR_SMALL_Y + 2; @@ -5397,6 +5437,10 @@ void Interface_Draw(PlayState* play) { Interface_DrawLineupTick(play); } + if(IS_ARCHIPELAGO) { + Interface_DrawArchipelagoStatusString(play); + } + if (fullUi || gSaveContext.magicState > MAGIC_STATE_IDLE) { Interface_DrawMagicBar(play); } @@ -6936,6 +6980,41 @@ void Interface_DrawTextCharacter(GraphicsContext* gfx, int16_t x, int16_t y, voi CLOSE_DISPS(gfx); } +void Interface_DrawTextCharacter_overlay(GraphicsContext* gfx, int16_t x, int16_t y, void* texture, uint16_t colorR, + uint16_t colorG, uint16_t colorB, uint16_t colorA, float textScale, + uint8_t textShadow) { + + int32_t scale = R_TEXT_CHAR_SCALE * textScale; + int32_t sCharTexSize = (scale / 100.0f) * 16.0f; + int32_t sCharTexScale = 1024.0f / (scale / 100.0f); + + OPEN_DISPS(gfx); + + gDPPipeSync(OVERLAY_DISP++); + + gDPLoadTextureBlock_4b(OVERLAY_DISP++, 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); + + if (textShadow) { + // Draw drop shadow + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, 0, 0, 0, colorA); + gSPWideTextureRectangle(OVERLAY_DISP++, (x + R_TEXT_DROP_SHADOW_OFFSET) << 2, (y + R_TEXT_DROP_SHADOW_OFFSET) << 2, + (x + R_TEXT_DROP_SHADOW_OFFSET + sCharTexSize) << 2, + (y + R_TEXT_DROP_SHADOW_OFFSET + sCharTexSize) << 2, G_TX_RENDERTILE, 0, 0, sCharTexScale, + sCharTexScale); + } + + gDPPipeSync(OVERLAY_DISP++); + + // Draw normal text + gDPSetPrimColor(OVERLAY_DISP++, 0, 0, colorR, colorG, colorB, colorA); + gSPWideTextureRectangle(OVERLAY_DISP++, x << 2, y << 2, (x + sCharTexSize) << 2, (y + sCharTexSize) << 2, + G_TX_RENDERTILE, 0, 0, sCharTexScale, sCharTexScale); + + CLOSE_DISPS(gfx); +} + uint16_t Interface_DrawTextLine(GraphicsContext* gfx, char text[], int16_t x, int16_t y, uint16_t colorR, uint16_t colorG, uint16_t colorB, uint16_t colorA, float textScale, uint8_t textShadow) { @@ -6966,3 +7045,34 @@ uint16_t Interface_DrawTextLine(GraphicsContext* gfx, char text[], int16_t x, in return kerningOffset; } + +uint16_t Interface_DrawTextLine_overlay(GraphicsContext* gfx, char text[], int16_t x, int16_t y, uint16_t colorR, + uint16_t colorG, uint16_t colorB, uint16_t colorA, float textScale, + uint8_t textShadow) { + + uint16_t textureIndex; + uint16_t kerningOffset = 0; + uint16_t lineOffset = 0; + void* texture; + const char* processedText = Interface_ReplaceSpecialCharacters(text); + uint8_t textLength = strlen(processedText); + + for (uint16_t i = 0; i < textLength; i++) { + if (processedText[i] == '\n') { + lineOffset += 15 * textScale; + kerningOffset = 0; + } else { + textureIndex = processedText[i] - 32; + + if (textureIndex != 0) { + texture = Ship_GetCharFontTexture(processedText[i]); + Interface_DrawTextCharacter_overlay(gfx, (int16_t)(x + kerningOffset), (int16_t)(y + lineOffset), texture, colorR, colorG, colorB, + colorA, textScale, textShadow); + } + kerningOffset += + (uint16_t)(Ship_GetCharFontWidth(processedText[i]) * (R_TEXT_CHAR_SCALE / 100.0f) * textScale); + } + } + + return kerningOffset; +}