From 820fdf78cc169d77ebfc9234a96284b2f6bea078 Mon Sep 17 00:00:00 2001 From: Adam Bird Date: Mon, 5 Jun 2023 17:18:18 -0400 Subject: [PATCH] Improve TTS for file select menus (#2950) * improve TTS for file select menus * french translation change recommendation --- .../accessibility/texts/filechoose_eng.json | 14 ++- .../accessibility/texts/filechoose_fra.json | 12 +- .../accessibility/texts/filechoose_ger.json | 12 +- .../game-interactor/GameInteractor.h | 4 + .../game-interactor/GameInteractor_Hooks.cpp | 16 +++ .../game-interactor/GameInteractor_Hooks.h | 4 + soh/soh/Enhancements/tts/tts.cpp | 108 +++++++++++++++++- .../ovl_file_choose/z_file_choose.c | 32 +++++- .../ovl_file_choose/z_file_copy_erase.c | 35 +++--- .../ovl_file_choose/z_file_nameset_PAL.c | 25 +++- 10 files changed, 234 insertions(+), 28 deletions(-) diff --git a/OTRExporter/assets/accessibility/texts/filechoose_eng.json b/OTRExporter/assets/accessibility/texts/filechoose_eng.json index ed70b4a4b..b61aa5ae0 100644 --- a/OTRExporter/assets/accessibility/texts/filechoose_eng.json +++ b/OTRExporter/assets/accessibility/texts/filechoose_eng.json @@ -7,10 +7,20 @@ "erase": "Erase", "quit": "Quit", "confirm": "Yes", + "end": "End", + "hyphen": "Hyphen", + "period": "Period", + "space": "Space", + "backspace": "Backspace", + "capital_letter": "Capital $0", "audio_stereo": "Sound - Stereo", "audio_mono": "Sound - Mono", "audio_headset": "Sound - Headset", "audio_surround": "Sound - Surround", - "target_switch": "Targetting Mode - Switch", - "target_hold": "Targetting Mode - Hold" + "target_switch": "Targeting Mode - Switch", + "target_hold": "Targeting Mode - Hold", + "quest_sel_vanilla": "Quest - Original", + "quest_sel_mq": "Quest - Master Quest", + "quest_sel_randomizer": "Quest - Randomizer", + "quest_sel_boss_rush": "Quest - Boss Rush" } \ No newline at end of file diff --git a/OTRExporter/assets/accessibility/texts/filechoose_fra.json b/OTRExporter/assets/accessibility/texts/filechoose_fra.json index 4e601ab3d..23be1ee3d 100644 --- a/OTRExporter/assets/accessibility/texts/filechoose_fra.json +++ b/OTRExporter/assets/accessibility/texts/filechoose_fra.json @@ -7,10 +7,20 @@ "erase": "Effacer", "quit": "Retour", "confirm": "Oui", + "end": "Fin", + "hyphen": "Trait d'union", + "period": "Point", + "space": "Espace", + "backspace": "Retour arrière", + "capital_letter": "Majuscule $0", "audio_stereo": "Son - Stéréo", "audio_mono": "Son - Mono", "audio_headset": "Son - Casque", "audio_surround": "Son - Surround", "target_switch": "Visée - Fixe", - "target_hold": "Visée - Maintenue" + "target_hold": "Visée - Maintenue", + "quest_sel_vanilla": "Quête - Originale", + "quest_sel_mq": "Quête - Master Quest", + "quest_sel_randomizer": "Quête - Randomizer", + "quest_sel_boss_rush": "Quête - Boss Rush" } \ No newline at end of file diff --git a/OTRExporter/assets/accessibility/texts/filechoose_ger.json b/OTRExporter/assets/accessibility/texts/filechoose_ger.json index 539466669..6c88f9d44 100644 --- a/OTRExporter/assets/accessibility/texts/filechoose_ger.json +++ b/OTRExporter/assets/accessibility/texts/filechoose_ger.json @@ -7,10 +7,20 @@ "erase": "Löschen", "quit": "Zurück", "confirm": "Ja", + "end": "Ende", + "hyphen": "Bindestrich", + "period": "Punkt", + "space": "Raum", + "backspace": "Rücktaste", + "capital_letter": "Großbuchstabe $0", "audio_stereo": "Sound - Stereo", "audio_mono": "Sound - Mono", "audio_headset": "Sound - Kopfhörer", "audio_surround": "Sound - Surround", "target_switch": "Zielerfassung - Einmal drücken", - "target_hold": "Zielerfassung - Trigger halten" + "target_hold": "Zielerfassung - Trigger halten", + "quest_sel_vanilla": "Quest - Original", + "quest_sel_mq": "Quest - Master Quest", + "quest_sel_randomizer": "Quest - Randomizer", + "quest_sel_boss_rush": "Quest - Bosse Rush" } \ No newline at end of file diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor.h b/soh/soh/Enhancements/game-interactor/GameInteractor.h index c2dd2c05f..193adb6c4 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor.h @@ -166,12 +166,16 @@ public: DEFINE_HOOK(OnPresentFileSelect, void()); DEFINE_HOOK(OnUpdateFileSelectSelection, void(uint16_t optionIndex)); + DEFINE_HOOK(OnUpdateFileSelectConfirmationSelection, void(uint16_t optionIndex)); DEFINE_HOOK(OnUpdateFileCopySelection, void(uint16_t optionIndex)); DEFINE_HOOK(OnUpdateFileCopyConfirmationSelection, void(uint16_t optionIndex)); DEFINE_HOOK(OnUpdateFileEraseSelection, void(uint16_t optionIndex)); DEFINE_HOOK(OnUpdateFileEraseConfirmationSelection, void(uint16_t optionIndex)); DEFINE_HOOK(OnUpdateFileAudioSelection, void(uint8_t optionIndex)); DEFINE_HOOK(OnUpdateFileTargetSelection, 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)); DEFINE_HOOK(OnSetGameLanguage, void()); diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp index e5159849e..7277d765f 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.cpp @@ -92,6 +92,10 @@ void GameInteractor_ExecuteOnUpdateFileSelectSelection(uint16_t optionIndex) { GameInteractor::Instance->ExecuteHooks(optionIndex); } +void GameInteractor_ExecuteOnUpdateFileSelectConfirmationSelection(uint16_t optionIndex) { + GameInteractor::Instance->ExecuteHooks(optionIndex); +} + void GameInteractor_ExecuteOnUpdateFileCopySelection(uint16_t optionIndex) { GameInteractor::Instance->ExecuteHooks(optionIndex); } @@ -116,6 +120,18 @@ void GameInteractor_ExecuteOnUpdateFileTargetSelection(uint8_t optionIndex) { GameInteractor::Instance->ExecuteHooks(optionIndex); } +void GameInteractor_ExecuteOnUpdateFileQuestSelection(uint8_t questIndex) { + GameInteractor::Instance->ExecuteHooks(questIndex); +} + +void GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(uint8_t optionIndex, uint8_t optionValue) { + GameInteractor::Instance->ExecuteHooks(optionIndex, optionValue); +} + +void GameInteractor_ExecuteOnUpdateFileNameSelection(int16_t charCode) { + GameInteractor::Instance->ExecuteHooks(charCode); +} + // MARK: - Game void GameInteractor_ExecuteOnSetGameLanguage() { diff --git a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h index 07843c950..edff2f84b 100644 --- a/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h +++ b/soh/soh/Enhancements/game-interactor/GameInteractor_Hooks.h @@ -32,12 +32,16 @@ void GameInteractor_ExecuteOnKaleidoscopeUpdate(int16_t inDungeonScene); // MARK: - Main Menu void GameInteractor_ExecuteOnPresentFileSelect(); void GameInteractor_ExecuteOnUpdateFileSelectSelection(uint16_t optionIndex); +void GameInteractor_ExecuteOnUpdateFileSelectConfirmationSelection(uint16_t optionIndex); void GameInteractor_ExecuteOnUpdateFileCopySelection(uint16_t optionIndex); void GameInteractor_ExecuteOnUpdateFileCopyConfirmationSelection(uint16_t optionIndex); 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_ExecuteOnUpdateFileQuestSelection(uint8_t questIndex); +void GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(uint8_t optionIndex, uint8_t optionValue); +void GameInteractor_ExecuteOnUpdateFileNameSelection(int16_t charCode); // MARK: - Game void GameInteractor_ExecuteOnSetGameLanguage(); diff --git a/soh/soh/Enhancements/tts/tts.cpp b/soh/soh/Enhancements/tts/tts.cpp index 29e39c7e5..fceb9c84a 100644 --- a/soh/soh/Enhancements/tts/tts.cpp +++ b/soh/soh/Enhancements/tts/tts.cpp @@ -9,8 +9,10 @@ #include "soh/OTRGlobals.h" #include "message_data_static.h" #include "overlays/gamestates/ovl_file_choose/file_choose.h" +#include "soh/Enhancements/boss-rush/BossRush.h" extern "C" { +extern SaveContext gSaveContext; extern PlayState* gPlayState; } @@ -67,7 +69,19 @@ std::string GetParameritizedText(std::string key, TextBank bank, const char* arg break; } case TEXT_BANK_FILECHOOSE: { - return fileChooseMap[key].get(); + auto value = fileChooseMap[key].get(); + + std::string searchString = "$0"; + size_t index = value.find(searchString); + + if (index != std::string::npos) { + ASSERT(arg != nullptr); + value.replace(index, searchString.size(), std::string(arg)); + return value; + } else { + return value; + } + break; } } @@ -350,7 +364,26 @@ void RegisterOnUpdateMainMenuSelection() { break; } }); - + + GameInteractor::Instance->RegisterGameHook([](uint16_t optionIndex) { + if (!CVarGetInteger("gA11yTTS", 0)) return; + + switch (optionIndex) { + case FS_BTN_CONFIRM_YES: { + auto translation = GetParameritizedText("confirm", TEXT_BANK_FILECHOOSE, nullptr); + SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); + break; + } + case FS_BTN_CONFIRM_QUIT: { + auto translation = GetParameritizedText("quit", TEXT_BANK_FILECHOOSE, nullptr); + SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); + break; + } + default: + break; + } + }); + GameInteractor::Instance->RegisterGameHook([](uint16_t optionIndex) { if (!CVarGetInteger("gA11yTTS", 0)) return; @@ -493,7 +526,78 @@ void RegisterOnUpdateMainMenuSelection() { default: break; } + }); + GameInteractor::Instance->RegisterGameHook([](uint8_t questIndex) { + if (!CVarGetInteger("gA11yTTS", 0)) return; + + switch (questIndex) { + case FS_QUEST_NORMAL: { + auto translation = GetParameritizedText("quest_sel_vanilla", TEXT_BANK_FILECHOOSE, nullptr); + SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); + break; + } + case FS_QUEST_MASTER: { + auto translation = GetParameritizedText("quest_sel_mq", TEXT_BANK_FILECHOOSE, nullptr); + SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); + break; + } + case FS_QUEST_RANDOMIZER: { + auto translation = GetParameritizedText("quest_sel_randomizer", TEXT_BANK_FILECHOOSE, nullptr); + SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); + break; + } + case FS_QUEST_BOSSRUSH: { + auto translation = GetParameritizedText("quest_sel_boss_rush", TEXT_BANK_FILECHOOSE, nullptr); + SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); + break; + } + default: + break; + } + }); + + GameInteractor::Instance->RegisterGameHook([](uint8_t optionIndex, uint8_t optionValue) { + if (!CVarGetInteger("gA11yTTS", 0)) return; + + auto optionName = BossRush_GetSettingName(optionIndex, gSaveContext.language); + auto optionValueName = BossRush_GetSettingChoiceName(optionIndex, optionValue, gSaveContext.language); + auto translation = optionName + std::string(" - ") + optionValueName; + SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); + }); + + GameInteractor::Instance->RegisterGameHook([](int16_t charCode) { + if (!CVarGetInteger("gA11yTTS", 0)) return; + + char charVal[2]; + std::string translation; + + if (charCode < 10) { // Digits + sprintf(charVal, "%c", charCode + 0x30); + } else if (charCode >= 10 && charCode < 36) { // Uppercase letters + sprintf(charVal, "%c", charCode + 0x37); + translation = GetParameritizedText("capital_letter", TEXT_BANK_FILECHOOSE, charVal); + } else if (charCode >= 36 && charCode < 62) { // Lowercase letters + sprintf(charVal, "%c", charCode + 0x3D); + } else if (charCode == 62) { // Space + translation = GetParameritizedText("space", TEXT_BANK_FILECHOOSE, nullptr); + } else if (charCode == 63) { // - + translation = GetParameritizedText("hyphen", TEXT_BANK_FILECHOOSE, nullptr); + } else if (charCode == 64) { // . + translation = GetParameritizedText("period", TEXT_BANK_FILECHOOSE, nullptr); + } else if (charCode == 0xF0 + FS_KBD_BTN_BACKSPACE) { + translation = GetParameritizedText("backspace", TEXT_BANK_FILECHOOSE, nullptr); + } else if (charCode == 0xF0 + FS_KBD_BTN_END) { + translation = GetParameritizedText("end", TEXT_BANK_FILECHOOSE, nullptr); + } else { + sprintf(charVal, "%c", charCode); + } + + if (translation.empty()) { + SpeechSynthesizer::Instance->Speak(charVal, GetLanguageCode()); + } else { + SpeechSynthesizer::Instance->Speak(translation.c_str(), GetLanguageCode()); + } }); } 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 8b9f3f317..e88e76a4a 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 @@ -383,7 +383,7 @@ void FileChoose_UpdateRandomizer() { } } -uint16_t lastFileChooseButtonIndex; +static s16 sLastFileChooseButtonIndex; /** * Update the cursor and wait for the player to select a button to change menus accordingly. @@ -441,6 +441,8 @@ void FileChoose_UpdateMainMenu(GameState* thisx) { this->nameEntryBoxPosX = 120; } + sLastFileChooseButtonIndex = -1; + this->actionTimer = 8; } else { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_ERROR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); @@ -487,10 +489,10 @@ void FileChoose_UpdateMainMenu(GameState* thisx) { } else { this->warningLabel = FS_WARNING_NONE; } - - if (lastFileChooseButtonIndex != this->buttonIndex) { + + if (sLastFileChooseButtonIndex != this->buttonIndex) { GameInteractor_ExecuteOnUpdateFileSelectSelection(this->buttonIndex); - lastFileChooseButtonIndex = this->buttonIndex; + sLastFileChooseButtonIndex = this->buttonIndex; } } } @@ -560,6 +562,8 @@ void FileChoose_StartQuestMenu(GameState* thisx) { if (this->logoAlpha >= 255) { this->logoAlpha = 255; this->configMode = CM_QUEST_MENU; + + GameInteractor_ExecuteOnUpdateFileQuestSelection(this->questType[this->buttonIndex]); } } @@ -614,6 +618,8 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) { } Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + + GameInteractor_ExecuteOnUpdateFileQuestSelection(this->questType[this->buttonIndex]); } if (CHECK_BTN_ALL(input->press.button, BTN_A)) { @@ -651,10 +657,14 @@ void FileChoose_UpdateQuestMenu(GameState* thisx) { if (CHECK_BTN_ALL(input->press.button, BTN_B)) { this->configMode = CM_QUEST_TO_MAIN; + sLastFileChooseButtonIndex = -1; return; } } +static s8 sLastBossRushOptionIndex = -1; +static s8 sLastBossRushOptionValue = -1; + void FileChoose_UpdateBossRushMenu(GameState* thisx) { FileChoose_UpdateStickDirectionPromptAnim(thisx); FileChooseContext* this = (FileChooseContext*)thisx; @@ -726,6 +736,13 @@ void FileChoose_UpdateBossRushMenu(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); } + if (sLastBossRushOptionIndex != this->bossRushIndex || + sLastBossRushOptionValue != gSaveContext.bossRushOptions[this->bossRushIndex]) { + GameInteractor_ExecuteOnUpdateFileBossRushOptionSelection(this->bossRushIndex, gSaveContext.bossRushOptions[this->bossRushIndex]); + sLastBossRushOptionIndex = this->bossRushIndex; + sLastBossRushOptionValue = gSaveContext.bossRushOptions[this->bossRushIndex]; + } + if (CHECK_BTN_ALL(input->press.button, BTN_B)) { this->configMode = CM_BOSS_RUSH_TO_QUEST; return; @@ -2072,6 +2089,7 @@ void FileChoose_FadeMainToSelect(GameState* thisx) { this->actionTimer = 8; this->selectMode++; this->confirmButtonIndex = FS_BTN_CONFIRM_YES; + sLastFileChooseButtonIndex = -1; } } @@ -2149,6 +2167,11 @@ void FileChoose_ConfirmFile(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->confirmButtonIndex ^= 1; } + + if (sLastFileChooseButtonIndex != this->confirmButtonIndex) { + GameInteractor_ExecuteOnUpdateFileSelectConfirmationSelection(this->confirmButtonIndex); + sLastFileChooseButtonIndex = this->confirmButtonIndex; + } } /** @@ -2169,6 +2192,7 @@ void FileChoose_FadeOutFileInfo(GameState* thisx) { this->nextTitleLabel = FS_TITLE_SELECT_FILE; this->actionTimer = 8; this->selectMode++; + sLastFileChooseButtonIndex = -1; } this->confirmButtonAlpha[0] = this->confirmButtonAlpha[1] = this->fileInfoAlpha[this->buttonIndex]; diff --git a/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c b/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c index da4e72a8e..f502d3ce4 100644 --- a/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c +++ b/soh/src/overlays/gamestates/ovl_file_choose/z_file_copy_erase.c @@ -54,7 +54,7 @@ void FileChoose_SetupCopySource(GameState* thisx) { } } -uint16_t lastCopyEraseButtonIndex; +static s16 sLastCopyEraseButtonIndex; /** * Allow the player to select a file to copy or exit back to the main menu. @@ -112,10 +112,10 @@ void FileChoose_SelectCopySource(GameState* thisx) { } } } - - if (lastCopyEraseButtonIndex != this->buttonIndex) { + + if (sLastCopyEraseButtonIndex != this->buttonIndex) { GameInteractor_ExecuteOnUpdateFileCopySelection(this->buttonIndex); - lastCopyEraseButtonIndex = this->buttonIndex; + sLastCopyEraseButtonIndex = this->buttonIndex; } } @@ -240,6 +240,11 @@ void FileChoose_SelectCopyDest(GameState* thisx) { this->warningLabel = FS_WARNING_NONE; } } + + if (sLastCopyEraseButtonIndex != this->buttonIndex) { + GameInteractor_ExecuteOnUpdateFileCopySelection(this->buttonIndex); + sLastCopyEraseButtonIndex = this->buttonIndex; + } } } @@ -386,10 +391,10 @@ void FileChoose_CopyConfirm(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->buttonIndex ^= 1; } - - if (lastCopyEraseButtonIndex != this->buttonIndex) { + + if (sLastCopyEraseButtonIndex != this->buttonIndex) { GameInteractor_ExecuteOnUpdateFileCopyConfirmationSelection(this->buttonIndex); - lastCopyEraseButtonIndex = this->buttonIndex; + sLastCopyEraseButtonIndex = this->buttonIndex; } } @@ -630,6 +635,8 @@ void FileChoose_ExitCopyToMain(GameState* thisx) { this->optionButtonAlpha = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] = this->actionButtonAlpha[FS_BTN_ACTION_COPY]; + + sLastCopyEraseButtonIndex = -1; } /** @@ -736,10 +743,10 @@ void FileChoose_EraseSelect(GameState* thisx) { this->warningLabel = FS_WARNING_NONE; } } - - if (lastCopyEraseButtonIndex != this->buttonIndex) { + + if (sLastCopyEraseButtonIndex != this->buttonIndex) { GameInteractor_ExecuteOnUpdateFileEraseSelection(this->buttonIndex); - lastCopyEraseButtonIndex = this->buttonIndex; + sLastCopyEraseButtonIndex = this->buttonIndex; } } @@ -850,10 +857,10 @@ void FileChoose_EraseConfirm(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->buttonIndex ^= 1; } - - if (lastCopyEraseButtonIndex != this->buttonIndex) { + + if (sLastCopyEraseButtonIndex != this->buttonIndex) { GameInteractor_ExecuteOnUpdateFileEraseConfirmationSelection(this->buttonIndex); - lastCopyEraseButtonIndex = this->buttonIndex; + sLastCopyEraseButtonIndex = this->buttonIndex; } } @@ -1084,4 +1091,6 @@ void FileChoose_ExitEraseToMain(GameState* thisx) { this->optionButtonAlpha = this->actionButtonAlpha[FS_BTN_ACTION_ERASE] = this->actionButtonAlpha[FS_BTN_ACTION_COPY]; + + sLastCopyEraseButtonIndex = -1; } 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 6ad5afb7e..17d63fb0d 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 @@ -102,6 +102,9 @@ static s16 D_80812604[] = { 0x0048, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, 0x0045, }; +static s16 sLastCharIndex = -1; +static s16 sLastKbdX = -1; + /** * Set vertices used by all elements of the name entry screen that are NOT the keyboard. * This includes the cursor highlight, the name entry plate and characters, and the buttons. @@ -373,6 +376,7 @@ void FileChoose_DrawNameEntry(GameState* thisx) { this->configMode = CM_NAME_ENTRY_TO_MAIN; } this->prevConfigMode = CM_NAME_ENTRY; + sLastCharIndex = -1; CVarSetInteger("gOnFileSelectNameEntry", 0); } else { for (i = this->newFileNameCharCount; i < 7; i++) { @@ -628,6 +632,16 @@ void FileChoose_UpdateKeyboardCursor(GameState* thisx) { if (this->kbdY == 5) { this->kbdButton = this->kbdX; + + if (sLastKbdX != this->kbdX) { + GameInteractor_ExecuteOnUpdateFileNameSelection(0xF0 + this->kbdX); + sLastKbdX = this->kbdX; + sLastCharIndex = -1; + } + } else if (sLastCharIndex != this->charIndex && this->charIndex < 65) { + GameInteractor_ExecuteOnUpdateFileNameSelection(D_808123F0[this->charIndex]); + sLastCharIndex = this->charIndex; + sLastKbdX = -1; } } @@ -656,7 +670,7 @@ void FileChoose_StartOptions(GameState* thisx) { } static u8 sSelectedSetting; -int8_t lastOptionButtonIndex = -1; +static s8 sLastOptionButtonIndex = -1; /** * Update the cursor and appropriate settings for the options menu. @@ -673,6 +687,7 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) { Audio_PlaySoundGeneral(NA_SE_SY_FSEL_DECIDE_L, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); this->prevConfigMode = this->configMode; this->configMode = CM_OPTIONS_TO_MAIN; + sLastOptionButtonIndex = -1; osSyncPrintf("SAVE"); Save_SaveGlobal(); osSyncPrintf(VT_FGCOL(YELLOW)); @@ -721,15 +736,15 @@ void FileChoose_UpdateOptionsMenu(GameState* thisx) { } if (sSelectedSetting == FS_SETTING_AUDIO) { - if (lastOptionButtonIndex != gSaveContext.audioSetting) { + if (sLastOptionButtonIndex != gSaveContext.audioSetting) { GameInteractor_ExecuteOnUpdateFileAudioSelection(gSaveContext.audioSetting); - lastOptionButtonIndex = gSaveContext.audioSetting; + sLastOptionButtonIndex = gSaveContext.audioSetting; } } else { // offset to detect switching between modes - if (lastOptionButtonIndex != FS_BTN_SELECT_QUIT + gSaveContext.zTargetSetting + 1) { + if (sLastOptionButtonIndex != FS_BTN_SELECT_QUIT + gSaveContext.zTargetSetting + 1) { GameInteractor_ExecuteOnUpdateFileTargetSelection(gSaveContext.zTargetSetting); - lastOptionButtonIndex = FS_BTN_SELECT_QUIT + gSaveContext.zTargetSetting + 1; + sLastOptionButtonIndex = FS_BTN_SELECT_QUIT + gSaveContext.zTargetSetting + 1; } } }