diff --git a/OTRExporter/assets/accessibility/texts/filechoose_eng.json b/OTRExporter/assets/accessibility/texts/filechoose_eng.json
index b61aa5ae0..b43719926 100644
--- a/OTRExporter/assets/accessibility/texts/filechoose_eng.json
+++ b/OTRExporter/assets/accessibility/texts/filechoose_eng.json
@@ -19,6 +19,9 @@
"audio_surround": "Sound - Surround",
"target_switch": "Targeting Mode - Switch",
"target_hold": "Targeting Mode - Hold",
+ "language_english": "Language - English",
+ "language_german": "Language - German",
+ "language_french": "Language - French",
"quest_sel_vanilla": "Quest - Original",
"quest_sel_mq": "Quest - Master Quest",
"quest_sel_randomizer": "Quest - Randomizer",
diff --git a/OTRExporter/assets/accessibility/texts/filechoose_fra.json b/OTRExporter/assets/accessibility/texts/filechoose_fra.json
index 23be1ee3d..f76861f21 100644
--- a/OTRExporter/assets/accessibility/texts/filechoose_fra.json
+++ b/OTRExporter/assets/accessibility/texts/filechoose_fra.json
@@ -19,6 +19,9 @@
"audio_surround": "Son - Surround",
"target_switch": "Visée - Fixe",
"target_hold": "Visée - Maintenue",
+ "language_english": "Langue - Anglaise",
+ "language_german": "Langue - Allemande",
+ "language_french": "Langue - Français",
"quest_sel_vanilla": "Quête - Originale",
"quest_sel_mq": "Quête - Master Quest",
"quest_sel_randomizer": "Quête - Randomizer",
diff --git a/OTRExporter/assets/accessibility/texts/filechoose_ger.json b/OTRExporter/assets/accessibility/texts/filechoose_ger.json
index 6c88f9d44..2ad1322fd 100644
--- a/OTRExporter/assets/accessibility/texts/filechoose_ger.json
+++ b/OTRExporter/assets/accessibility/texts/filechoose_ger.json
@@ -19,6 +19,9 @@
"audio_surround": "Sound - Surround",
"target_switch": "Zielerfassung - Einmal drücken",
"target_hold": "Zielerfassung - Trigger halten",
+ "language_english": "Sprache - Englisch",
+ "language_german": "Sprache - Deutsch",
+ "language_french": "Sprache - Französisch",
"quest_sel_vanilla": "Quest - Original",
"quest_sel_mq": "Quest - Master Quest",
"quest_sel_randomizer": "Quest - Randomizer",
diff --git a/soh/assets/soh_assets.h b/soh/assets/soh_assets.h
index 667a9ff1a..b1feac469 100644
--- a/soh/assets/soh_assets.h
+++ b/soh/assets/soh_assets.h
@@ -44,6 +44,10 @@ static const ALIGN_ASSET(2) char gTitleRandomizerSubtitleTex[] = dgTitleRandomiz
#define dgTitleBossRushSubtitleTex "__OTR__objects/object_mag/gTitleBossRushSubtitleTex"
static const ALIGN_ASSET(2) char gTitleBossRushSubtitleTex[] = dgTitleBossRushSubtitleTex;
+// overlays
+#define dgOptionsDividerChangeLangVtx "__OTR__overlays/ovl_file_choose/gOptionsDividerChangeLangVtx"
+static const ALIGN_ASSET(2) char gOptionsDividerChangeLangVtx[] = dgOptionsDividerChangeLangVtx;
+
// textures
#define dgDPad "__OTR__textures/parameter_static/gDPad"
static const ALIGN_ASSET(2) char gDPadTex[] = dgDPad;
@@ -78,5 +82,23 @@ static const ALIGN_ASSET(2) char gFileSelBossRushSettingsGERText[] = dgFileSelBo
#define dgFileSelRANDButtonTex "__OTR__textures/title_static/gFileSelRANDButtonTex"
static const ALIGN_ASSET(2) char gFileSelRANDButtonTex[] = dgFileSelRANDButtonTex;
+#define dgFileSelLangEnglishENGTex "__OTR__textures/title_static/gFileSelLangEnglishENGTex"
+static const ALIGN_ASSET(2) char gFileSelLangEnglishENGTex[] = dgFileSelLangEnglishENGTex;
+
+#define dgFileSelLangDeutschGERTex "__OTR__textures/title_static/gFileSelLangDeutschGERTex"
+static const ALIGN_ASSET(2) char gFileSelLangDeutschGERTex[] = dgFileSelLangDeutschGERTex;
+
+#define dgFileSelLangFrancaisFRATex "__OTR__textures/title_static/gFileSelLangFrancaisFRATex"
+static const ALIGN_ASSET(2) char gFileSelLangFrancaisFRATex[] = dgFileSelLangFrancaisFRATex;
+
+#define dgFileSelLanguageENGTex "__OTR__textures/title_static/gFileSelLanguageENGTex"
+static const ALIGN_ASSET(2) char gFileSelLanguageENGTex[] = dgFileSelLanguageENGTex;
+
+#define dgFileSelLanguageFRATex "__OTR__textures/title_static/gFileSelLanguageFRATex"
+static const ALIGN_ASSET(2) char gFileSelLanguageFRATex[] = dgFileSelLanguageFRATex;
+
+#define dgFileSelLanguageGERTex "__OTR__textures/title_static/gFileSelLanguageGERTex"
+static const ALIGN_ASSET(2) char gFileSelLanguageGERTex[] = dgFileSelLanguageGERTex;
+
#define dgEmptyTexture "__OTR__textures/virtual/gEmptyTexture"
static const ALIGN_ASSET(2) char gEmptyTexture[] = dgEmptyTexture;
diff --git a/soh/assets/xml/N64_PAL_11/overlays/ovl_File_Choose.xml b/soh/assets/xml/N64_PAL_11/overlays/ovl_File_Choose.xml
index de41882eb..b97861d62 100644
--- a/soh/assets/xml/N64_PAL_11/overlays/ovl_File_Choose.xml
+++ b/soh/assets/xml/N64_PAL_11/overlays/ovl_File_Choose.xml
@@ -3,18 +3,16 @@
-
+
-
-
-
+
+
-
+
@@ -26,6 +24,9 @@
-
+
+
+
+
diff --git a/soh/assets/xml/N64_PAL_11/textures/title_static.xml b/soh/assets/xml/N64_PAL_11/textures/title_static.xml
index 7367190a9..eb8d3288f 100644
--- a/soh/assets/xml/N64_PAL_11/textures/title_static.xml
+++ b/soh/assets/xml/N64_PAL_11/textures/title_static.xml
@@ -185,6 +185,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h
index 79a2cb465..546a70635 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h
@@ -175,6 +175,7 @@ public:
DEFINE_HOOK(OnUpdateFileEraseConfirmationSelection, void(uint16_t optionIndex));
DEFINE_HOOK(OnUpdateFileAudioSelection, void(uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileTargetSelection, void(uint8_t optionIndex));
+ DEFINE_HOOK(OnUpdateFileLanguageSelection, void(uint8_t optionIndex));
DEFINE_HOOK(OnUpdateFileQuestSelection, void(uint8_t questIndex));
DEFINE_HOOK(OnUpdateFileBossRushOptionSelection, void(uint8_t optionIndex, uint8_t optionValue));
DEFINE_HOOK(OnUpdateFileNameSelection, void(int16_t charCode));
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
index e96474996..75879e3e6 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp
@@ -132,6 +132,10 @@ void GameInteractor_ExecuteOnUpdateFileTargetSelection(uint8_t optionIndex) {
GameInteractor::Instance->ExecuteHooks(optionIndex);
}
+void GameInteractor_ExecuteOnUpdateFileLanguageSelection(uint8_t optionIndex) {
+ GameInteractor::Instance->ExecuteHooks(optionIndex);
+}
+
void GameInteractor_ExecuteOnUpdateFileQuestSelection(uint8_t questIndex) {
GameInteractor::Instance->ExecuteHooks(questIndex);
}
diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
index c69a8ec24..ca21b9a6b 100644
--- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
+++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h
@@ -42,6 +42,7 @@ void GameInteractor_ExecuteOnUpdateFileEraseSelection(uint16_t optionIndex);
void GameInteractor_ExecuteOnUpdateFileEraseConfirmationSelection(uint16_t optionIndex);
void GameInteractor_ExecuteOnUpdateFileAudioSelection(uint8_t optionIndex);
void GameInteractor_ExecuteOnUpdateFileTargetSelection(uint8_t optionIndex);
+void GameInteractor_ExecuteOnUpdateFileLanguageSelection(uint8_t optionIndex);
void GameInteractor_ExecuteOnUpdateFileQuestSelection(uint8_t questIndex);
void GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(uint8_t optionIndex, uint8_t optionValue);
void GameInteractor_ExecuteOnUpdateFileNameSelection(int16_t charCode);
diff --git a/soh/soh/Enhancements/tts/tts.cpp b/soh/soh/Enhancements/tts/tts.cpp
index 128ab4b1e..3387bfd21 100644
--- a/soh/soh/Enhancements/tts/tts.cpp
+++ b/soh/soh/Enhancements/tts/tts.cpp
@@ -674,7 +674,7 @@ void RegisterOnUpdateMainMenuSelection() {
break;
}
});
-
+
GameInteractor::Instance->RegisterGameHook([](uint8_t optionIndex) {
if (!CVarGetInteger("gA11yTTS", 0)) return;
@@ -694,6 +694,30 @@ void RegisterOnUpdateMainMenuSelection() {
}
});
+ GameInteractor::Instance->RegisterGameHook([](uint8_t optionIndex) {
+ if (!CVarGetInteger("gA11yTTS", 0)) return;
+
+ switch (optionIndex) {
+ case LANGUAGE_ENG: {
+ auto translation = GetParameritizedText("language_english", TEXT_BANK_FILECHOOSE, nullptr);
+ SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
+ break;
+ }
+ case LANGUAGE_GER: {
+ auto translation = GetParameritizedText("language_german", TEXT_BANK_FILECHOOSE, nullptr);
+ SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
+ break;
+ }
+ case LANGUAGE_FRA: {
+ auto translation = GetParameritizedText("language_french", TEXT_BANK_FILECHOOSE, nullptr);
+ SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode());
+ break;
+ }
+ default:
+ break;
+ }
+ });
+
GameInteractor::Instance->RegisterGameHook([](uint8_t questIndex) {
if (!CVarGetInteger("gA11yTTS", 0)) return;
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 f4a23d38b..3f76ebd0d 100644
--- a/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h
+++ b/soh/src/overlays/gamestates/ovl_file_choose/file_choose.h
@@ -142,7 +142,8 @@ typedef enum {
typedef enum {
/* 0 */ FS_SETTING_AUDIO,
- /* 1 */ FS_SETTING_TARGET
+ /* 1 */ FS_SETTING_TARGET,
+ /* 2 */ FS_SETTING_LANGUAGE, // PAL N64 only
} SettingIndex;
typedef enum {
diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c
index 44cb67987..377c23eb3 100644
--- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c
+++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_nameset_PAL.c
@@ -1,6 +1,7 @@
#include "file_choose.h"
#include "textures/title_static/title_static.h"
#include "assets/overlays/ovl_File_Choose/ovl_file_choose.h"
+#include "assets/soh_assets.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
@@ -702,6 +703,11 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) {
return;
}
+ uint8_t languageChanged = 0;
+ uint8_t versionIndex = ResourceMgr_GameHasMasterQuest() && ResourceMgr_GameHasOriginal();
+ uint8_t isPalN64 = ResourceMgr_GetGameRegion(versionIndex) == GAME_REGION_PAL &&
+ ResourceMgr_GetGamePlatform(versionIndex) == GAME_PLATFORM_N64;
+
if ((this->stickRelX < -30) || (dpad && CHECK_BTN_ALL(input->press.button, BTN_DLEFT))) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
@@ -712,6 +718,14 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) {
if (gSaveContext.audioSetting > 0xF0) {
gSaveContext.audioSetting = FS_AUDIO_SURROUND;
}
+ } else if (sSelectedSetting == FS_SETTING_LANGUAGE) {
+ gSaveContext.language--;
+
+ if (gSaveContext.language > 0xF0) {
+ gSaveContext.language = LANGUAGE_FRA;
+ }
+
+ languageChanged = 1;
} else {
gSaveContext.zTargetSetting ^= 1;
}
@@ -724,29 +738,75 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) {
if (gSaveContext.audioSetting > FS_AUDIO_SURROUND) {
gSaveContext.audioSetting = FS_AUDIO_STEREO;
}
+ } else if (sSelectedSetting == FS_SETTING_LANGUAGE) {
+ gSaveContext.language++;
+
+ if (gSaveContext.language > LANGUAGE_FRA) {
+ gSaveContext.language = LANGUAGE_ENG;
+ }
+
+ languageChanged = 1;
} else {
gSaveContext.zTargetSetting ^= 1;
}
}
- if ((ABS(this->stickRelY) > 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP))) {
+ // Persist the new language so it is not overridden on the next frame
+ if (languageChanged) {
+ CVarSetInteger("gLanguages", gSaveContext.language);
+ GameInteractor_ExecuteOnSetGameLanguage();
+ }
+
+ // NTSC and GC only has two rows and can just flip the setting bit
+ // Otherwise for PAL 64, handle the additional change language setting
+ if (!isPalN64 && ((ABS(this->stickRelY) > 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN | BTN_DUP)))) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
sSelectedSetting ^= 1;
+ } else if (isPalN64 && ((this->stickRelY > 30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DUP)))) {
+ Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
+ sSelectedSetting--;
+
+ if (sSelectedSetting > 0xF0) {
+ sSelectedSetting = FS_SETTING_LANGUAGE;
+ }
+ } else if (isPalN64 && ((this->stickRelY < -30) || (dpad && CHECK_BTN_ANY(input->press.button, BTN_DDOWN)))) {
+ Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
+ sSelectedSetting++;
+
+ if (sSelectedSetting > FS_SETTING_LANGUAGE) {
+ sSelectedSetting = FS_SETTING_AUDIO;
+ }
} else if (CHECK_BTN_ALL(input->press.button, BTN_A)) {
Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8);
- sSelectedSetting ^= 1;
+ if (isPalN64) {
+ sSelectedSetting++;
+
+ if (sSelectedSetting > FS_SETTING_LANGUAGE) {
+ sSelectedSetting = FS_SETTING_AUDIO;
+ }
+ } else {
+ sSelectedSetting ^= 1;
+ }
}
-
+
if (sSelectedSetting == FS_SETTING_AUDIO) {
if (sLastOptionButtonIndex != gSaveContext.audioSetting) {
GameInteractor_ExecuteOnUpdateFileAudioSelection(gSaveContext.audioSetting);
sLastOptionButtonIndex = gSaveContext.audioSetting;
}
+ } else if (sSelectedSetting == FS_SETTING_TARGET) {
+ // offset to detect switching between modes
+ u8 optionOffset = gSaveContext.zTargetSetting + FS_AUDIO_SURROUND + FS_SETTING_TARGET;
+ if (sLastOptionButtonIndex != optionOffset) {
+ GameInteractor_ExecuteOnUpdateFileTargetSelection(gSaveContext.zTargetSetting);
+ sLastOptionButtonIndex = optionOffset;
+ }
} else {
// offset to detect switching between modes
- if (sLastOptionButtonIndex != FS_BTN_SELECT_QUIT + gSaveContext.zTargetSetting + 1) {
- GameInteractor_ExecuteOnUpdateFileTargetSelection(gSaveContext.zTargetSetting);
- sLastOptionButtonIndex = FS_BTN_SELECT_QUIT + gSaveContext.zTargetSetting + 1;
+ u8 optionOffset = gSaveContext.language + FS_AUDIO_SURROUND + FS_TARGET_HOLD + FS_SETTING_LANGUAGE;
+ if (sLastOptionButtonIndex != optionOffset) {
+ GameInteractor_ExecuteOnUpdateFileLanguageSelection(gSaveContext.language);
+ sLastOptionButtonIndex = optionOffset;
}
}
}
@@ -778,6 +838,11 @@ static OptionsMenuTextureInfo gOptionsMenuHeaders[] = {
{ 128, 128, 128 },
16,
},
+ {
+ { gFileSelLanguageENGTex, gFileSelLanguageGERTex, gFileSelLanguageFRATex },
+ { 64, 64, 64 },
+ 16,
+ },
};
static OptionsMenuTextureInfo gOptionsMenuSettings[] = {
@@ -811,6 +876,21 @@ static OptionsMenuTextureInfo gOptionsMenuSettings[] = {
{ 48, 80, 48 },
16,
},
+ {
+ { gFileSelLangEnglishENGTex, gFileSelLangEnglishENGTex, gFileSelLangEnglishENGTex },
+ { 48, 48, 48 },
+ 16,
+ },
+ {
+ { gFileSelLangDeutschGERTex, gFileSelLangDeutschGERTex, gFileSelLangDeutschGERTex },
+ { 48, 48, 48 },
+ 16,
+ },
+ {
+ { gFileSelLangFrancaisFRATex, gFileSelLangFrancaisFRATex, gFileSelLangFrancaisFRATex },
+ { 48, 48, 48 },
+ 16,
+ },
};
void FileChoose_DrawOptionsImpl(GameState* thisx) {
@@ -943,12 +1023,22 @@ void FileChoose_DrawOptionsImpl(GameState* thisx) {
}
}
+ // Draw the change language header
+ if (isPalN64) {
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gOptionsMenuHeaders[i].texture[gSaveContext.language], G_IM_FMT_IA,
+ G_IM_SIZ_8b, gOptionsMenuHeaders[i].width[gSaveContext.language],
+ gOptionsMenuHeaders[i].height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
+ G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
+
+ gSP1Quadrangle(POLY_OPA_DISP++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+ }
+
if (gSaveContext.language == LANGUAGE_GER && isPalGC) {
gSPVertex(POLY_OPA_DISP++, D_80812130, 32, 0);
} else {
// PAL N64 has extra german vertices combined in the regular array instead of a dedicated array
if (isPalN64) {
- gSPVertex(POLY_OPA_DISP++, D_80811F30, 40, 0);
+ gSPVertex(POLY_OPA_DISP++, D_80811F30, 52, 0);
} else {
gSPVertex(POLY_OPA_DISP++, D_80811F30, 32, 0);
}
@@ -981,7 +1071,7 @@ void FileChoose_DrawOptionsImpl(GameState* thisx) {
gDPPipeSync(POLY_OPA_DISP++);
if (i == (gSaveContext.zTargetSetting + 4)) {
- if (sSelectedSetting != FS_SETTING_AUDIO) {
+ if (sSelectedSetting == FS_SETTING_TARGET) {
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, cursorPrimRed, cursorPrimGreen, cursorPrimBlue,
this->titleAlpha[0]);
gDPSetEnvColor(POLY_OPA_DISP++, cursorEnvRed, cursorEnvGreen, cursorEnvBlue, 0xFF);
@@ -998,7 +1088,7 @@ void FileChoose_DrawOptionsImpl(GameState* thisx) {
G_IM_SIZ_8b, gOptionsMenuSettings[i].width[gSaveContext.language],
gOptionsMenuSettings[i].height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
- // Pal N64 German vertices for z target options are offset an by 8
+ // Pal N64 German vertices for z target options are offset by 8
if (gSaveContext.language == LANGUAGE_GER && isPalN64) {
gSP1Quadrangle(POLY_OPA_DISP++, vtx + 8, vtx + 2 + 8, vtx + 3 + 8, vtx + 1 + 8, 0);
} else {
@@ -1030,6 +1120,33 @@ void FileChoose_DrawOptionsImpl(GameState* thisx) {
vtx += 4;
+ // Draw the language options
+ if (isPalN64) {
+ for (; i < 9; i++, vtx += 4) {
+ gDPPipeSync(POLY_OPA_DISP++);
+
+ if (i == (gSaveContext.language + 6)) {
+ if (sSelectedSetting == FS_SETTING_LANGUAGE) {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, cursorPrimRed, cursorPrimGreen, cursorPrimBlue,
+ this->titleAlpha[0]);
+ gDPSetEnvColor(POLY_OPA_DISP++, cursorEnvRed, cursorEnvGreen, cursorEnvBlue, 0xFF);
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, this->titleAlpha[0]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ }
+ } else {
+ gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 120, 120, 120, this->titleAlpha[0]);
+ gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255);
+ }
+
+ gDPLoadTextureBlock(POLY_OPA_DISP++, gOptionsMenuSettings[i].texture[gSaveContext.language], G_IM_FMT_IA,
+ G_IM_SIZ_8b, gOptionsMenuSettings[i].width[gSaveContext.language],
+ gOptionsMenuSettings[i].height, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP,
+ G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD);
+ gSP1Quadrangle(POLY_OPA_DISP++, vtx, vtx + 2, vtx + 3, vtx + 1, 0);
+ }
+ }
+
// blue divider lines
gDPPipeSync(POLY_OPA_DISP++);
gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 255, 255, this->titleAlpha[0]);
@@ -1064,6 +1181,17 @@ void FileChoose_DrawOptionsImpl(GameState* thisx) {
gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
Matrix_Pop();
+ // Draw the divider for change language header
+ if (isPalN64) {
+ Matrix_Push();
+ Matrix_Translate(0.0f, 0.3f, 0.0f, MTXMODE_APPLY);
+ gSPMatrix(POLY_OPA_DISP++, MATRIX_NEWMTX(this->state.gfxCtx),
+ G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
+ gSPVertex(POLY_OPA_DISP++, gOptionsDividerChangeLangVtx, 4, 0);
+ gSP1Quadrangle(POLY_OPA_DISP++, 0, 2, 3, 1, 0);
+ Matrix_Pop();
+ }
+
CLOSE_DISPS(this->state.gfxCtx);
}