From 972a560bba095d3c16ff0700fa14a94e0d1a10cc Mon Sep 17 00:00:00 2001 From: earthcrafterman Date: Sun, 15 May 2022 21:07:34 -0400 Subject: [PATCH] Turned the Owl Text Inversion into a toggle Instead of replacing the Kokiri Owl Text at boot, a new Text Entry is added for it --- libultraship/libultraship/SohImGuiImpl.cpp | 2 ++ soh/soh/z_message_OTR.cpp | 26 ++++++++--------- soh/src/code/z_message_PAL.c | 13 +++++++-- soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c | 28 ++++++++++++------- 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/libultraship/libultraship/SohImGuiImpl.cpp b/libultraship/libultraship/SohImGuiImpl.cpp index d17d6ccee..c45b5cf48 100644 --- a/libultraship/libultraship/SohImGuiImpl.cpp +++ b/libultraship/libultraship/SohImGuiImpl.cpp @@ -679,6 +679,8 @@ namespace SohImGui { Tooltip("Allows equiping the tunic and boots to c-buttons"); EnhancementCheckbox("MM Bunny Hood", "gMMBunnyHood"); Tooltip("Wearing the Bunny Hood grants a speed increase like in Majora's Mask"); + EnhancementCheckbox("Better Owl", "gBetterOwl"); + Tooltip("The default response to Kaepora Gaebora is always that you understood what he said"); ImGui::EndMenu(); } diff --git a/soh/soh/z_message_OTR.cpp b/soh/soh/z_message_OTR.cpp index e21c6a22c..f1c0bea42 100644 --- a/soh/soh/z_message_OTR.cpp +++ b/soh/soh/z_message_OTR.cpp @@ -11,6 +11,7 @@ extern "C" MessageTableEntry* sNesMessageEntryTablePtr; extern "C" MessageTableEntry* sGerMessageEntryTablePtr; extern "C" MessageTableEntry* sFraMessageEntryTablePtr; extern "C" MessageTableEntry* sStaffMessageEntryTablePtr; +extern "C" const u16 sKaeporaPatchIndex = 0x71B3; //extern "C" MessageTableEntry* _message_0xFFFC_nes; MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) { @@ -19,13 +20,12 @@ MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) { if (file == nullptr) return nullptr; - MessageTableEntry* table = (MessageTableEntry*)malloc(sizeof(MessageTableEntry) * file->messages.size()); - char* kaeporaPatch; + MessageTableEntry* table = (MessageTableEntry*)malloc(sizeof(MessageTableEntry) * (file->messages.size() + 1)); for (int i = 0; i < file->messages.size(); i++) { if (file->messages[i].id == 0x2066) { - kaeporaPatch = (char*)malloc(sizeof(char) * file->messages[i].msg.size()); - kaeporaPatch = (char*)file->messages[i].msg.c_str(); + char* kaeporaPatch = (char*)malloc(sizeof(char) * file->messages[i].msg.size()); + file->messages[i].msg.copy(kaeporaPatch, file->messages[i].msg.size(), 0); kaeporaPatch[26] = 'Y'; kaeporaPatch[27] = 'e'; @@ -33,21 +33,17 @@ MessageTableEntry* OTRMessage_LoadTable(const char* filePath, bool isNES) { kaeporaPatch[29] = 1; kaeporaPatch[30] = 'N'; kaeporaPatch[31] = 'o'; - break; - } - } - for (int i = 0; i < file->messages.size(); i++) { + table[file->messages.size()].textId = sKaeporaPatchIndex; + table[file->messages.size()].typePos = (file->messages[i].textboxType << 4) | file->messages[i].textboxYPos; + table[file->messages.size()].segment = kaeporaPatch; + table[file->messages.size()].msgSize = file->messages[i].msg.size(); + } + table[i].textId = file->messages[i].id; table[i].typePos = (file->messages[i].textboxType << 4) | file->messages[i].textboxYPos; + table[i].segment = file->messages[i].msg.c_str(); table[i].msgSize = file->messages[i].msg.size(); - - if (kaeporaPatch != "" && (file->messages[i].id == 0x2066 || file->messages[i].id == 0x607B || - file->messages[i].id == 0x10C2 || file->messages[i].id == 0x10C6 || file->messages[i].id == 0x206A)) { - table[i].segment = kaeporaPatch; - } else { - table[i].segment = file->messages[i].msg.c_str(); - } if (isNES && file->messages[i].id == 0xFFFC) _message_0xFFFC_nes = (char*)file->messages[i].msg.c_str(); diff --git a/soh/src/code/z_message_PAL.c b/soh/src/code/z_message_PAL.c index ffb0581c7..da1e33f93 100644 --- a/soh/src/code/z_message_PAL.c +++ b/soh/src/code/z_message_PAL.c @@ -36,6 +36,7 @@ MessageTableEntry* sNesMessageEntryTablePtr; MessageTableEntry* sGerMessageEntryTablePtr; MessageTableEntry* sFraMessageEntryTablePtr; MessageTableEntry* sStaffMessageEntryTablePtr; +const u16 sKaeporaPatchIndex; char* _message_0xFFFC_nes; @@ -272,6 +273,12 @@ void Message_FindMessage(GlobalContext* globalCtx, u16 textId) { const char** languageSegmentTable; Font* font; const char* seg; + u16 bufferId = textId; + if (CVar_GetS32("gBetterOwl", 0) != 0 && (bufferId == 0x2066 || bufferId == 0x607B || + bufferId == 0x10C2 || bufferId == 0x10C6 || bufferId == 0x206A)) + { + bufferId = sKaeporaPatchIndex; + } if (gSaveContext.language == LANGUAGE_GER) messageTableEntry = sGerMessageEntryTablePtr; @@ -287,7 +294,7 @@ void Message_FindMessage(GlobalContext* globalCtx, u16 textId) { while (messageTableEntry->textId != 0xFFFF) { font = &globalCtx->msgCtx.font; - if (messageTableEntry->textId == textId) { + if (messageTableEntry->textId == bufferId) { foundSeg = messageTableEntry->segment; font->charTexBuf[0] = messageTableEntry->typePos; @@ -298,14 +305,14 @@ void Message_FindMessage(GlobalContext* globalCtx, u16 textId) { // "Message found!!!" osSyncPrintf(" メッセージが,見つかった!!! = %x " "(data=%x) (data0=%x) (data1=%x) (data2=%x) (data3=%x)\n", - textId, font->msgOffset, font->msgLength, foundSeg, seg, nextSeg); + bufferId, font->msgOffset, font->msgLength, foundSeg, seg, nextSeg); return; } messageTableEntry++; } // "Message not found!!!" - osSyncPrintf(" メッセージが,見つからなかった!!! = %x\n", textId); + osSyncPrintf(" メッセージが,見つからなかった!!! = %x\n", bufferId); font = &globalCtx->msgCtx.font; messageTableEntry = sNesMessageEntryTablePtr; diff --git a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 39a2a9a20..aaa4ac601 100644 --- a/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/soh/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -61,8 +61,8 @@ typedef enum { } EnOwlType; typedef enum { - /* 0x00 */ OWL_OK, - /* 0x01 */ OWL_REPEAT + /* 0x00 */ OWL_REPEAT, + /* 0x01 */ OWL_OK } EnOwlMessageChoice; const ActorInit En_Owl_InitVars = { @@ -366,7 +366,8 @@ void func_80ACA7E0(EnOwl* this, GlobalContext* globalCtx) { void EnOwl_ConfirmKokiriMessage(EnOwl* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { - switch (globalCtx->msgCtx.choiceIndex) { + uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex); + switch (index) { case OWL_REPEAT: Message_ContinueTextbox(globalCtx, 0x2065); break; @@ -393,7 +394,8 @@ void EnOwl_WaitOutsideKokiri(EnOwl* this, GlobalContext* globalCtx) { void func_80ACA998(EnOwl* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { - switch (globalCtx->msgCtx.choiceIndex) { + uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex); + switch (index) { case OWL_REPEAT: Message_ContinueTextbox(globalCtx, 0x2069); this->actionFunc = func_80ACAA54; @@ -437,7 +439,8 @@ void EnOwl_WaitHyruleCastle(EnOwl* this, GlobalContext* globalCtx) { void func_80ACAB88(EnOwl* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { - switch (globalCtx->msgCtx.choiceIndex) { + uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex); + switch (index) { case OWL_REPEAT: // obtained zelda's letter if (gSaveContext.eventChkInf[4] & 1) { @@ -478,7 +481,8 @@ void EnOwl_WaitKakariko(EnOwl* this, GlobalContext* globalCtx) { void func_80ACAD34(EnOwl* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { - switch (globalCtx->msgCtx.choiceIndex) { + uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex); + switch (index) { case OWL_REPEAT: Message_ContinueTextbox(globalCtx, 0x206F); this->actionFunc = func_80ACADF0; @@ -514,7 +518,8 @@ void EnOwl_WaitGerudo(EnOwl* this, GlobalContext* globalCtx) { void func_80ACAEB8(EnOwl* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { - switch (globalCtx->msgCtx.choiceIndex) { + uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex); + switch (index) { case OWL_REPEAT: Message_ContinueTextbox(globalCtx, 0x2071); this->actionFunc = func_80ACAF74; @@ -634,7 +639,8 @@ void EnOwl_WaitDeathMountainShortcut(EnOwl* this, GlobalContext* globalCtx) { void func_80ACB344(EnOwl* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { - switch (globalCtx->msgCtx.choiceIndex) { + uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex); + switch (index) { case OWL_REPEAT: Message_ContinueTextbox(globalCtx, 0x607A); break; @@ -657,7 +663,8 @@ void func_80ACB3E0(EnOwl* this, GlobalContext* globalCtx) { void func_80ACB440(EnOwl* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { - switch (globalCtx->msgCtx.choiceIndex) { + uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex); + switch (index) { case OWL_REPEAT: Message_ContinueTextbox(globalCtx, 0x10C1); this->actionFunc = func_80ACB4FC; @@ -692,7 +699,8 @@ void EnOwl_WaitLWPreSaria(EnOwl* this, GlobalContext* globalCtx) { void func_80ACB5C4(EnOwl* this, GlobalContext* globalCtx) { if (Message_GetState(&globalCtx->msgCtx) == TEXT_STATE_CHOICE && Message_ShouldAdvance(globalCtx)) { - switch (globalCtx->msgCtx.choiceIndex) { + uint8_t index = CVar_GetS32("gBetterOwl", 0) == 0 ? globalCtx->msgCtx.choiceIndex : (1 - globalCtx->msgCtx.choiceIndex); + switch (index) { case OWL_REPEAT: Message_ContinueTextbox(globalCtx, 0x10C5); this->actionFunc = func_80ACB680;