From 0fe29b4a20e3b0a4b0af537f11bead0ce9454c0a Mon Sep 17 00:00:00 2001 From: Jerom Venneker Date: Wed, 11 Jun 2025 21:35:03 +0200 Subject: [PATCH] Added menus for creating an archipelago file --- .../gTitleArchipelagoSubtitleTex.rgba32.png | Bin 0 -> 16992 bytes soh/assets/soh_assets.h | 3 + soh/include/z64.h | 6 +- soh/include/z64save.h | 2 +- .../Enhancements/FileSelectEnhancements.cpp | 39 +++- soh/soh/Enhancements/FileSelectEnhancements.h | 13 +- soh/soh/OTRGlobals.cpp | 8 + soh/soh/OTRGlobals.h | 2 + soh/soh/SohGui/SohGui.cpp | 4 + soh/soh/SohGui/SohGui.hpp | 1 + .../gamestates/ovl_file_choose/file_choose.h | 5 + .../ovl_file_choose/z_file_choose.c | 198 +++++++++++++++++- 12 files changed, 267 insertions(+), 14 deletions(-) create mode 100644 soh/assets/custom/objects/object_mag/gTitleArchipelagoSubtitleTex.rgba32.png diff --git a/soh/assets/custom/objects/object_mag/gTitleArchipelagoSubtitleTex.rgba32.png b/soh/assets/custom/objects/object_mag/gTitleArchipelagoSubtitleTex.rgba32.png new file mode 100644 index 0000000000000000000000000000000000000000..5e0b83446dc99044ee3852818df7303f644fe225 GIT binary patch literal 16992 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 literal 0 HcmV?d00001 diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h index 990a93c41..a331c4319 100644 --- a/soh/assets/soh_assets.h +++ b/soh/assets/soh_assets.h @@ -44,6 +44,9 @@ static const ALIGN_ASSET(2) char gTitleRandomizerSubtitleTex[] = dgTitleRandomiz #define dgTitleBossRushSubtitleTex "__OTR__objects/object_mag/gTitleBossRushSubtitleTex" static const ALIGN_ASSET(2) char gTitleBossRushSubtitleTex[] = dgTitleBossRushSubtitleTex; +#define dgTitleArchipelagoSubtilteTex "__OTR__objects/object_mag/gTitleArchipelagoSubtitleTex" +static const ALIGN_ASSET(2) char gTitleArchipelagoSubtitleTex[] = dgTitleArchipelagoSubtilteTex; + #define dgOcarinaAButtonDL "__OTR__objects/object_ocarina_a_button/gOcarinaAButtonDL" static const ALIGN_ASSET(2) char gOcarinaAButtonDL[] = dgOcarinaAButtonDL; diff --git a/soh/include/z64.h b/soh/include/z64.h index 53b76e8fb..8cb39a125 100644 --- a/soh/include/z64.h +++ b/soh/include/z64.h @@ -1593,7 +1593,7 @@ typedef struct { /* 0x1CAD4 */ s16 newFileNameCharCount; /* 0x1CAD6 */ s16 unk_1CAD6[5]; s16 logoAlpha; - s8 questType[3]; // 0 for Normal, 1 for MQ + s8 questType[4]; // 0 for Normal, 1 for MQ StickDirectionPrompt stickLeftPrompt; StickDirectionPrompt stickRightPrompt; f32 arrowAnimTween; @@ -1607,6 +1607,10 @@ typedef struct { uint8_t randomizerIndex; int16_t randomizerUIAlpha; uint16_t randomizerArrowOffset; + uint8_t archipelagoIndex; + int16_t archipelagoUIAlpha; + uint16_t archipelagoArrowOffset; + } FileChooseContext; // size = 0x1CAE0 // Macros for `EntranceInfo.field` diff --git a/soh/include/z64save.h b/soh/include/z64save.h index 8e57500b4..7f7433b0b 100644 --- a/soh/include/z64save.h +++ b/soh/include/z64save.h @@ -329,7 +329,7 @@ typedef enum { /* 01 */ QUEST_MASTER, /* 02 */ QUEST_RANDOMIZER, /* 03 */ QUEST_BOSSRUSH, - /* 03 */ QUEST_ARCHIPELAGO, + /* 04 */ QUEST_ARCHIPELAGO, } Quest; #define IS_VANILLA (gSaveContext.ship.quest.id == QUEST_NORMAL) diff --git a/soh/soh/Enhancements/FileSelectEnhancements.cpp b/soh/soh/Enhancements/FileSelectEnhancements.cpp index f9e993b6a..a13c74f46 100644 --- a/soh/soh/Enhancements/FileSelectEnhancements.cpp +++ b/soh/soh/Enhancements/FileSelectEnhancements.cpp @@ -63,6 +63,43 @@ std::array RandomizerSettingsMenuText[RSM_MAX] = { }, }; -const char* SohFileSelect_GetSettingText(uint8_t optionIndex, uint8_t language) { +std::array ArchipelagoSettingsMenuText[ASM_MAX] { + { //ASM_CHANGE_SETTINGS + "Change connection settings.", + "Todo", + "Todo", + }, + { //ASM_CONNECT + "Connect to server.", + "Todo", + "Todo", + }, + { //ASM_CONNECTING + "Connecting...", + "Todo", + "Todo", + }, + { //ASM_CONNECTION_ERROR + "Could not connect, please check settings", + "Todo", + "Todo", + }, + { //ASM_SERVER_ADDRESS + "Server Address: ", + "Todo", + "Todo", + }, + { //ASM_SLOT_NAME + "Slot Name: ", + "Todo", + "Todo", + }, +}; + +const char* SohFileSelect_GetRandomizerSettingText(uint8_t optionIndex, uint8_t language) { return RandomizerSettingsMenuText[optionIndex][language].c_str(); } + +const char* SohFileSelect_GetArchipelagoSettingText(uint8_t optionIndex, uint8_t language) { + return ArchipelagoSettingsMenuText[optionIndex][language].c_str(); +} \ No newline at end of file diff --git a/soh/soh/Enhancements/FileSelectEnhancements.h b/soh/soh/Enhancements/FileSelectEnhancements.h index 070d270dc..11d9c0a8b 100644 --- a/soh/soh/Enhancements/FileSelectEnhancements.h +++ b/soh/soh/Enhancements/FileSelectEnhancements.h @@ -6,7 +6,8 @@ #ifdef __cplusplus extern "C" { #endif -const char* SohFileSelect_GetSettingText(u8 optionIndex, u8 language); +const char* SohFileSelect_GetRandomizerSettingText(u8 optionIndex, u8 language); +const char* SohFileSelect_GetArchipelagoSettingText(u8 optionIndex, u8 language); #ifdef __cplusplus }; #endif @@ -20,4 +21,14 @@ typedef enum { RSM_MAX, } RandomizerSettingsMenuEnums; +typedef enum { + ASM_CHANGE_SETTINGS, + ASM_CONNECT, + ASM_CONNECTING, + ASM_CONNECTION_ERROR, + ASM_SERVER_ADDRESS, + ASM_SLOT_NAME, + ASM_MAX +} ArchipelagoSettingsMenuEnums; + #endif diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 9c032dff3..831d7a3aa 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -2165,6 +2165,14 @@ extern "C" void Randomizer_ShowRandomizerMenu() { SohGui::ShowRandomizerSettingsMenu(); } +extern "C" void Archipelago_Connect() { + ArchipelagoClient::GetInstance().StartClient(); +} + +extern "C" void Archipelago_ShowArchipelagoMenu() { + SohGui::ShowArchipelagoSettingsMenu(); +} + CustomMessage Randomizer_GetCustomGetItemMessage(Player* player) { s16 giid; if (player->getItemEntry.objectId != OBJECT_INVALID) { diff --git a/soh/soh/OTRGlobals.h b/soh/soh/OTRGlobals.h index 0848dabd7..864a80af8 100644 --- a/soh/soh/OTRGlobals.h +++ b/soh/soh/OTRGlobals.h @@ -156,6 +156,8 @@ uint8_t Randomizer_IsSpoilerLoaded(); void Randomizer_SetSpoilerLoaded(bool spoilerLoaded); uint8_t Randomizer_GenerateRandomizer(); void Randomizer_ShowRandomizerMenu(); +void Archipelago_Connect(); +void Archipelago_ShowArchipelagoMenu(); int CustomMessage_RetrieveIfExists(PlayState* play); void Overlay_DisplayText(float duration, const char* text); void Overlay_DisplayText_Seconds(int seconds, const char* text); diff --git a/soh/soh/SohGui/SohGui.cpp b/soh/soh/SohGui/SohGui.cpp index de5db9c0c..2c773ff9b 100644 --- a/soh/soh/SohGui/SohGui.cpp +++ b/soh/soh/SohGui/SohGui.cpp @@ -258,4 +258,8 @@ void RegisterPopup(std::string title, std::string message, std::string button1, void ShowRandomizerSettingsMenu() { mRandomizerSettingsWindow->Show(); } + +void ShowArchipelagoSettingsMenu() { + mArchipelagoSettingsWindow->Show(); +} } // namespace SohGui diff --git a/soh/soh/SohGui/SohGui.hpp b/soh/soh/SohGui/SohGui.hpp index b9571642c..9e78ebf77 100644 --- a/soh/soh/SohGui/SohGui.hpp +++ b/soh/soh/SohGui/SohGui.hpp @@ -40,6 +40,7 @@ void Destroy(); void RegisterPopup(std::string title, std::string message, std::string button1 = "OK", std::string button2 = "", std::function button1callback = nullptr, std::function button2callback = nullptr); void ShowRandomizerSettingsMenu(); +void ShowArchipelagoSettingsMenu(); UIWidgets::Colors GetMenuThemeColor(); } // namespace SohGui diff --git a/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h b/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h index 5f6e3f202..d97d17399 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h +++ b/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h @@ -70,6 +70,11 @@ typedef enum { CM_START_RANDOMIZER_SETTINGS_MENU, CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST, CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU, + CM_ROTATE_TO_ARCHIPELAGO_MENU, + CM_ARCHIPELAGO_SETTINGS_MENU, + CM_START_ARCHIPELAGO_SETTINGS_MENU, + CM_ARCHIPELAGO_SETTINGS_TO_QUEST, + CM_NAME_ENTRY_TO_ARCHIPELAGO_SETTINGS_MENU, } ConfigMode; typedef enum { diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c index 90d1ba0c5..c00f92f70 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_choose.c @@ -703,7 +703,7 @@ static void DrawMoreInfo(FileChooseContext* this, s16 fileIndex, u8 alpha) { } #define MIN_QUEST (ResourceMgr_GameHasOriginal() ? QUEST_NORMAL : QUEST_MASTER) -#define MAX_QUEST QUEST_BOSSRUSH +#define MAX_QUEST QUEST_ARCHIPELAGO void Sram_InitDebugSave(void); void Sram_InitBossRushSave(); @@ -1074,7 +1074,11 @@ void FileChoose_UpdateRandomizer() { remove(fileLoc); } } +} +u8 connecting; + +void FileChoose_UpdateArchipelago() { if (CVarGetInteger(CVAR_REMOTE_ARCHIPELAGO("Connected"), 0) && !fileSelectArchipelagoLoaded) { ParseArchipelago(); fileSelectArchipelagoLoaded = true; @@ -1355,6 +1359,11 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) { &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); this->prevConfigMode = this->configMode; this->configMode = CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU; + } else if (this->questType[this->buttonIndex] == QUEST_ARCHIPELAGO) { + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + this->prevConfigMode = this->configMode; + this->configMode = CM_ROTATE_TO_ARCHIPELAGO_MENU; } else { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); @@ -1633,7 +1642,8 @@ void FileChoose_RotateToNameEntry(GameState* thisx) { this->windowRot += VREG(16); - if (this->prevConfigMode == CM_RANDOMIZER_SETTINGS_MENU) { + if (this->prevConfigMode == CM_RANDOMIZER_SETTINGS_MENU || + this->prevConfigMode == CM_ARCHIPELAGO_SETTINGS_MENU) { if (this->windowRot >= 942.0f) { this->windowRot = 628.0f; this->configMode = CM_START_NAME_ENTRY; @@ -1690,7 +1700,8 @@ void FileChoose_RotateToQuest(GameState* thisx) { FileChooseContext* this = (FileChooseContext*)thisx; if (this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU || this->configMode == CM_BOSS_RUSH_TO_QUEST || - this->configMode == CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST) { + this->configMode == CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST || + this->configMode == CM_ARCHIPELAGO_SETTINGS_TO_QUEST) { this->windowRot -= VREG(16); if (this->windowRot <= 314.0f) { @@ -1738,6 +1749,92 @@ void FileChoose_RotateToRandomizer(GameState* thisx) { } } +void FileChoose_RotateToArchipelago(GameState* thisx) { + FileChooseContext* this = (FileChooseContext*)thisx; + + if (this->configMode == CM_NAME_ENTRY_TO_ARCHIPELAGO_SETTINGS_MENU ) { + this->windowRot -= VREG(16); + + if (this->windowRot <= 314.0f) { + this->windowRot = 628.0f; + this->configMode = CM_START_ARCHIPELAGO_SETTINGS_MENU; + } + } else { + this->windowRot += VREG(16); + + if (this->windowRot >= 628.0f) { + this->windowRot = 628.0f; + this->configMode = CM_START_ARCHIPELAGO_SETTINGS_MENU; + } + } +} + +void FileChoose_UpdateArchipelagoMenu(GameState* thisx) { + FileChooseContext* this = (FileChooseContext*)thisx; + Input* input = &this->state.input[0]; + bool dpad = CVarGetInteger(CVAR_SETTING("DpadInText"), 0); + + FileChoose_UpdateArchipelago(); + + if(connecting) { + return; + } + + // Fade in elements after opening Archipelago Options menu + this->archipelagoUIAlpha += 25; + if (this->archipelagoUIAlpha > 255) { + this->archipelagoUIAlpha = 255; + } + + // Move menu selection up or down + if(ABS(this->stickRelY) > 30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) { + // move down + if(this->stickRelY < -30 || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN))) { + if((this->archipelagoIndex + 1) > ASM_CONNECT) { + this->archipelagoIndex = ASM_CHANGE_SETTINGS; + } else { + this->archipelagoIndex++; + } + } else { + if(((int8_t)this->archipelagoIndex - 1) < ASM_CHANGE_SETTINGS) { + this->archipelagoIndex = ASM_CONNECT; + } else { + this->archipelagoIndex--; + } + } + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + } + + if (CHECK_BTN_ALL(input->press.button, BTN_B)) { + this->configMode = CM_ARCHIPELAGO_SETTINGS_TO_QUEST; + return; + } + + if (CHECK_BTN_ALL(input->press.button, BTN_A)) { + if (this->archipelagoIndex == ASM_CONNECT) { + Archipelago_Connect(); + } else if (this->archipelagoIndex == ASM_CHANGE_SETTINGS) { + Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &gSfxDefaultPos, 4, &gSfxDefaultFreqAndVolScale, + &gSfxDefaultFreqAndVolScale, &gSfxDefaultReverb); + Archipelago_ShowArchipelagoMenu(); + } + } +} + +void FileChoose_StartArchipelagoMenu(GameState* thisx) { + FileChooseContext* this = (FileChooseContext*)thisx; + + this->logoAlpha -= 25; + this->archipelagoUIAlpha = 0; + this->archipelagoArrowOffset = 0; + + if (this->logoAlpha <= 0) { + this->logoAlpha = 0; + this->configMode = CM_ARCHIPELAGO_SETTINGS_MENU; + } +} + static void (*gConfigModeUpdateFuncs[])(GameState*) = { FileChoose_StartFadeIn, FileChoose_FinishFadeIn, FileChoose_UpdateMainMenu, FileChoose_SetupCopySource, @@ -1766,7 +1863,9 @@ static void (*gConfigModeUpdateFuncs[])(GameState*) = { FileChoose_StartBossRushMenu, FileChoose_RotateToQuest, FileChoose_RotateToRandomizer, FileChoose_UpdateRandomizerMenu, FileChoose_StartRandomizerMenu, FileChoose_RotateToQuest, - FileChoose_RotateToRandomizer, + FileChoose_RotateToRandomizer, FileChoose_RotateToArchipelago, + FileChoose_UpdateArchipelagoMenu, FileChoose_StartArchipelagoMenu, + FileChoose_RotateToQuest, FileChoose_RotateToArchipelago }; static void (*gConfigModeUpdateFuncsNES[])(GameState*) = { @@ -1797,7 +1896,9 @@ static void (*gConfigModeUpdateFuncsNES[])(GameState*) = { FileChoose_StartBossRushMenu, FileChoose_RotateToQuest, FileChoose_RotateToRandomizer, FileChoose_UpdateRandomizerMenu, FileChoose_StartRandomizerMenu, FileChoose_RotateToQuest, - FileChoose_RotateToRandomizer, + FileChoose_RotateToRandomizer, FileChoose_RotateToArchipelago, + FileChoose_UpdateArchipelagoMenu, FileChoose_StartArchipelagoMenu, + FileChoose_RotateToQuest, FileChoose_RotateToArchipelago }; /** @@ -2460,6 +2561,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) { case CM_NAME_ENTRY_TO_QUEST_MENU: case CM_ROTATE_TO_BOSS_RUSH_MENU: case CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU: + case CM_ROTATE_TO_ARCHIPELAGO_MENU: tex = FileChoose_GetQuestChooseTitleTexName(gSaveContext.language); break; case CM_BOSS_RUSH_MENU: @@ -2469,6 +2571,10 @@ void FileChoose_DrawWindowContents(GameState* thisx) { case CM_START_RANDOMIZER_SETTINGS_MENU: case CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST: case CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU: + case CM_START_ARCHIPELAGO_SETTINGS_MENU: + case CM_ARCHIPELAGO_SETTINGS_MENU: + case CM_ARCHIPELAGO_SETTINGS_TO_QUEST: + case CM_NAME_ENTRY_TO_ARCHIPELAGO_SETTINGS_MENU: tex = FileChoose_GetSohOptionsTitleTexName(gSaveContext.language); break; default: @@ -2585,6 +2691,17 @@ void FileChoose_DrawWindowContents(GameState* thisx) { ResourceMgr_GameHasOriginal() ? gTitleZeldaShieldLogoTex : gTitleZeldaShieldLogoMQTex, 160, 160); FileChoose_DrawImageRGBA32(this->state.gfxCtx, 182, 180, gTitleBossRushSubtitleTex, 128, 32); break; + case QUEST_ARCHIPELAGO: + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->logoAlpha); + FileChoose_DrawTextureI8(this->state.gfxCtx, gTitleTheLegendOfTextTex, 72, 8, 156, 108, 72, 8, 1024, + 1024); + FileChoose_DrawTextureI8(this->state.gfxCtx, gTitleOcarinaOfTimeTMTextTex, 96, 8, 154, 163, 96, 8, 1024, + 1024); + FileChoose_DrawImageRGBA32( + this->state.gfxCtx, 160, 135, + ResourceMgr_GameHasOriginal() ? gTitleZeldaShieldLogoTex : gTitleZeldaShieldLogoMQTex, 160, 160); + FileChoose_DrawImageRGBA32(this->state.gfxCtx, 182, 180, gTitleArchipelagoSubtitleTex, 128, 32); + break; } } else if (this->configMode == CM_BOSS_RUSH_MENU) { uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language; @@ -2665,13 +2782,13 @@ void FileChoose_DrawWindowContents(GameState* thisx) { textColorR = textColorG = textColorB = 100; } - Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetSettingText(index, language), 70, + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetRandomizerSettingText(index, language), 70, (80 + (index * 16)), textColorR, textColorG, textColorB, textAlpha, 0.8f, true); } // Show text to indicate randomizer is being generated. if (generating) { - Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetSettingText(RSM_GENERATING, language), 70, + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetRandomizerSettingText(RSM_GENERATING, language), 70, (80 + 64), 255, 255, 255, textAlpha, 0.8f, true); } @@ -2680,7 +2797,7 @@ void FileChoose_DrawWindowContents(GameState* thisx) { if (!Randomizer_IsSeedGenerated() && !Randomizer_IsSpoilerLoaded() && this->randomizerIndex == RSM_START_RANDOMIZER) { Interface_DrawTextLine(this->state.gfxCtx, - SohFileSelect_GetSettingText(RSM_NO_RANDOMIZER_GENERATED, language), 70, (80 + 64), + SohFileSelect_GetRandomizerSettingText(RSM_NO_RANDOMIZER_GENERATED, language), 70, (80 + 64), 240, 80, 80, textAlpha, 0.8f, true); } @@ -2694,12 +2811,67 @@ void FileChoose_DrawWindowContents(GameState* thisx) { this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB, textAlpha, 62, (85 + textOffset), 0.42f, 0, 0, 1.0f, 1.0f); + } else if (this->configMode == CM_ARCHIPELAGO_SETTINGS_MENU) { + uint8_t language = (gSaveContext.language == LANGUAGE_JPN) ? LANGUAGE_ENG : gSaveContext.language; + uint8_t textAlpha = this->archipelagoUIAlpha; + + uint8_t textIndex = 0; + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetArchipelagoSettingText(ASM_SERVER_ADDRESS, language), 70, + (80 + (textIndex * 16)), 255, 255, 255, textAlpha, 0.8f, true); + textIndex++; + Interface_DrawTextLine(this->state.gfxCtx, CVarGetString(CVAR_REMOTE_ARCHIPELAGO("ServerAddress"), "No Data"), 70, + (75 + (textIndex * 16)), 185, 185, 185, textAlpha, 0.8f, true); + + textIndex++; + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetArchipelagoSettingText(ASM_SLOT_NAME, language), 70, + (80 + (textIndex * 16)), 255, 255, 255, textAlpha, 0.8f, true); + textIndex++; + Interface_DrawTextLine(this->state.gfxCtx, CVarGetString(CVAR_REMOTE_ARCHIPELAGO("SlotName"), "No Data"), 70, + (75 + (textIndex * 16)), 185, 185, 185, textAlpha, 0.8f, true); + + + for (uint8_t index = 0; index <= ASM_CONNECT; index++) { + uint8_t textColorR = 255; + uint8_t textColorG = 255; + uint8_t textColorB = 255; + + // If current index is the selected one, make the text yellow. + if (this->archipelagoIndex == index) { + textColorB = 80; + } + + // todo, gray out text when connecting + + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetArchipelagoSettingText(index, language), 70, + (80 + ((5 + index) * 16)), textColorR, textColorG, textColorB, textAlpha, 0.8f, true); + } + + // Show text to indicate the client is connecting to the server. + if (connecting) { + Interface_DrawTextLine(this->state.gfxCtx, SohFileSelect_GetArchipelagoSettingText(ASM_CONNECTING, language), 70, + (80 + 64), 255, 255, 255, textAlpha, 0.8f, true); + } + + uint16_t textOffset = 16 * (5 + this->archipelagoIndex); + Gfx_SetupDL_39Opa(this->state.gfxCtx); + gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); + gDPLoadTextureBlock(POLY_OPA_DISP++, gArrowCursorTex, G_IM_FMT_IA, G_IM_SIZ_8b, 16, 24, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, G_TX_NOMASK, G_TX_NOLOD, + G_TX_NOLOD); + FileChoose_DrawTextRec(this->state.gfxCtx, this->stickRightPrompt.arrowColorR, + this->stickRightPrompt.arrowColorG, this->stickRightPrompt.arrowColorB, textAlpha, 62, + (85 + textOffset), 0.42f, 0, 0, 1.0f, 1.0f); + } else if (this->configMode != CM_ROTATE_TO_NAME_ENTRY && this->configMode != CM_START_BOSS_RUSH_MENU && this->configMode != CM_ROTATE_TO_BOSS_RUSH_MENU && this->configMode != CM_BOSS_RUSH_TO_QUEST && this->configMode != CM_START_RANDOMIZER_SETTINGS_MENU && this->configMode != CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU && this->configMode != CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST && - this->configMode != CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU) { + this->configMode != CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU && + this->configMode != CM_START_ARCHIPELAGO_SETTINGS_MENU && + this->configMode != CM_ROTATE_TO_ARCHIPELAGO_MENU && + this->configMode != CM_ARCHIPELAGO_SETTINGS_TO_QUEST && + this->configMode != CM_NAME_ENTRY_TO_ARCHIPELAGO_SETTINGS_MENU) { gDPPipeSync(POLY_OPA_DISP++); gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[1]); gDPLoadTextureBlock(POLY_OPA_DISP++, sTitleLabels[gSaveContext.language][this->nextTitleLabel], G_IM_FMT_IA, @@ -3060,6 +3232,7 @@ void FileChoose_ConfigModeDraw(GameState* thisx) { this->configMode == CM_ROTATE_TO_NAME_ENTRY || this->configMode == CM_QUEST_TO_MAIN || this->configMode == CM_NAME_ENTRY_TO_QUEST_MENU || this->configMode == CM_ROTATE_TO_BOSS_RUSH_MENU || this->configMode == CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU || + this->configMode == CM_ROTATE_TO_ARCHIPELAGO_MENU || this->configMode == CM_NAME_ENTRY_TO_RANDOMIZER_SETTINGS_MENU) { // window gDPPipeSync(POLY_OPA_DISP++); @@ -3093,7 +3266,11 @@ void FileChoose_ConfigModeDraw(GameState* thisx) { this->configMode == CM_START_BOSS_RUSH_MENU || this->configMode == CM_BOSS_RUSH_TO_QUEST || this->configMode == CM_RANDOMIZER_SETTINGS_MENU || this->configMode == CM_ROTATE_TO_RANDOMIZER_SETTINGS_MENU || this->configMode == CM_START_RANDOMIZER_SETTINGS_MENU || - this->configMode == CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST) { + this->configMode == CM_RANDOMIZER_SETTINGS_MENU_TO_QUEST || + this->configMode == CM_START_ARCHIPELAGO_SETTINGS_MENU || + this->configMode == CM_ARCHIPELAGO_SETTINGS_MENU || + this->configMode == CM_ROTATE_TO_ARCHIPELAGO_MENU || + this->configMode == CM_ARCHIPELAGO_SETTINGS_TO_QUEST) { // window gDPPipeSync(POLY_OPA_DISP++); gDPSetCombineMode(POLY_OPA_DISP++, G_CC_MODULATEIA_PRIM, G_CC_MODULATEIA_PRIM); @@ -3908,6 +4085,7 @@ void FileChoose_InitContext(GameState* thisx) { this->bossRushIndex = 0; this->bossRushOffset = 0; this->randomizerIndex = 0; + this->archipelagoIndex = 0; ShrinkWindow_SetVal(0);