From 53516393862178faabd19a4d659782fa2e5a6ebc Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 6 Apr 2025 11:05:19 +0200 Subject: [PATCH] _talk and _link with the same problems as _get and _sword --- config/SOUE01/symbols.txt | 120 +++---- .../d/lyt/msg_window/d_lyt_msg_window_link.h | 17 +- .../d/lyt/msg_window/d_lyt_msg_window_talk.h | 18 +- src/d/lyt/msg_window/d_lyt_msg_window_get.cpp | 34 +- .../lyt/msg_window/d_lyt_msg_window_link.cpp | 302 ++++++++++++++++++ .../lyt/msg_window/d_lyt_msg_window_sword.cpp | 3 +- .../lyt/msg_window/d_lyt_msg_window_talk.cpp | 300 +++++++++++++++++ 7 files changed, 708 insertions(+), 86 deletions(-) create mode 100644 src/d/lyt/msg_window/d_lyt_msg_window_link.cpp create mode 100644 src/d/lyt/msg_window/d_lyt_msg_window_talk.cpp diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 7555ddd6..809c6a0e 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -7132,66 +7132,66 @@ remove__13dLytTextLightFv = .text:0x80120ED0; // type:function size:0x28 draw__13dLytTextLightFSc7mVec3_cUcf = .text:0x80120F00; // type:function size:0x14C getAnimDuration__13dLytTextLightCFv = .text:0x80121050; // type:function size:0xC vt_0x40__20dLytMsgWindowSubtypeCFv = .text:0x80121060; // type:function size:0x8 -LytMsgWindowTalk__initialize = .text:0x80121070; // type:function size:0x2F8 -fn_80121370 = .text:0x80121370; // type:function size:0xE0 -LytMsgWindowTalk__stateInvisibleEnter = .text:0x80121450; // type:function size:0x8 -LytMsgWindowTalk__stateInvisibleUpdate = .text:0x80121460; // type:function size:0x28 -LytMsgWindowTalk__stateInvisibleLeave = .text:0x80121490; // type:function size:0x4 -LytMsgWindowTalk__stateInEnter = .text:0x801214A0; // type:function size:0xF0 -LytMsgWindowTalk__stateInUpdate = .text:0x80121590; // type:function size:0x180 -LytMsgWindowTalk__stateInLeave = .text:0x80121710; // type:function size:0x4 -LytMsgWindowTalk__stateWaitEnter = .text:0x80121720; // type:function size:0x10 -LytMsgWindowTalk__stateWaitUpdate = .text:0x80121730; // type:function size:0x2C -LytMsgWindowTalk__stateWaitLeave = .text:0x80121760; // type:function size:0x4 -LytMsgWindowTalk__stateVisibleEnter = .text:0x80121770; // type:function size:0x10C -fn_80121880 = .text:0x80121880; // type:function size:0x8 -LytMsgWindowTalk__stateVisibleUpdate = .text:0x80121890; // type:function size:0x28 -LytMsgWindowTalk__stateVisibleLeave = .text:0x801218C0; // type:function size:0x4 -LytMsgWindowTalk__stateOutEnter = .text:0x801218D0; // type:function size:0x60 -LytMsgWindowTalk__stateOutUpdate = .text:0x80121930; // type:function size:0x194 -LytMsgWindowTalk__stateOutLeave = .text:0x80121AD0; // type:function size:0x4 -fn_80121AE0 = .text:0x80121AE0; // type:function size:0xBC -LytMsgWindowTalk__draw = .text:0x80121BA0; // type:function size:0x16C -fn_80121D10 = .text:0x80121D10; // type:function size:0x14 -LytMsgWindowTalk__checkIsOpenComplete = .text:0x80121D30; // type:function size:0x9C -fn_80121DD0 = .text:0x80121DD0; // type:function size:0xC -LytMsgWindowTalk__checkIsNotInOutState = .text:0x80121DE0; // type:function size:0x4C -fn_80121E30 = .text:0x80121E30; // type:function size:0x7C -fn_80121EB0 = .text:0x80121EB0; // type:function size:0x8 -fn_80121EC0 = .text:0x80121EC0; // type:function size:0x8 -fn_80121ED0 = .text:0x80121ED0; // type:function size:0x8 -LytMsgWindowTalk__initStates = .text:0x80121EE0; // type:function size:0x3F4 +build__19dLytMsgWindowTalk_cFPQ23d2d10ResAccIf_cPQ23d2d10ResAccIf_cP15dTagProcessor_c = .text:0x80121070; // type:function size:0x2F8 +remove__19dLytMsgWindowTalk_cFv = .text:0x80121370; // type:function size:0xE0 +initializeState_Invisible__19dLytMsgWindowTalk_cFv = .text:0x80121450; // type:function size:0x8 +executeState_Invisible__19dLytMsgWindowTalk_cFv = .text:0x80121460; // type:function size:0x28 +finalizeState_Invisible__19dLytMsgWindowTalk_cFv = .text:0x80121490; // type:function size:0x4 +initializeState_In__19dLytMsgWindowTalk_cFv = .text:0x801214A0; // type:function size:0xF0 +executeState_In__19dLytMsgWindowTalk_cFv = .text:0x80121590; // type:function size:0x180 +finalizeState_In__19dLytMsgWindowTalk_cFv = .text:0x80121710; // type:function size:0x4 +initializeState_Wait__19dLytMsgWindowTalk_cFv = .text:0x80121720; // type:function size:0x10 +executeState_Wait__19dLytMsgWindowTalk_cFv = .text:0x80121730; // type:function size:0x2C +finalizeState_Wait__19dLytMsgWindowTalk_cFv = .text:0x80121760; // type:function size:0x4 +initializeState_Visible__19dLytMsgWindowTalk_cFv = .text:0x80121770; // type:function size:0x10C +getTextBox__19dLytMsgWindowTalk_cFv = .text:0x80121880; // type:function size:0x8 +executeState_Visible__19dLytMsgWindowTalk_cFv = .text:0x80121890; // type:function size:0x28 +finalizeState_Visible__19dLytMsgWindowTalk_cFv = .text:0x801218C0; // type:function size:0x4 +initializeState_Out__19dLytMsgWindowTalk_cFv = .text:0x801218D0; // type:function size:0x60 +executeState_Out__19dLytMsgWindowTalk_cFv = .text:0x80121930; // type:function size:0x194 +finalizeState_Out__19dLytMsgWindowTalk_cFv = .text:0x80121AD0; // type:function size:0x4 +execute__19dLytMsgWindowTalk_cFv = .text:0x80121AE0; // type:function size:0xBC +draw__19dLytMsgWindowTalk_cFv = .text:0x80121BA0; // type:function size:0x16C +open__19dLytMsgWindowTalk_cFP12dAcObjBase_cUl = .text:0x80121D10; // type:function size:0x14 +isDoneOpening__19dLytMsgWindowTalk_cCFv = .text:0x80121D30; // type:function size:0x9C +close__19dLytMsgWindowTalk_cFv = .text:0x80121DD0; // type:function size:0xC +isDoneClosing__19dLytMsgWindowTalk_cCFv = .text:0x80121DE0; // type:function size:0x4C +setText__19dLytMsgWindowTalk_cFPCw = .text:0x80121E30; // type:function size:0x7C +isDoneDecide__19dLytMsgWindowTalk_cCFv = .text:0x80121EB0; // type:function size:0x8 +startDecide__19dLytMsgWindowTalk_cFb = .text:0x80121EC0; // type:function size:0x8 +startConfirm__19dLytMsgWindowTalk_cFv = .text:0x80121ED0; // type:function size:0x8 +__sinit_\d_lyt_msg_window_talk_cpp = .text:0x80121EE0; // type:function size:0x3F4 __dt__34sFStateID_c<19dLytMsgWindowTalk_c>Fv = .text:0x801222E0; // type:function size:0x58 isSameName__34sFStateID_c<19dLytMsgWindowTalk_c>CFPCc = .text:0x80122340; // type:function size:0x88 -fn_801223D0 = .text:0x801223D0; // type:function size:0x2F8 -fn_801226D0 = .text:0x801226D0; // type:function size:0xE0 -fn_801227B0 = .text:0x801227B0; // type:function size:0x8 -fn_801227C0 = .text:0x801227C0; // type:function size:0x28 -fn_801227F0 = .text:0x801227F0; // type:function size:0x4 -fn_80122800 = .text:0x80122800; // type:function size:0xF0 -fn_801228F0 = .text:0x801228F0; // type:function size:0x180 -fn_80122A70 = .text:0x80122A70; // type:function size:0x4 -fn_80122A80 = .text:0x80122A80; // type:function size:0x10 -fn_80122A90 = .text:0x80122A90; // type:function size:0x2C -fn_80122AC0 = .text:0x80122AC0; // type:function size:0x4 -fn_80122AD0 = .text:0x80122AD0; // type:function size:0x10C -fn_80122BE0 = .text:0x80122BE0; // type:function size:0x8 -fn_80122BF0 = .text:0x80122BF0; // type:function size:0x28 -fn_80122C20 = .text:0x80122C20; // type:function size:0x4 -fn_80122C30 = .text:0x80122C30; // type:function size:0x60 -fn_80122C90 = .text:0x80122C90; // type:function size:0x194 -fn_80122E30 = .text:0x80122E30; // type:function size:0x4 -fn_80122E40 = .text:0x80122E40; // type:function size:0xBC -fn_80122F00 = .text:0x80122F00; // type:function size:0x178 -fn_80123080 = .text:0x80123080; // type:function size:0x14 -fn_801230A0 = .text:0x801230A0; // type:function size:0x4C -fn_801230F0 = .text:0x801230F0; // type:function size:0xC -fn_80123100 = .text:0x80123100; // type:function size:0x9C -fn_801231A0 = .text:0x801231A0; // type:function size:0x7C -fn_80123220 = .text:0x80123220; // type:function size:0x8 -fn_80123230 = .text:0x80123230; // type:function size:0x8 -fn_80123240 = .text:0x80123240; // type:function size:0x8 -LytMsgWindowLink__initStates = .text:0x80123250; // type:function size:0x3F4 +build__19dLytMsgWindowLink_cFPQ23d2d10ResAccIf_cPQ23d2d10ResAccIf_cP15dTagProcessor_c = .text:0x801223D0; // type:function size:0x2F8 +remove__19dLytMsgWindowLink_cFv = .text:0x801226D0; // type:function size:0xE0 +initializeState_Invisible__19dLytMsgWindowLink_cFv = .text:0x801227B0; // type:function size:0x8 +executeState_Invisible__19dLytMsgWindowLink_cFv = .text:0x801227C0; // type:function size:0x28 +finalizeState_Invisible__19dLytMsgWindowLink_cFv = .text:0x801227F0; // type:function size:0x4 +initializeState_In__19dLytMsgWindowLink_cFv = .text:0x80122800; // type:function size:0xF0 +executeState_In__19dLytMsgWindowLink_cFv = .text:0x801228F0; // type:function size:0x180 +finalizeState_In__19dLytMsgWindowLink_cFv = .text:0x80122A70; // type:function size:0x4 +initializeState_Wait__19dLytMsgWindowLink_cFv = .text:0x80122A80; // type:function size:0x10 +executeState_Wait__19dLytMsgWindowLink_cFv = .text:0x80122A90; // type:function size:0x2C +finalizeState_Wait__19dLytMsgWindowLink_cFv = .text:0x80122AC0; // type:function size:0x4 +initializeState_Visible__19dLytMsgWindowLink_cFv = .text:0x80122AD0; // type:function size:0x10C +getTextBox__19dLytMsgWindowLink_cFv = .text:0x80122BE0; // type:function size:0x8 +executeState_Visible__19dLytMsgWindowLink_cFv = .text:0x80122BF0; // type:function size:0x28 +finalizeState_Visible__19dLytMsgWindowLink_cFv = .text:0x80122C20; // type:function size:0x4 +initializeState_Out__19dLytMsgWindowLink_cFv = .text:0x80122C30; // type:function size:0x60 +executeState_Out__19dLytMsgWindowLink_cFv = .text:0x80122C90; // type:function size:0x194 +finalizeState_Out__19dLytMsgWindowLink_cFv = .text:0x80122E30; // type:function size:0x4 +execute__19dLytMsgWindowLink_cFv = .text:0x80122E40; // type:function size:0xBC +draw__19dLytMsgWindowLink_cFv = .text:0x80122F00; // type:function size:0x178 +open__19dLytMsgWindowLink_cFP12dAcObjBase_cUl = .text:0x80123080; // type:function size:0x14 +isDoneOpening__19dLytMsgWindowLink_cCFv = .text:0x801230A0; // type:function size:0x4C +close__19dLytMsgWindowLink_cFv = .text:0x801230F0; // type:function size:0xC +isDoneClosing__19dLytMsgWindowLink_cCFv = .text:0x80123100; // type:function size:0x9C +setText__19dLytMsgWindowLink_cFPCw = .text:0x801231A0; // type:function size:0x7C +isDoneDecide__19dLytMsgWindowLink_cCFv = .text:0x80123220; // type:function size:0x8 +startDecide__19dLytMsgWindowLink_cFb = .text:0x80123230; // type:function size:0x8 +startConfirm__19dLytMsgWindowLink_cFv = .text:0x80123240; // type:function size:0x8 +__sinit_\d_lyt_msg_window_link_cpp = .text:0x80123250; // type:function size:0x3F4 __dt__34sFStateID_c<19dLytMsgWindowLink_c>Fv = .text:0x80123650; // type:function size:0x58 isSameName__34sFStateID_c<19dLytMsgWindowLink_c>CFPCc = .text:0x801236B0; // type:function size:0x88 build__18dLytMsgWindowGet_cFPQ23d2d10ResAccIf_cPQ23d2d10ResAccIf_cP15dTagProcessor_c = .text:0x80123740; // type:function size:0x2A0 @@ -32177,8 +32177,8 @@ lbl_8051CD90 = .data:0x8051CD90; // type:object size:0x10 lbl_8051CDA0 = .data:0x8051CDA0; // type:object size:0x10 lbl_8051CDB0 = .data:0x8051CDB0; // type:object size:0xC lbl_8051CDBC = .data:0x8051CDBC; // type:object size:0x18 -__vt__19dLytMsgWindowTalk_c = .data:0x8051CDD4; // type:object size:0x1B4 -__vt__34sFStateID_c<19dLytMsgWindowTalk_c> = .data:0x8051CF88; // type:object size:0x38 +__vt__19dLytMsgWindowTalk_c = .data:0x8051CDD4; // type:object size:0x44 +__vt__34sFStateID_c<19dLytMsgWindowTalk_c> = .data:0x8051CF88; // type:object size:0x34 lbl_8051CFC0 = .data:0x8051CFC0; // type:object size:0x18 lbl_8051CFD8 = .data:0x8051CFD8; // type:object size:0x10 lbl_8051CFE8 = .data:0x8051CFE8; // type:object size:0x18 data:string diff --git a/include/d/lyt/msg_window/d_lyt_msg_window_link.h b/include/d/lyt/msg_window/d_lyt_msg_window_link.h index 3d517d26..ffb99c91 100644 --- a/include/d/lyt/msg_window/d_lyt_msg_window_link.h +++ b/include/d/lyt/msg_window/d_lyt_msg_window_link.h @@ -24,20 +24,21 @@ public: /* vt 0x28 */ virtual bool isDoneClosing() const override; /* vt 0x2C */ virtual bool setText(const wchar_t *text) override; /* vt 0x30 */ virtual dTextBox_c *getTextBox() override { - return nullptr; + return mpTextboxes[0]; } /* vt 0x34 */ virtual bool startConfirm() override { - return true; + return mBtn.requestIn(); } /* vt 0x38 */ virtual bool startDecide(bool b) override { - return true; + return mBtn.requestOut(b); } /* vt 0x3C */ virtual bool isDoneDecide() const override { - return true; + return mBtn.isDoneOut(); } STATE_FUNC_DECLARE(dLytMsgWindowLink_c, Invisible); STATE_FUNC_DECLARE(dLytMsgWindowLink_c, In); + STATE_FUNC_DECLARE(dLytMsgWindowLink_c, Wait); STATE_FUNC_DECLARE(dLytMsgWindowLink_c, Visible); STATE_FUNC_DECLARE(dLytMsgWindowLink_c, Out); @@ -56,7 +57,13 @@ private: /* 0x0568 */ dTextBox_c *mpTextboxes[2]; /* 0x0570 */ nw4r::lyt::Pane *mpPanes[5]; /* 0x0584 */ dTagProcessor_c *mpTagProcessor; - /* 0x0588 */ u8 _0x0588[0x05C0 - 0x0588]; + /* 0x0588 */ mVec3_c mTranslationOrig; + /* 0x0594 */ mVec3_c mTranslationTo; + /* 0x05A0 */ mVec3_c mTranslationFrom; + /* 0x05AC */ mVec2_c mOffset; + /* 0x05B4 */ dAcObjBase_c *mpActor; + /* 0x05B8 */ s32 mParam; + /* 0x05BC */ s32 field_0x05BC; /* 0x05C0 */ dLytCommonABtn_c mBtn; /* 0x0770 */ dLytTextLight mText; /* 0x084C */ MsgWindowBlurRelated mBlurRelated; diff --git a/include/d/lyt/msg_window/d_lyt_msg_window_talk.h b/include/d/lyt/msg_window/d_lyt_msg_window_talk.h index abf23061..f7770bfa 100644 --- a/include/d/lyt/msg_window/d_lyt_msg_window_talk.h +++ b/include/d/lyt/msg_window/d_lyt_msg_window_talk.h @@ -7,6 +7,7 @@ #include "d/lyt/d_lyt_common_a_btn.h" #include "d/lyt/d_textbox.h" #include "d/lyt/msg_window/d_lyt_msg_window_common.h" +#include "m/m_vec.h" #include "s/s_State.hpp" class dLytMsgWindowTalk_c : public dLytMsgWindowSubtype { @@ -24,20 +25,21 @@ public: /* vt 0x28 */ virtual bool isDoneClosing() const override; /* vt 0x2C */ virtual bool setText(const wchar_t *text) override; /* vt 0x30 */ virtual dTextBox_c *getTextBox() override { - return nullptr; + return mpTextboxes[0]; } /* vt 0x34 */ virtual bool startConfirm() override { - return true; + return mBtn.requestIn(); } /* vt 0x38 */ virtual bool startDecide(bool b) override { - return true; + return mBtn.requestOut(b); } /* vt 0x3C */ virtual bool isDoneDecide() const override { - return true; + return mBtn.isDoneOut(); } STATE_FUNC_DECLARE(dLytMsgWindowTalk_c, Invisible); STATE_FUNC_DECLARE(dLytMsgWindowTalk_c, In); + STATE_FUNC_DECLARE(dLytMsgWindowTalk_c, Wait); STATE_FUNC_DECLARE(dLytMsgWindowTalk_c, Visible); STATE_FUNC_DECLARE(dLytMsgWindowTalk_c, Out); @@ -56,7 +58,13 @@ private: /* 0x0568 */ dTextBox_c *mpTextboxes[2]; /* 0x0570 */ nw4r::lyt::Pane *mpPanes[5]; /* 0x0584 */ dTagProcessor_c *mpTagProcessor; - /* 0x0588 */ u8 _0x0588[0x05C0 - 0x0588]; + /* 0x0588 */ mVec3_c mTranslationOrig; + /* 0x0594 */ mVec3_c mTranslationTo; + /* 0x05A0 */ mVec3_c mTranslationFrom; + /* 0x05AC */ mVec2_c mOffset; + /* 0x05B4 */ dAcObjBase_c *mpActor; + /* 0x05B8 */ s32 mParam; + /* 0x05BC */ s32 field_0x05BC; /* 0x05C0 */ dLytCommonABtn_c mBtn; /* 0x0770 */ dLytTextLight mText; /* 0x084C */ MsgWindowBlurRelated mBlurRelated; diff --git a/src/d/lyt/msg_window/d_lyt_msg_window_get.cpp b/src/d/lyt/msg_window/d_lyt_msg_window_get.cpp index ca18221a..d595badc 100644 --- a/src/d/lyt/msg_window/d_lyt_msg_window_get.cpp +++ b/src/d/lyt/msg_window/d_lyt_msg_window_get.cpp @@ -180,15 +180,19 @@ void dLytMsgWindowGet_c::draw() { // The instruction patterns here are the same that EGG::StateGX::Scoped // generates, but there's no RAII to be found here. What's the missing // link that makes the compiler generate these? - bool bVis0 = mpPanes[0]->IsVisible(); - bool bVis1 = mpPanes[1]->IsVisible(); - bool bVis2 = mpPanes[2]->IsVisible(); - bool bVis3 = mpPanes[3]->IsVisible(); - bool bVis4 = mpPanes[4]->IsVisible(); + // When you fix this, fix other instances of this problem + // by searching for 91657b77 + bool bVis[5] = { + mpPanes[0]->IsVisible(), + mpPanes[1]->IsVisible(), + mpPanes[2]->IsVisible(), + mpPanes[3]->IsVisible(), + mpPanes[4]->IsVisible(), + }; - mpPanes[0]->SetVisible(bVis0); - mpPanes[1]->SetVisible(bVis1); - mpPanes[2]->SetVisible(bVis2); + mpPanes[0]->SetVisible(bVis[0]); + mpPanes[1]->SetVisible(bVis[1]); + mpPanes[2]->SetVisible(bVis[2]); mpPanes[3]->SetVisible(false); mpPanes[4]->SetVisible(false); @@ -198,16 +202,16 @@ void dLytMsgWindowGet_c::draw() { mpPanes[0]->SetVisible(false); mpPanes[1]->SetVisible(false); mpPanes[2]->SetVisible(false); - mpPanes[3]->SetVisible(bVis3); - mpPanes[4]->SetVisible(bVis4); + mpPanes[3]->SetVisible(bVis[3]); + mpPanes[4]->SetVisible(bVis[4]); mLyt.draw(); - mpPanes[0]->SetVisible(bVis0); - mpPanes[1]->SetVisible(bVis1); - mpPanes[2]->SetVisible(bVis2); - mpPanes[3]->SetVisible(bVis3); - mpPanes[4]->SetVisible(bVis4); + mpPanes[0]->SetVisible(bVis[0]); + mpPanes[1]->SetVisible(bVis[1]); + mpPanes[2]->SetVisible(bVis[2]); + mpPanes[3]->SetVisible(bVis[3]); + mpPanes[4]->SetVisible(bVis[4]); } void dLytMsgWindowGet_c::open(dAcObjBase_c *obj, u32 param) { diff --git a/src/d/lyt/msg_window/d_lyt_msg_window_link.cpp b/src/d/lyt/msg_window/d_lyt_msg_window_link.cpp new file mode 100644 index 00000000..7ed55489 --- /dev/null +++ b/src/d/lyt/msg_window/d_lyt_msg_window_link.cpp @@ -0,0 +1,302 @@ +#include "d/lyt/msg_window/d_lyt_msg_window_link.h" + +#include "common.h" +#include "d/d_tag_processor.h" +#include "d/d_textunk.h" +#include "d/lyt/d2d.h" +#include "d/lyt/d_textbox.h" +#include "d/lyt/msg_window/d_lyt_msg_window_common.h" +#include "nw4r/lyt/lyt_group.h" +#include "nw4r/lyt/lyt_pane.h" +#include "s/s_State.hpp" + +STATE_DEFINE(dLytMsgWindowLink_c, Invisible); +STATE_DEFINE(dLytMsgWindowLink_c, In); +STATE_DEFINE(dLytMsgWindowLink_c, Wait); +STATE_DEFINE(dLytMsgWindowLink_c, Visible); +STATE_DEFINE(dLytMsgWindowLink_c, Out); + +static const d2d::LytBrlanMapping brlanMap[] = { + { "linkWindow_00_in.brlan", "G_inOut_00"}, + { "linkWindow_00_out.brlan", "G_inOut_00"}, + {"linkWindow_00_position.brlan", "G_position_00"}, + {"linkWindow_00_loop.brlan", "G_loop_00"}, +}; + +#define LINK_ANIM_IN 0 +#define LINK_ANIM_OUT 1 +#define LINK_ANIM_POSITION 2 +#define LINK_ANIM_LOOP 3 + +#define LINK_NUM_ANIMS 4 + +static const char *sPanes[] = { + "N_window_00", "N_message_00", "N_aBtn_00", "N_inOut_00", "N_position_00", +}; + +static const char *sTextBoxes[] = { + "T_message_00", + "T_messageS_00", +}; + +static const char *sGroupName = "G_ref_00"; + +bool dLytMsgWindowLink_c::build(d2d::ResAccIf_c *resAcc1, d2d::ResAccIf_c *resAcc, dTagProcessor_c *tagProcessor) { + mLyt.setResAcc(resAcc); + mLyt.build("linkWindow_00.brlyt", nullptr); + mLyt.setPriority(0x8A); + + for (int i = 0; i < LINK_NUM_ANIMS; i++) { + mAnm[i].init(brlanMap[i].mFile, resAcc, mLyt.getLayout(), brlanMap[i].mName); + mAnm[i].bind(false); + mAnm[i].setAnimEnable(false); + } + + mAnm[LINK_ANIM_LOOP].setAnimEnable(true); + mAnm[LINK_ANIM_OUT].setAnimEnable(true); + mAnm[LINK_ANIM_OUT].setToEnd(); + mLyt.calc(); + mAnm[LINK_ANIM_OUT].setAnimEnable(false); + + for (int i = 0; i < 5; i++) { + mpPanes[i] = mLyt.findPane(sPanes[i]); + } + + for (int i = 0; i < 2; i++) { + mpTextboxes[i] = mLyt.getTextBox(sTextBoxes[i]); + mpTextboxes[i]->SetTextPositionH(0); + mpTextboxes[i]->SetTextPositionV(0); + } + + mpTextboxes[1]->set0x1F6(1); + + for (int i = 0; i < 1; i++) { + mNodes[i].mpLytPane = &mBtn; + mBtn.build(resAcc); + mSubpaneList.PushBack(&mNodes[i]); + } + + if (mLyt.getLayout()->GetGroupContainer() != nullptr) { + nw4r::lyt::Group *g = mLyt.getLayout()->GetGroupContainer()->FindGroupByName(sGroupName); + if (g != nullptr) { + d2d::dSubPane::linkMeters(g, &mSubpaneList); + } + } + + mText.build(resAcc, dLytTextLight::NORMAL); + mBlurRelated.build(); + + mpPanes[3]->SetVisible(true); + mLyt.calc(); + mpPanes[3]->SetVisible(false); + mpTagProcessor = tagProcessor; + + mTranslationOrig.copyFrom(mpPanes[4]->GetTranslate()); + mTranslationTo.copyFrom(mpPanes[4]->GetTranslate()); + mTranslationFrom.copyFrom(mpPanes[4]->GetTranslate()); + + mParam = 0; + + mOffset.x = mOffset.y = 0.0f; + + field_0x05BC = 0; + + mStateMgr.changeState(StateID_Invisible); + return true; +} + +bool dLytMsgWindowLink_c::remove() { + mText.remove(); + + for (d2d::SubPaneList::Iterator it = mSubpaneList.GetBeginIter(); it != mSubpaneList.GetEndIter(); ++it) { + d2d::dSubPane *subPane = it->mpLytPane; + if (subPane != nullptr) { + nw4r::lyt::Pane *parent = subPane->getPane()->GetParent(); + parent->RemoveChild(subPane->getPane()); + } + } + + for (int i = 0; i < 1; i++) { + mNodes[i].mpLytPane->remove(); + } + mBtn.remove(); + for (int i = 0; i < LINK_NUM_ANIMS; i++) { + mAnm[i].remove(); + } + return true; +} + +void dLytMsgWindowLink_c::initializeState_Invisible() { + mBtn.resetToInvisble(); +} +void dLytMsgWindowLink_c::executeState_Invisible() { + if (mShouldBeOpen) { + mStateMgr.changeState(StateID_In); + } +} +void dLytMsgWindowLink_c::finalizeState_Invisible() {} + +void dLytMsgWindowLink_c::initializeState_In() { + mAnm[LINK_ANIM_POSITION].setFrame(mParam); + mAnm[LINK_ANIM_POSITION].setAnimEnable(true); + mLyt.calc(); + mAnm[LINK_ANIM_POSITION].setAnimEnable(false); + + mTranslationTo = mTranslationOrig; + mTranslationTo.y = mpPanes[4]->GetTranslate().y; + mTranslationFrom = mTranslationTo; + + mAnm[LINK_ANIM_IN].setAnimEnable(true); + mAnm[LINK_ANIM_IN].setFrame(0.0f); + + mpPanes[4]->SetTranslate(mTranslationFrom); +} +void dLytMsgWindowLink_c::executeState_In() { + if (mTranslationFrom != mTranslationTo) { + mVec3_c v; + if (mAnm[LINK_ANIM_IN].isEndReached()) { + v = mTranslationTo; + } else { + // TODO - when you fix this, fix other instances of this + // by searching for de4663d6 + v = mpPanes[4]->GetTranslate(); + v += (mTranslationTo - v) / 2.0f; + } + mpPanes[4]->SetTranslate(v); + } + + if (mAnm[LINK_ANIM_IN].isEndReached()) { + mAnm[LINK_ANIM_IN].setAnimEnable(false); + mStateMgr.changeState(StateID_Wait); + } +} +void dLytMsgWindowLink_c::finalizeState_In() {} + +void dLytMsgWindowLink_c::initializeState_Wait() { + field_0x05BC = UnkTextThing::getInstance()->getField_0x7AE(); +} +void dLytMsgWindowLink_c::executeState_Wait() { + if (--field_0x05BC > 0) { + return; + } + mStateMgr.changeState(StateID_Visible); +} +void dLytMsgWindowLink_c::finalizeState_Wait() {} + +void dLytMsgWindowLink_c::initializeState_Visible() { + nw4r::lyt::Size size = getTextBox()->GetSize(); + nw4r::lyt::Size fontSize = getTextBox()->GetFontSize(); + nw4r::math::MTX34 transform = getTextBox()->GetGlobalMtx(); + + mOffset.x = transform._03 - size.width / 2; + mOffset.y = transform._13 + size.height / 2; +} +void dLytMsgWindowLink_c::executeState_Visible() { + if (!mShouldBeOpen) { + mStateMgr.changeState(StateID_Out); + } +} +void dLytMsgWindowLink_c::finalizeState_Visible() {} + +void dLytMsgWindowLink_c::initializeState_Out() { + mTranslationFrom = mTranslationTo; + mAnm[LINK_ANIM_OUT].setAnimEnable(true); + mAnm[LINK_ANIM_OUT].setFrame(0.0f); +} +void dLytMsgWindowLink_c::executeState_Out() { + if (mTranslationFrom != mTranslationTo) { + mVec3_c v; + if (mAnm[LINK_ANIM_OUT].isEndReached()) { + v = mTranslationFrom; + } else { + f32 ratio = mAnm[LINK_ANIM_OUT].getRatio(); + if (ratio > 1.0f) { + ratio = 1.0f; + } + v = mTranslationTo + (mTranslationFrom - mTranslationTo) * ratio; + } + mpPanes[4]->SetTranslate(v); + } + + if (mAnm[LINK_ANIM_OUT].isEndReached()) { + mAnm[LINK_ANIM_OUT].setAnimEnable(false); + mStateMgr.changeState(StateID_Invisible); + } +} +void dLytMsgWindowLink_c::finalizeState_Out() {} + +bool dLytMsgWindowLink_c::execute() { + mStateMgr.executeState(); + for (int i = 0; i < LINK_NUM_ANIMS; i++) { + if (mAnm[i].isEnabled()) { + mAnm[i].play(); + } + } + mLyt.calc(); + for (int i = 0; i < 1; i++) { + mNodes[i].mpLytPane->execute(); + } + return true; +} + +void dLytMsgWindowLink_c::draw() { + // NONMATCHING + // The instruction patterns here are the same that EGG::StateGX::Scoped + // generates, but there's no RAII to be found here. What's the missing + // link that makes the compiler generate these? + // When you fix this, fix other instances of this problem + // by searching for 91657b77 + bool bVis[3] = { + mpPanes[0]->IsVisible(), + mpPanes[1]->IsVisible(), + mpPanes[2]->IsVisible(), + }; + + mpPanes[0]->SetVisible(bVis[0]); + mpPanes[1]->SetVisible(false); + mpPanes[2]->SetVisible(false); + + mLyt.draw(); + mBlurRelated.drawTextBlur(&mText, mOffset, mpPanes[5]->GetAlpha()); + + mpPanes[0]->SetVisible(false); + mpPanes[3]->SetVisible(bVis[1]); + mpPanes[4]->SetVisible(bVis[2]); + + mLyt.draw(); + + mpPanes[0]->SetVisible(bVis[0]); + mpPanes[1]->SetVisible(bVis[1]); + mpPanes[2]->SetVisible(bVis[2]); +} + +void dLytMsgWindowLink_c::open(dAcObjBase_c *obj, u32 param) { + mpActor = obj; + mParam = param; + mShouldBeOpen = true; +} + +// Curiously enough, this file is almost an exact copy of d_lyt_msg_window_talk, +// but the behavior of these two functions (isDoneOpening/isDoneClosing) is swapped +bool dLytMsgWindowLink_c::isDoneOpening() const { + return !(*mStateMgr.getStateID() == StateID_In); +} + +void dLytMsgWindowLink_c::close() { + mShouldBeOpen = false; +} + +bool dLytMsgWindowLink_c::isDoneClosing() const { + if (*mStateMgr.getStateID() == StateID_Out || *mStateMgr.getStateID() == StateID_Wait) { + return false; + } + return true; +} + +bool dLytMsgWindowLink_c::setText(const wchar_t *text) { + mpTextboxes[0]->SetTagProcessor(mpTagProcessor); + mpTextboxes[1]->SetTagProcessor(mpTagProcessor); + mpTextboxes[0]->setTextWithTextProcessor(text, mpTagProcessor, 0); + mpTextboxes[1]->setTextWithTextProcessor(text, mpTagProcessor, 0); + return true; +} diff --git a/src/d/lyt/msg_window/d_lyt_msg_window_sword.cpp b/src/d/lyt/msg_window/d_lyt_msg_window_sword.cpp index dc2a35b3..a7551517 100644 --- a/src/d/lyt/msg_window/d_lyt_msg_window_sword.cpp +++ b/src/d/lyt/msg_window/d_lyt_msg_window_sword.cpp @@ -234,7 +234,8 @@ void dLytMsgWindowSword_c::executeState_Out() { if (mAnm[SWORD_ANIM_OUT].isEndReached()) { v = mTranslationFrom; } else { - // TODO floats + // TODO - when you fix this, fix other instances of this + // by searching for de4663d6 v = mpPanes[2]->GetTranslate(); v += (mTranslationTo - v) / 2.0f; } diff --git a/src/d/lyt/msg_window/d_lyt_msg_window_talk.cpp b/src/d/lyt/msg_window/d_lyt_msg_window_talk.cpp new file mode 100644 index 00000000..56a4d1ef --- /dev/null +++ b/src/d/lyt/msg_window/d_lyt_msg_window_talk.cpp @@ -0,0 +1,300 @@ +#include "d/lyt/msg_window/d_lyt_msg_window_talk.h" + +#include "common.h" +#include "d/d_tag_processor.h" +#include "d/d_textunk.h" +#include "d/lyt/d2d.h" +#include "d/lyt/d_textbox.h" +#include "d/lyt/msg_window/d_lyt_msg_window_common.h" +#include "nw4r/lyt/lyt_group.h" +#include "nw4r/lyt/lyt_pane.h" +#include "s/s_State.hpp" + +STATE_DEFINE(dLytMsgWindowTalk_c, Invisible); +STATE_DEFINE(dLytMsgWindowTalk_c, In); +STATE_DEFINE(dLytMsgWindowTalk_c, Wait); +STATE_DEFINE(dLytMsgWindowTalk_c, Visible); +STATE_DEFINE(dLytMsgWindowTalk_c, Out); + +static const d2d::LytBrlanMapping brlanMap[] = { + { "messageWindow_00_in.brlan", "G_inOut_00"}, + { "messageWindow_00_out.brlan", "G_inOut_00"}, + {"messageWindow_00_position.brlan", "G_position_00"}, + { "messageWindow_00_loop.brlan", "G_loop_00"}, +}; + +#define TALK_ANIM_IN 0 +#define TALK_ANIM_OUT 1 +#define TALK_ANIM_POSITION 2 +#define TALK_ANIM_LOOP 3 + +#define TALK_NUM_ANIMS 4 + +static const char *sPanes[] = { + "N_window_00", "N_message_00", "N_aBtn_00", "N_inOut_00", "N_position_00", +}; + +static const char *sTextBoxes[] = { + "T_message_00", + "T_messageS_00", +}; + +static const char *sGroupName = "G_ref_00"; + +bool dLytMsgWindowTalk_c::build(d2d::ResAccIf_c *resAcc1, d2d::ResAccIf_c *resAcc, dTagProcessor_c *tagProcessor) { + mLyt.setResAcc(resAcc); + mLyt.build("messageWindow_00.brlyt", nullptr); + mLyt.setPriority(0x8A); + + for (int i = 0; i < TALK_NUM_ANIMS; i++) { + mAnm[i].init(brlanMap[i].mFile, resAcc, mLyt.getLayout(), brlanMap[i].mName); + mAnm[i].bind(false); + mAnm[i].setAnimEnable(false); + } + + mAnm[TALK_ANIM_LOOP].setAnimEnable(true); + mAnm[TALK_ANIM_OUT].setAnimEnable(true); + mAnm[TALK_ANIM_OUT].setToEnd(); + mLyt.calc(); + mAnm[TALK_ANIM_OUT].setAnimEnable(false); + + for (int i = 0; i < 5; i++) { + mpPanes[i] = mLyt.findPane(sPanes[i]); + } + + for (int i = 0; i < 2; i++) { + mpTextboxes[i] = mLyt.getTextBox(sTextBoxes[i]); + mpTextboxes[i]->SetTextPositionH(0); + mpTextboxes[i]->SetTextPositionV(0); + } + + mpTextboxes[1]->set0x1F6(1); + + for (int i = 0; i < 1; i++) { + mNodes[i].mpLytPane = &mBtn; + mBtn.build(resAcc); + mSubpaneList.PushBack(&mNodes[i]); + } + + if (mLyt.getLayout()->GetGroupContainer() != nullptr) { + nw4r::lyt::Group *g = mLyt.getLayout()->GetGroupContainer()->FindGroupByName(sGroupName); + if (g != nullptr) { + d2d::dSubPane::linkMeters(g, &mSubpaneList); + } + } + + mText.build(resAcc, dLytTextLight::NORMAL); + mBlurRelated.build(); + + mpPanes[3]->SetVisible(true); + mLyt.calc(); + mpPanes[3]->SetVisible(false); + mpTagProcessor = tagProcessor; + + mTranslationOrig.copyFrom(mpPanes[4]->GetTranslate()); + mTranslationTo.copyFrom(mpPanes[4]->GetTranslate()); + mTranslationFrom.copyFrom(mpPanes[4]->GetTranslate()); + + mParam = 0; + + mOffset.x = mOffset.y = 0.0f; + + field_0x05BC = 0; + + mStateMgr.changeState(StateID_Invisible); + return true; +} + +bool dLytMsgWindowTalk_c::remove() { + mText.remove(); + + for (d2d::SubPaneList::Iterator it = mSubpaneList.GetBeginIter(); it != mSubpaneList.GetEndIter(); ++it) { + d2d::dSubPane *subPane = it->mpLytPane; + if (subPane != nullptr) { + nw4r::lyt::Pane *parent = subPane->getPane()->GetParent(); + parent->RemoveChild(subPane->getPane()); + } + } + + for (int i = 0; i < 1; i++) { + mNodes[i].mpLytPane->remove(); + } + mBtn.remove(); + for (int i = 0; i < TALK_NUM_ANIMS; i++) { + mAnm[i].remove(); + } + return true; +} + +void dLytMsgWindowTalk_c::initializeState_Invisible() { + mBtn.resetToInvisble(); +} +void dLytMsgWindowTalk_c::executeState_Invisible() { + if (mShouldBeOpen) { + mStateMgr.changeState(StateID_In); + } +} +void dLytMsgWindowTalk_c::finalizeState_Invisible() {} + +void dLytMsgWindowTalk_c::initializeState_In() { + mAnm[TALK_ANIM_POSITION].setFrame(mParam); + mAnm[TALK_ANIM_POSITION].setAnimEnable(true); + mLyt.calc(); + mAnm[TALK_ANIM_POSITION].setAnimEnable(false); + + mTranslationTo = mTranslationOrig; + mTranslationTo.y = mpPanes[4]->GetTranslate().y; + mTranslationFrom = mTranslationTo; + + mAnm[TALK_ANIM_IN].setAnimEnable(true); + mAnm[TALK_ANIM_IN].setFrame(0.0f); + + mpPanes[4]->SetTranslate(mTranslationFrom); +} +void dLytMsgWindowTalk_c::executeState_In() { + if (mTranslationFrom != mTranslationTo) { + mVec3_c v; + if (mAnm[TALK_ANIM_IN].isEndReached()) { + v = mTranslationTo; + } else { + // TODO - when you fix this, fix other instances of this + // by searching for de4663d6 + v = mpPanes[4]->GetTranslate(); + v += (mTranslationTo - v) / 2.0f; + } + mpPanes[4]->SetTranslate(v); + } + + if (mAnm[TALK_ANIM_IN].isEndReached()) { + mAnm[TALK_ANIM_IN].setAnimEnable(false); + mStateMgr.changeState(StateID_Wait); + } +} +void dLytMsgWindowTalk_c::finalizeState_In() {} + +void dLytMsgWindowTalk_c::initializeState_Wait() { + field_0x05BC = UnkTextThing::getInstance()->getField_0x7AE(); +} +void dLytMsgWindowTalk_c::executeState_Wait() { + if (--field_0x05BC > 0) { + return; + } + mStateMgr.changeState(StateID_Visible); +} +void dLytMsgWindowTalk_c::finalizeState_Wait() {} + +void dLytMsgWindowTalk_c::initializeState_Visible() { + nw4r::lyt::Size size = getTextBox()->GetSize(); + nw4r::lyt::Size fontSize = getTextBox()->GetFontSize(); + nw4r::math::MTX34 transform = getTextBox()->GetGlobalMtx(); + + mOffset.x = transform._03 - size.width / 2; + mOffset.y = transform._13 + size.height / 2; +} +void dLytMsgWindowTalk_c::executeState_Visible() { + if (!mShouldBeOpen) { + mStateMgr.changeState(StateID_Out); + } +} +void dLytMsgWindowTalk_c::finalizeState_Visible() {} + +void dLytMsgWindowTalk_c::initializeState_Out() { + mTranslationFrom = mTranslationTo; + mAnm[TALK_ANIM_OUT].setAnimEnable(true); + mAnm[TALK_ANIM_OUT].setFrame(0.0f); +} +void dLytMsgWindowTalk_c::executeState_Out() { + if (mTranslationFrom != mTranslationTo) { + mVec3_c v; + if (mAnm[TALK_ANIM_OUT].isEndReached()) { + v = mTranslationFrom; + } else { + f32 ratio = mAnm[TALK_ANIM_OUT].getRatio(); + if (ratio > 1.0f) { + ratio = 1.0f; + } + v = mTranslationTo + (mTranslationFrom - mTranslationTo) * ratio; + } + mpPanes[4]->SetTranslate(v); + } + + if (mAnm[TALK_ANIM_OUT].isEndReached()) { + mAnm[TALK_ANIM_OUT].setAnimEnable(false); + mStateMgr.changeState(StateID_Invisible); + } +} +void dLytMsgWindowTalk_c::finalizeState_Out() {} + +bool dLytMsgWindowTalk_c::execute() { + mStateMgr.executeState(); + for (int i = 0; i < TALK_NUM_ANIMS; i++) { + if (mAnm[i].isEnabled()) { + mAnm[i].play(); + } + } + mLyt.calc(); + for (int i = 0; i < 1; i++) { + mNodes[i].mpLytPane->execute(); + } + return true; +} + +void dLytMsgWindowTalk_c::draw() { + // NONMATCHING + // The instruction patterns here are the same that EGG::StateGX::Scoped + // generates, but there's no RAII to be found here. What's the missing + // link that makes the compiler generate these? + // When you fix this, fix other instances of this problem + // by searching for 91657b77 + bool bVis[3] = { + mpPanes[0]->IsVisible(), + mpPanes[1]->IsVisible(), + mpPanes[2]->IsVisible(), + }; + + mpPanes[0]->SetVisible(bVis[0]); + mpPanes[1]->SetVisible(false); + mpPanes[2]->SetVisible(false); + + mLyt.draw(); + mBlurRelated.drawTextBlur(&mText, mOffset, mpPanes[5]->GetAlpha()); + + mpPanes[0]->SetVisible(false); + mpPanes[3]->SetVisible(bVis[1]); + mpPanes[4]->SetVisible(bVis[2]); + + mLyt.draw(); + + mpPanes[0]->SetVisible(bVis[0]); + mpPanes[1]->SetVisible(bVis[1]); + mpPanes[2]->SetVisible(bVis[2]); +} + +void dLytMsgWindowTalk_c::open(dAcObjBase_c *obj, u32 param) { + mpActor = obj; + mParam = param; + mShouldBeOpen = true; +} + +bool dLytMsgWindowTalk_c::isDoneOpening() const { + if (*mStateMgr.getStateID() == StateID_In || *mStateMgr.getStateID() == StateID_Wait) { + return false; + } + return true; +} + +void dLytMsgWindowTalk_c::close() { + mShouldBeOpen = false; +} + +bool dLytMsgWindowTalk_c::isDoneClosing() const { + return !(*mStateMgr.getStateID() == StateID_Out); +} + +bool dLytMsgWindowTalk_c::setText(const wchar_t *text) { + mpTextboxes[0]->SetTagProcessor(mpTagProcessor); + mpTextboxes[1]->SetTagProcessor(mpTagProcessor); + mpTextboxes[0]->setTextWithTextProcessor(text, mpTagProcessor, 0); + mpTextboxes[1]->setTextWithTextProcessor(text, mpTagProcessor, 0); + return true; +}