From 9dbf5cd0005bcda2d63d2758e380031119f0de4e Mon Sep 17 00:00:00 2001 From: Ryan Conrad Date: Wed, 13 Apr 2022 11:03:34 -0500 Subject: [PATCH 1/4] Improve reading messages with choice prompts Pause before reading the choices as well as in between chioces --- soh/src/code/z_message_PAL.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 2439a8edd..2444771cd 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -3011,6 +3011,7 @@ void Message_Draw(GlobalContext* globalCtx) { void Message_TTS_Decode(u8* srcBuf, u8* dstBuf, u32 srcOffset, u32 size) { u32 dstIdx = 0; + bool isListingChoices = false; for (u32 i = 0; i < size; i++) { u8 currChar = srcBuf[i + srcOffset]; @@ -3018,7 +3019,12 @@ void Message_TTS_Decode(u8* srcBuf, u8* dstBuf, u32 srcOffset, u32 size) { if (currChar < ' ') { switch (currChar) { case MESSAGE_NEWLINE: - dstBuf[dstIdx++] = ' '; + dstBuf[dstIdx++] = (isListingChoices) ? '\n' : ' '; + break; + case MESSAGE_THREE_CHOICE: + case MESSAGE_TWO_CHOICE: + dstBuf[dstIdx++] = '\n'; + isListingChoices = true; break; case MESSAGE_COLOR: case MESSAGE_SHIFT: From a0ef95dd25c38f00890dab379d14c6641b7b114a Mon Sep 17 00:00:00 2001 From: Ryan Conrad Date: Wed, 13 Apr 2022 11:32:41 -0500 Subject: [PATCH 2/4] Slightly improve TTS timing in some cases --- soh/src/code/z_message_PAL.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index 2444771cd..18cc10496 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -3059,7 +3059,11 @@ void Message_TTS_Update(GlobalContext* globalCtx) { } else if (msgCtx->msgMode == MSGMODE_TEXT_DISPLAYING || msgCtx->msgMode == MSGMODE_OCARINA_STARTING || msgCtx->msgMode == MSGMODE_OCARINA_PLAYING || msgCtx->msgMode == MSGMODE_TEXT_AWAIT_NEXT || msgCtx->msgMode == MSGMODE_TEXT_DONE || msgCtx->msgMode == MSGMODE_DISPLAY_SONG_PLAYED_TEXT || - msgCtx->msgMode == MSGMODE_TEXT_DELAYED_BREAK) { + msgCtx->msgMode == MSGMODE_TEXT_DELAYED_BREAK || msgCtx->msgMode == MSGMODE_SONG_PLAYED_ACT_BEGIN || + msgCtx->msgMode == MSGMODE_SONG_PLAYED_ACT || msgCtx->msgMode == MSGMODE_SONG_PLAYBACK_STARTING || + msgCtx->msgMode == MSGMODE_SONG_PLAYBACK || msgCtx->msgMode == MSGMODE_SONG_DEMONSTRATION_STARTING || + msgCtx->msgMode == MSGMODE_SONG_DEMONSTRATION_SELECT_INSTRUMENT || + msgCtx->msgMode == MSGMODE_SONG_DEMONSTRATION) { if (sTtsHasNewMessage == 1) { sTtsHasNewMessage = 0; sTtsHasMessage = 1; From f6a1e8ee9c921a9588cb98533f3de71941774e0f Mon Sep 17 00:00:00 2001 From: Ryan Conrad Date: Wed, 13 Apr 2022 18:52:34 -0500 Subject: [PATCH 3/4] Add more TTS, use otr mod to load a11y strings Now reads title cards and item ammo amounts Also reads skull tokens and heart container amounts The OTR mod is not included in this commit --- soh/soh/z_message_OTR.cpp | 38 ++++ soh/src/code/z_actor.c | 51 +++++ .../ovl_kaleido_scope/z_kaleido_collect.c | 58 ++---- .../ovl_kaleido_scope/z_kaleido_equipment.c | 99 +--------- .../misc/ovl_kaleido_scope/z_kaleido_item.c | 185 ++---------------- .../ovl_kaleido_scope/z_kaleido_map_PAL.c | 14 ++ 6 files changed, 140 insertions(+), 305 deletions(-) diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index 354997e16..5bc00dd7f 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -6,11 +6,47 @@ #include "global.h" #include "vt.h" #include +#include extern "C" MessageTableEntry* sNesMessageEntryTablePtr; extern "C" MessageTableEntry* sStaffMessageEntryTablePtr; //extern "C" MessageTableEntry* _message_0xFFFC_nes; +static std::unordered_map sAccessibilityText; +static std::string sTextInterpolated; +extern "C" void OTRMessage_InitAccessibilityText() +{ + auto file = std::static_pointer_cast( + OTRGlobals::Instance->context->GetResourceManager()->LoadResource("text/accessibility_text/accessibility_text_eng")); + + for (int i = 0; i < file->messages.size(); i++) + { + sAccessibilityText[file->messages[i].id] = file->messages[i].msg; + } +} +extern "C" const char * OTRMessage_GetAccessibilityText(const char * textResourcePath, u16 textId, const char * arg) +{ + auto it = sAccessibilityText.find(textId); + if (it == sAccessibilityText.end()) + { + return nullptr; + } + + if (arg != nullptr) + { + sTextInterpolated = it->second; + std::string searchString = "$0"; + size_t index = sTextInterpolated.find(searchString); + if (index != std::string::npos) + { + sTextInterpolated.replace(index, searchString.size(), std::string(arg)); + return sTextInterpolated.c_str(); + } + } + + return it->second.c_str(); +} + extern "C" void OTRMessage_Init() { auto file = std::static_pointer_cast(OTRGlobals::Instance->context->GetResourceManager()->LoadResource("text/nes_message_data_static/nes_message_data_static")); @@ -41,4 +77,6 @@ extern "C" void OTRMessage_Init() sStaffMessageEntryTablePtr[i].segment = file2->messages[i].msg.c_str(); sStaffMessageEntryTablePtr[i].msgSize = file2->messages[i].msg.size(); } + + OTRMessage_InitAccessibilityText(); } \ No newline at end of file diff --git a/soh/src/code/z_actor.c b/soh/src/code/z_actor.c index 976ec0386..b2e948512 100644 --- a/soh/src/code/z_actor.c +++ b/soh/src/code/z_actor.c @@ -763,9 +763,46 @@ void func_8002CDE4(GlobalContext* globalCtx, TitleCardContext* titleCtx) { titleCtx->durationTimer = titleCtx->delayTimer = titleCtx->intensity = titleCtx->alpha = 0; } +static u8* sTitleCardText; + void TitleCard_InitBossName(GlobalContext* globalCtx, TitleCardContext* titleCtx, void* texture, s16 x, s16 y, u8 width, u8 height) { + //TODO: improve + char* texturePath = (char*)texture; + s16 bossActorId = 0; + if (!strcmp(texturePath, "__OTR__objects/object_kingdodongo/gKingDodongoTitleCardTex")) { + // gKingDodongoTitleCardTex + bossActorId = ACTOR_EN_DODONGO; + } else if (!strcmp(texturePath, "__OTR__objects/object_fd/gVolvagiaBossTitleCardTex")) { + // gVolvagiaTitleCardTex + bossActorId = ACTOR_BOSS_FD; + } else if (!strcmp(texturePath, "__OTR__objects/object_ganon/gDorfTitleCardTex")) { + // gDorfTitleCardTex + bossActorId = ACTOR_BOSS_GANON; + } else if (!strcmp(texturePath, "__OTR__objects/object_ganon2/object_ganon2_Tex_021A90")) { + // object_ganon2_Tex_021A90 + bossActorId = ACTOR_BOSS_GANON2; + } else if (!strcmp(texturePath, "__OTR__objects/object_goma/gGohmaTitleCardTex")) { + // gGohmaTitleCardTex + bossActorId = ACTOR_BOSS_GOMA; + } else if (!strcmp(texturePath, "__OTR__objects/object_mo/gMorphaTitleCardTex")) { + // gMorphaTitleCardTex + bossActorId = ACTOR_BOSS_MO; + } else if (!strcmp(texturePath, "__OTR__objects/object_sst/gBongoTitleCardTex")) { + // gBongoTitleCardTex + bossActorId = ACTOR_BOSS_SST; + } else if (!strcmp(texturePath, "__OTR__objects/object_tw/gTwinrovaTitleCardTex")) { + // gTwinrovaTitleCardTex + bossActorId = ACTOR_BOSS_TW; + } else if (!strcmp(texturePath, "__OTR__objects/object_bv/gBarinadeTitleCardTex")) { + // gBarinadeTitleCardTex + bossActorId = ACTOR_BOSS_VA; + } else if (!strcmp(texturePath, "__OTR__objects/object_fhg/gPhantomGanonTitleCardTex")) { + // gPhantomGanonTitleCardTex + bossActorId = ACTOR_EN_FHG; + } + if (ResourceMgr_OTRSigCheck(texture)) texture = ResourceMgr_LoadTexByName(texture); @@ -776,6 +813,11 @@ void TitleCard_InitBossName(GlobalContext* globalCtx, TitleCardContext* titleCtx titleCtx->height = height; titleCtx->durationTimer = 80; titleCtx->delayTimer = 0; + + if (bossActorId != 0 && CVar_GetS32("gMessageTTS", 0)) { + sTitleCardText = OTRMessage_GetAccessibilityText("text/accessibility_text/accessibility_text_eng", + 0x1000 + bossActorId, NULL); + } } void TitleCard_InitPlaceName(GlobalContext* globalCtx, TitleCardContext* titleCtx, char* texture, s32 x, s32 y, @@ -993,10 +1035,19 @@ void TitleCard_InitPlaceName(GlobalContext* globalCtx, TitleCardContext* titleCt titleCtx->height = height; titleCtx->durationTimer = 80; titleCtx->delayTimer = delay; + + if (CVar_GetS32("gMessageTTS", 0)) { + sTitleCardText = + OTRMessage_GetAccessibilityText("text/accessibility_text/accessibility_text_eng", 0x0300 + globalCtx->sceneNum, NULL); + } } void TitleCard_Update(GlobalContext* globalCtx, TitleCardContext* titleCtx) { if (DECR(titleCtx->delayTimer) == 0) { + if (titleCtx->durationTimer == 80 && CVar_GetS32("gMessageTTS", 0)) { + OTRTextToSpeechCallback(sTitleCardText); + } + if (DECR(titleCtx->durationTimer) == 0) { Math_StepToS(&titleCtx->alpha, 0, 30); Math_StepToS(&titleCtx->intensity, 0, 70); diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c index 42fe91daa..b9b987b48 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_collect.c @@ -172,51 +172,21 @@ void KaleidoScope_DrawQuestStatus(GlobalContext* globalCtx, GraphicsContext* gfx pauseCtx->cursorItem[pauseCtx->pageIndex] = phi_s0_2; pauseCtx->cursorSlot[pauseCtx->pageIndex] = sp216; - switch (pauseCtx->cursorItem[PAUSE_QUEST]) { - case ITEM_KOKIRI_EMERALD: - OTRTextToSpeechCallback("Kokiri Emerald"); - break; - case ITEM_GORON_RUBY: - OTRTextToSpeechCallback("Goron Ruby"); - break; - case ITEM_ZORA_SAPPHIRE: - OTRTextToSpeechCallback("Zora Sapphire"); - break; - case ITEM_MEDALLION_LIGHT: - OTRTextToSpeechCallback("Light Medallion"); - break; - case ITEM_MEDALLION_FOREST: - OTRTextToSpeechCallback("Forest Medallion"); - break; - case ITEM_MEDALLION_FIRE: - OTRTextToSpeechCallback("Fire Medallion"); - break; - case ITEM_MEDALLION_WATER: - OTRTextToSpeechCallback("Water Medallion"); - break; - case ITEM_MEDALLION_SHADOW: - OTRTextToSpeechCallback("Shadow Medallion"); - break; - case ITEM_MEDALLION_SPIRIT: - OTRTextToSpeechCallback("Spirit Medallion"); - break; - case ITEM_GERUDO_CARD: - OTRTextToSpeechCallback("Gerudo Card"); - break; - case ITEM_STONE_OF_AGONY: - OTRTextToSpeechCallback("Stone of Agony"); - break; - case ITEM_HEART_PIECE: - OTRTextToSpeechCallback("Heart Pieces"); - break; - case ITEM_SKULL_TOKEN: { - int tokens = gSaveContext.inventory.gsTokens; - OTRTextToSpeechCallback("Skulltula Tokens"); - break; + if (CVar_GetS32("gMessageTTS", 0)) { + u8 arg[8]; // at least big enough where no s8 string will overflow + switch (pauseCtx->cursorItem[PAUSE_QUEST]) { + case ITEM_SKULL_TOKEN: + sprintf(arg, "%d", gSaveContext.inventory.gsTokens); + break; + case ITEM_HEART_CONTAINER: + sprintf(arg, "%d of 4", (((gSaveContext.inventory.questItems & 0xF0000000) & 0xF0000000) >> 0x1C)); + break; + default: + arg[0] = '\0'; } - default: - OTRTextToSpeechCallback("Unknown Item"); - break; + OTRTextToSpeechCallback(OTRMessage_GetAccessibilityText("text/accessibility_text/accessibility_text_eng", + pauseCtx->cursorItem[PAUSE_QUEST]), + arg); } } diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c index 9f24fbaad..be3dbf06d 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_equipment.c @@ -508,101 +508,10 @@ void KaleidoScope_DrawEquipment(GlobalContext* globalCtx) { if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_EQUIP]) { Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - - switch (pauseCtx->cursorItem[PAUSE_EQUIP]) { - case ITEM_SWORD_KOKIRI: - OTRTextToSpeechCallback("Kokiri Sword"); - break; - case ITEM_SWORD_MASTER: - OTRTextToSpeechCallback("Master Sword"); - break; - case ITEM_HEART_PIECE_2: - OTRTextToSpeechCallback("Biggoron's Sword"); - break; - case ITEM_SWORD_BGS: - OTRTextToSpeechCallback("Giant's Knife"); - break; - case ITEM_SWORD_KNIFE: - OTRTextToSpeechCallback("Broken Giant's Knife"); - break; - case ITEM_SHIELD_DEKU: - OTRTextToSpeechCallback("Deku Shield"); - break; - case ITEM_SHIELD_HYLIAN: - OTRTextToSpeechCallback("Hylian Shield"); - break; - case ITEM_SHIELD_MIRROR: - OTRTextToSpeechCallback("Mirror Shield"); - break; - case ITEM_TUNIC_KOKIRI: - OTRTextToSpeechCallback("Kokiri Tunic"); - break; - case ITEM_TUNIC_GORON: - OTRTextToSpeechCallback("Goron Tunic"); - break; - case ITEM_TUNIC_ZORA: - OTRTextToSpeechCallback("Zora Tunic"); - break; - case ITEM_BOOTS_KOKIRI: - OTRTextToSpeechCallback("Kokiri Boots"); - break; - case ITEM_BOOTS_IRON: - OTRTextToSpeechCallback("Iron Boots"); - break; - case ITEM_BOOTS_HOVER: - OTRTextToSpeechCallback("Hover Boots"); - break; - case ITEM_BULLET_BAG_30: - OTRTextToSpeechCallback("Bullet Bag"); - break; - case ITEM_BULLET_BAG_40: - OTRTextToSpeechCallback("Bigger Bullet Bag"); - break; - case ITEM_BULLET_BAG_50: - OTRTextToSpeechCallback("Biggest Bullet Bag"); - break; - case ITEM_QUIVER_30: - OTRTextToSpeechCallback("Quiver"); - break; - case ITEM_QUIVER_40: - OTRTextToSpeechCallback("Big Quiver"); - break; - case ITEM_QUIVER_50: - OTRTextToSpeechCallback("Biggest Quiver"); - break; - case ITEM_BOMB_BAG_20: - OTRTextToSpeechCallback("Bomb Bag"); - break; - case ITEM_BOMB_BAG_30: - OTRTextToSpeechCallback("Big Bomb Bag"); - break; - case ITEM_BOMB_BAG_40: - OTRTextToSpeechCallback("Biggest Bomb Bag"); - break; - case ITEM_WALLET_ADULT: - OTRTextToSpeechCallback("Adult Wallet"); - break; - case ITEM_WALLET_GIANT: - OTRTextToSpeechCallback("Giant Wallet"); - break; - case ITEM_SCALE_SILVER: - OTRTextToSpeechCallback("Silver Scale"); - break; - case ITEM_SCALE_GOLDEN: - OTRTextToSpeechCallback("Golden Scale"); - break; - case ITEM_BRACELET: - OTRTextToSpeechCallback("Goron Bracelet"); - break; - case ITEM_GAUNTLETS_SILVER: - OTRTextToSpeechCallback("Silver Gauntlets"); - break; - case ITEM_GAUNTLETS_GOLD: - OTRTextToSpeechCallback("Golden Gauntlets"); - break; - default: - OTRTextToSpeechCallback("Unknown Item"); - break; + + if (CVar_GetS32("gMessageTTS", 0)) { + OTRTextToSpeechCallback(OTRMessage_GetAccessibilityText("text/accessibility_text/accessibility_text_eng", + pauseCtx->cursorItem[PAUSE_EQUIP], NULL)); } } } else if ((pauseCtx->unk_1E4 == 7) && (pauseCtx->pageIndex == PAUSE_EQUIP)) { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c index 761e6512b..429679509 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_item.c @@ -409,172 +409,25 @@ void KaleidoScope_DrawItemSelect(GlobalContext* globalCtx) { if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_ITEM]) { Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); - switch (pauseCtx->cursorItem[PAUSE_ITEM]) { - case ITEM_STICK: - OTRTextToSpeechCallback("Deku Stick"); - break; - case ITEM_NUT: - OTRTextToSpeechCallback("Deku Nut"); - break; - case ITEM_BOMB: - OTRTextToSpeechCallback("Bomb"); - break; - case ITEM_BOW: - OTRTextToSpeechCallback("Fairy Bow"); - break; - case ITEM_ARROW_FIRE: - OTRTextToSpeechCallback("Fire Arrow"); - break; - case ITEM_DINS_FIRE: - OTRTextToSpeechCallback("Din's Fire"); - break; - case ITEM_SLINGSHOT: - OTRTextToSpeechCallback("Slingshot"); - break; - case ITEM_OCARINA_FAIRY: - OTRTextToSpeechCallback("Fairy Ocarina"); - break; - case ITEM_OCARINA_TIME: - OTRTextToSpeechCallback("Ocarina of Time"); - break; - case ITEM_BOMBCHU: - OTRTextToSpeechCallback("Bombchu"); - break; - case ITEM_HOOKSHOT: - OTRTextToSpeechCallback("Hookshot"); - break; - case ITEM_LONGSHOT: - OTRTextToSpeechCallback("Longshot"); - break; - case ITEM_ARROW_ICE: - OTRTextToSpeechCallback("Ice Arrow"); - break; - case ITEM_FARORES_WIND: - OTRTextToSpeechCallback("Farore's Wind"); - break; - case ITEM_BOOMERANG: - OTRTextToSpeechCallback("Boomerang"); - break; - case ITEM_LENS: - OTRTextToSpeechCallback("Lens of Truth"); - break; - case ITEM_BEAN: - OTRTextToSpeechCallback("Magic Bean"); - break; - case ITEM_HAMMER: - OTRTextToSpeechCallback("Megaton Hammer"); - break; - case ITEM_ARROW_LIGHT: - OTRTextToSpeechCallback("Light Arrow"); - break; - case ITEM_NAYRUS_LOVE: - OTRTextToSpeechCallback("Nayru's Love"); - break; - case ITEM_POTION_GREEN: - OTRTextToSpeechCallback("Bottled Green Potion"); - break; - case ITEM_POTION_RED: - OTRTextToSpeechCallback("Bottled Red Potion"); - break; - case ITEM_POTION_BLUE: - OTRTextToSpeechCallback("Bottled Blue Potion"); - break; - case ITEM_MILK: - OTRTextToSpeechCallback("Bottled Lon Lon Milk"); - break; - case ITEM_MILK_HALF: - OTRTextToSpeechCallback("Bottled Lon Lon Milk (Half)"); - break; - case ITEM_FAIRY: - OTRTextToSpeechCallback("Bottled Fairy"); - break; - case ITEM_BUG: - OTRTextToSpeechCallback("Bottled Bugs"); - break; - case ITEM_FISH: - OTRTextToSpeechCallback("Bottled Fish"); - break; - case ITEM_POE: - OTRTextToSpeechCallback("Bottled Poe"); - break; - case ITEM_BIG_POE: - OTRTextToSpeechCallback("Bottled Big Poe"); - break; - case ITEM_BLUE_FIRE: - OTRTextToSpeechCallback("Bottled Blue Fire"); - break; - case ITEM_LETTER_RUTO: - OTRTextToSpeechCallback("Bottled Ruto's Letter"); - break; - case ITEM_WEIRD_EGG: - OTRTextToSpeechCallback("Weird Egg"); - break; - case ITEM_CHICKEN: - OTRTextToSpeechCallback("Cucco"); - break; - case ITEM_LETTER_ZELDA: - OTRTextToSpeechCallback("Zelda's Letter"); - break; - case ITEM_MASK_KEATON: - OTRTextToSpeechCallback("Keaton Mask"); - break; - case ITEM_MASK_SKULL: - OTRTextToSpeechCallback("Skull Mask"); - break; - case ITEM_MASK_SPOOKY: - OTRTextToSpeechCallback("Spooky Mask"); - break; - case ITEM_MASK_BUNNY: - OTRTextToSpeechCallback("Bunny Hood"); - break; - case ITEM_MASK_TRUTH: - OTRTextToSpeechCallback("Mask of Truth"); - break; - case ITEM_MASK_GORON: - OTRTextToSpeechCallback("Goron Mask"); - break; - case ITEM_MASK_ZORA: - OTRTextToSpeechCallback("Zora Mask"); - break; - case ITEM_MASK_GERUDO: - OTRTextToSpeechCallback("Gerudo Mask"); - break; - case ITEM_POCKET_EGG: - OTRTextToSpeechCallback("Pocket Egg"); - break; - case ITEM_POCKET_CUCCO: - OTRTextToSpeechCallback("Pocket Cucco"); - break; - case ITEM_COJIRO: - OTRTextToSpeechCallback("Cojiro"); - break; - case ITEM_ODD_MUSHROOM: - OTRTextToSpeechCallback("Odd Mushroom"); - break; - case ITEM_ODD_POTION: - OTRTextToSpeechCallback("Odd Potion"); - break; - case ITEM_SAW: - OTRTextToSpeechCallback("Poacher's Saw"); - break; - case ITEM_PRESCRIPTION: - OTRTextToSpeechCallback("Prescription"); - break; - case ITEM_FROG: - OTRTextToSpeechCallback("Eyeball Frog"); - break; - case ITEM_EYEDROPS: - OTRTextToSpeechCallback("World's Finest Eye Drops"); - break; - case ITEM_CLAIM_CHECK: - OTRTextToSpeechCallback("Claim Check"); - break; - case ITEM_BOTTLE: - OTRTextToSpeechCallback("Empty Bottle"); - break; - default: - OTRTextToSpeechCallback("Unknown Item"); - break; + if (CVar_GetS32("gMessageTTS", 0)) { + u8 arg[8]; // at least big enough where no s8 string will overflow + switch (pauseCtx->cursorItem[PAUSE_ITEM]) { + case ITEM_STICK: + case ITEM_NUT: + case ITEM_BOMB: + case ITEM_BOMBCHU: + case ITEM_SLINGSHOT: + case ITEM_BOW: + sprintf(arg, "%d", AMMO(pauseCtx->cursorItem[PAUSE_ITEM])); + break; + case ITEM_BEAN: + sprintf(arg, "%d", BEANS_BOUGHT); + break; + default: + arg[0] = '\0'; + } + OTRTextToSpeechCallback(OTRMessage_GetAccessibilityText("text/accessibility_text/accessibility_text_eng", + pauseCtx->cursorItem[PAUSE_ITEM]), arg); } } } else if ((pauseCtx->unk_1E4 == 3) && (pauseCtx->pageIndex == PAUSE_ITEM)) { diff --git a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c index af5c2b424..4df44b971 100644 --- a/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c +++ b/soh/src/overlays/misc/ovl_kaleido_scope/z_kaleido_map_PAL.c @@ -208,6 +208,15 @@ void KaleidoScope_DrawDungeonMap(GlobalContext* globalCtx, GraphicsContext* gfxC } } + if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_MAP]) { + if (CVar_GetS32("gMessageTTS", 0)) { + if (pauseCtx->cursorItem[PAUSE_MAP] != PAUSE_ITEM_NONE) { + OTRTextToSpeechCallback(OTRMessage_GetAccessibilityText( + "text/accessibility_text/accessibility_text_eng", pauseCtx->cursorItem[PAUSE_MAP], NULL)); + } + } + } + gDPPipeSync(POLY_KAL_DISP++); gDPSetPrimColor(POLY_KAL_DISP++, 0, 0, 255, 255, 255, pauseCtx->alpha); gDPSetCombineMode(POLY_KAL_DISP++, G_CC_MODULATEIA, G_CC_MODULATEIA); @@ -482,6 +491,11 @@ void KaleidoScope_DrawWorldMap(GlobalContext* globalCtx, GraphicsContext* gfxCtx if (oldCursorPoint != pauseCtx->cursorPoint[PAUSE_WORLD_MAP]) { Audio_PlaySoundGeneral(NA_SE_SY_CURSOR, &D_801333D4, 4, &D_801333E0, &D_801333E0, &D_801333E8); + + if (CVar_GetS32("gMessageTTS", 0)) { + OTRTextToSpeechCallback(OTRMessage_GetAccessibilityText( + "text/accessibility_text/accessibility_text_eng", 0x0100 + pauseCtx->cursorPoint[PAUSE_WORLD_MAP], NULL)); + } } } From a1ab42e59fe20923e365e8a9ad2b9892e3c08dfb Mon Sep 17 00:00:00 2001 From: Ryan Conrad Date: Wed, 13 Apr 2022 18:58:26 -0500 Subject: [PATCH 4/4] Add null check --- libultraship/libultraship/Window.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libultraship/libultraship/Window.cpp b/libultraship/libultraship/Window.cpp index d929b5ea3..d17ec049a 100644 --- a/libultraship/libultraship/Window.cpp +++ b/libultraship/libultraship/Window.cpp @@ -293,6 +293,9 @@ namespace Ship { void Window::ReadText(const char textToRead[]) { + if (textToRead == nullptr) { + return; + } std::string textCopy(textToRead); std::thread t1(task1, textCopy); t1.detach();