diff options
| author | robojumper <robojumper@gmail.com> | 2025-04-04 21:14:40 +0200 |
|---|---|---|
| committer | robojumper <robojumper@gmail.com> | 2025-04-07 22:12:38 +0200 |
| commit | af4a1cfdb0842ee4ac440b3c98308b0d68da6897 (patch) | |
| tree | fbab16b3f30e0a4321c3075438e77a069b8b149a /src/d/lyt/msg_window | |
| parent | 4612c35f458f524c65e7c87ac3e4f955a44759a9 (diff) | |
Sword somewhat ok, though not well understood
Diffstat (limited to 'src/d/lyt/msg_window')
| -rw-r--r-- | src/d/lyt/msg_window/d_lyt_msg_window.cpp | 64 | ||||
| -rw-r--r-- | src/d/lyt/msg_window/d_lyt_msg_window_sword.cpp | 346 |
2 files changed, 385 insertions, 25 deletions
diff --git a/src/d/lyt/msg_window/d_lyt_msg_window.cpp b/src/d/lyt/msg_window/d_lyt_msg_window.cpp index e5caefaa..0f15501f 100644 --- a/src/d/lyt/msg_window/d_lyt_msg_window.cpp +++ b/src/d/lyt/msg_window/d_lyt_msg_window.cpp @@ -13,6 +13,13 @@ // clang-format off // vtable order +#include "d/lyt/msg_window/d_lyt_msg_window_common.h" +#include "d/lyt/msg_window/d_lyt_msg_window_demo.h" +#include "d/lyt/msg_window/d_lyt_msg_window_get.h" +#include "d/lyt/msg_window/d_lyt_msg_window_link.h" +#include "d/lyt/msg_window/d_lyt_msg_window_sword.h" +#include "d/lyt/msg_window/d_lyt_msg_window_talk.h" + #include "d/lyt/msg_window/d_lyt_msg_window_wood.h" #include "d/lyt/msg_window/d_lyt_msg_window_stone.h" #include "d/lyt/d_lyt_auto_explain.h" @@ -28,6 +35,7 @@ #include "toBeSorted/global_fi_context.h" #include "toBeSorted/music_mgrs.h" #include "toBeSorted/small_sound_mgr.h" + #include <cstring> class MsgWindowUnkLocalClass { @@ -184,7 +192,7 @@ void dLytMsgWindow_c::executeState_Invisible() { } mpCurrentSubtype->setPriority(0x8A); - dTextBox_c *box = mpCurrentSubtype->vt_0x30(); + dTextBox_c *box = mpCurrentSubtype->getTextBox(); mpMsgWindowUnk->fn_800B2130(mNameCopy, box, nullptr, true); mpMsgWindowUnk->textAdvancingRelated(true, true); mShowAutoMessage = false; @@ -196,13 +204,13 @@ void dLytMsgWindow_c::executeState_Invisible() { mSpecialFiMenuValue = 7; if (mpTagProcessor->getMsgWindowSubtype() == 6) { mpCurrentSubtype = mpWindowWood; - dTextBox_c *box = mpCurrentSubtype->vt_0x30(); + dTextBox_c *box = mpCurrentSubtype->getTextBox(); mpMsgWindowUnk->fn_800B2130(mNameCopy, box, nullptr, true); mpMsgWindowUnk->textAdvancingRelated(true, true); setTextToDisplay(mpMsgWindowUnk->getProcessedText()); } else if (mpTagProcessor->getMsgWindowSubtype() == 7) { mpCurrentSubtype = mpWindowStone; - dTextBox_c *box = mpCurrentSubtype->vt_0x30(); + dTextBox_c *box = mpCurrentSubtype->getTextBox(); mpMsgWindowUnk->fn_800B2130(mNameCopy, box, nullptr, true); mpMsgWindowUnk->textAdvancingRelated(true, true); setTextToDisplay(mpMsgWindowUnk->getProcessedText()); @@ -218,7 +226,7 @@ void dLytMsgWindow_c::executeState_Invisible() { // TODO } else if (mpTagProcessor->getMsgWindowSubtype() == 30) { mpCurrentSubtype = mpWindowDemo; - dTextBox_c *box = mpCurrentSubtype->vt_0x30(); + dTextBox_c *box = mpCurrentSubtype->getTextBox(); mpMsgWindowUnk->fn_800B2130(mNameCopy, box, field_0x828, true); mpMsgWindowUnk->textAdvancingRelated(true, true); setTextToDisplay(mpMsgWindowUnk->getProcessedText()); @@ -229,7 +237,7 @@ void dLytMsgWindow_c::executeState_Invisible() { // TODO } mpCurrentSubtype->setPriority(0x8A); - dTextBox_c *box = mpCurrentSubtype->vt_0x30(); + dTextBox_c *box = mpCurrentSubtype->getTextBox(); mpMsgWindowUnk->fn_800B2130(mNameCopy, box, field_0x828, true); setTextToDisplay(mpMsgWindowUnk->getProcessedText()); mStateMgr.changeState(StateID_In); @@ -307,14 +315,14 @@ void dLytMsgWindow_c::executeState_OutputText() { mStateMgr.changeState(StateID_WaitKeyMsgEnd0); } else if (mpTagProcessor->getField_0x90E() != 0) { mStateMgr.changeState(StateID_WaitKeyMsgEnd0); - } else if (mpCurrentSubtype->vt_0x34()) { + } else if (mpCurrentSubtype->startConfirm()) { field_0x817 = 1; mStateMgr.changeState(StateID_WaitKeyMsgEnd0); } } else if (field_0x81D != 0) { if (field_0x811 != 0) { mStateMgr.changeState(StateID_WaitKeyChangePage0); - } else if (mpCurrentSubtype->vt_0x34()) { + } else if (mpCurrentSubtype->startConfirm()) { field_0x817 = 1; mStateMgr.changeState(StateID_WaitKeyChangePage0); } @@ -369,7 +377,7 @@ void dLytMsgWindow_c::finalizeState_WaitKeyChangePage0() {} void dLytMsgWindow_c::initializeState_WaitKeyChangePage1() {} void dLytMsgWindow_c::executeState_WaitKeyChangePage1() { - if (mpCurrentSubtype->vt_0x38(false)) { + if (mpCurrentSubtype->startDecide(false)) { field_0x817 = 0; mpMsgWindowUnk->fn_800B2AA0(); if (mpTagProcessor->getMsgWindowSubtype() >= 6 && mpTagProcessor->getMsgWindowSubtype() < 8) { @@ -416,7 +424,7 @@ void dLytMsgWindow_c::executeState_WaitKeyMsgEnd0() { } else if (field_0x810 != 0) { if (dMessage_c::isValidTextLabel(mName)) { mNameCopy = mName; - dTextBox_c *box = mpCurrentSubtype->vt_0x30(); + dTextBox_c *box = mpCurrentSubtype->getTextBox(); mpMsgWindowUnk->fn_800B2130(mNameCopy, box, field_0x828, true); setTextToDisplay(mpMsgWindowUnk->getProcessedText()); field_0x818 = 1; @@ -436,12 +444,12 @@ void dLytMsgWindow_c::finalizeState_WaitKeyMsgEnd0() {} void dLytMsgWindow_c::initializeState_WaitKeyMsgEnd1() {} void dLytMsgWindow_c::executeState_WaitKeyMsgEnd1() { - if (mpCurrentSubtype->vt_0x38(false)) { + if (mpCurrentSubtype->startDecide(false)) { if (field_0x810 != 0) { field_0x817 = 0; if (dMessage_c::isValidTextLabel(mName)) { mNameCopy = mName; - mpMsgWindowUnk->fn_800B2130(mNameCopy, mpCurrentSubtype->vt_0x30(), field_0x828, true); + mpMsgWindowUnk->fn_800B2130(mNameCopy, mpCurrentSubtype->getTextBox(), field_0x828, true); setTextToDisplay(mpMsgWindowUnk->getProcessedText()); field_0x818 = 1; mStateMgr.changeState(StateID_OutputText); @@ -464,7 +472,7 @@ void dLytMsgWindow_c::finalizeState_WaitKeyMsgEnd1() {} void dLytMsgWindow_c::initializeState_WaitKeyMsgEnd2() {} void dLytMsgWindow_c::executeState_WaitKeyMsgEnd2() { - if (mpCurrentSubtype->vt_0x3C()) { + if (mpCurrentSubtype->isDoneDecide()) { mStateMgr.changeState(StateID_Out); } } @@ -560,7 +568,7 @@ void dLytMsgWindow_c::initializeState_Out() { mpCurrentSubtype->close(); } void dLytMsgWindow_c::executeState_Out() { - if (mpCurrentSubtype->isDoneClosing() && (field_0x817 == 0 || mpCurrentSubtype->vt_0x3C())) { + if (mpCurrentSubtype->isDoneClosing() && (field_0x817 == 0 || mpCurrentSubtype->isDoneDecide())) { removeSubMsgManagers(); mStateMgr.changeState(StateID_Invisible); } @@ -749,33 +757,39 @@ void dLytMsgWindow_c::createSubMsgManager(u8 type) { mpWindowStone->build(&mResAcc1, &mResAcc2, mpTagProcessor); break; case 2: - // TODO Sword + mpWindowSword = new dLytMsgWindowSword_c(); + mpWindowSword->setSwordType(dLytTextSword::FI); + mpWindowSword->build(&mResAcc1, &mResAcc2, mpTagProcessor); break; case 3: - // TODO Sword + mpWindowSword = new dLytMsgWindowSword_c(); + mpWindowSword->setSwordType(dLytTextSword::GHIRAHIM); + mpWindowSword->build(&mResAcc1, &mResAcc2, mpTagProcessor); break; case 4: - // TODO Sword - break; - case 5: - // TODO Get - mpWindowGet = new dLytMsgWindowWood_c(); - mpWindowGet->build(&mResAcc1, &mResAcc2, mpTagProcessor); + mpWindowSword = new dLytMsgWindowSword_c(); + mpWindowSword->setSwordType(dLytTextSword::LASTBOSS); + mpWindowSword->build(&mResAcc1, &mResAcc2, mpTagProcessor); break; case 9: // TODO Link - mpWindowLink = new dLytMsgWindowWood_c(); + mpWindowLink = new dLytMsgWindowLink_c(); mpWindowLink->build(&mResAcc1, &mResAcc2, mpTagProcessor); break; + case 5: + // TODO Get + mpWindowGet = new dLytMsgWindowGet_c(); + mpWindowGet->build(&mResAcc1, &mResAcc2, mpTagProcessor); + break; case 30: // TODO Demo - mpWindowDemo = new dLytMsgWindowWood_c(); + mpWindowDemo = new dLytMsgWindowDemo_c(); mpWindowDemo->build(&mResAcc1, &mResAcc2, mpTagProcessor); break; default: // TODO talk - mpWindowDemo = new dLytMsgWindowWood_c(); - mpWindowDemo->build(&mResAcc1, &mResAcc2, mpTagProcessor); + mpWindowTalk = new dLytMsgWindowTalk_c(); + mpWindowTalk->build(&mResAcc1, &mResAcc2, mpTagProcessor); break; } } 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 new file mode 100644 index 00000000..74674e9d --- /dev/null +++ b/src/d/lyt/msg_window/d_lyt_msg_window_sword.cpp @@ -0,0 +1,346 @@ +#include "d/lyt/msg_window/d_lyt_msg_window_sword.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 "m/m_vec.h" +#include "nw4r/lyt/lyt_group.h" +#include "nw4r/lyt/lyt_pane.h" +#include "nw4r/lyt/lyt_types.h" +#include "nw4r/math/math_types.h" +#include "s/s_State.hpp" + +STATE_DEFINE(dLytMsgWindowSword_c, Invisible); +STATE_DEFINE(dLytMsgWindowSword_c, In); +STATE_DEFINE(dLytMsgWindowSword_c, Wait); +STATE_DEFINE(dLytMsgWindowSword_c, Visible); +STATE_DEFINE(dLytMsgWindowSword_c, Out); + +static const d2d::LytBrlanMapping brlanMap[] = { + { "messageWindow_01_in.brlan", "G_inOut_00"}, + { "messageWindow_01_out.brlan", "G_inOut_00"}, + { "messageWindow_01_loop.brlan", "G_loop_00"}, + { "messageWindow_01_color.brlan", "G_color_00"}, + {"messageWindow_01_position.brlan", "G_position_00"}, +}; + +#define SWORD_ANIM_IN 0 +#define SWORD_ANIM_OUT 1 +#define SWORD_ANIM_LOOP 2 +#define SWORD_ANIM_COLOR 3 +#define SWORD_ANIM_POSITION 4 + +#define SWORD_NUM_ANIMS 5 + +#define TRANSLATE_ORIGINAL 0 +#define TRANSLATE_TO 1 +#define TRANSLATE_FROM 2 + +static const char *sPanes[] = { + "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 dLytMsgWindowSword_c::build(d2d::ResAccIf_c *resAcc1, d2d::ResAccIf_c *resAcc, dTagProcessor_c *tagProcessor) { + mLyt.setResAcc(resAcc); + mLyt.build("messageWindow_01.brlyt", nullptr); + mLyt.setPriority(0x8A); + + for (int i = 0; i < SWORD_NUM_ANIMS; i++) { + mAnm[i].init(brlanMap[i].mFile, resAcc, mLyt.getLayout(), brlanMap[i].mName); + mAnm[i].bind(false); + mAnm[i].setAnimEnable(false); + } + + mAnm[SWORD_ANIM_LOOP].setAnimEnable(true); + mAnm[SWORD_ANIM_OUT].setAnimEnable(true); + mAnm[SWORD_ANIM_OUT].setToEnd(); + mLyt.calc(); + mAnm[SWORD_ANIM_OUT].setAnimEnable(false); + + for (int i = 0; i < 3; 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); + } + } + + mSwordText.build(resAcc, mSwordType); + + for (int i = 0; i < 1023; i++) { + mCharacterData[i].posX = 0.0f; + mCharacterData[i].posY = 0.0f; + mCharacterData[i].field_0x08 = dTagProcessor_c::fn_800B8040(0, 0); + mCharacterData[i].character = L'\0'; + mCharacterData[i].field_0x0C = 1023; + mCharacterData[i].displayTimerMaybe = -1; + + mTextBuf[i] = L'\0'; + } + + mAnm[SWORD_ANIM_COLOR].setAnimEnable(true); + mAnm[SWORD_ANIM_COLOR].setFrame(mSwordType); + + mpPanes[1]->SetVisible(true); + mLyt.calc(); + mpPanes[1]->SetVisible(false); + + mAnm[SWORD_ANIM_COLOR].setAnimEnable(false); + + mpTagProcessor = tagProcessor; + + mTranslationOrig.copyFrom(mpPanes[2]->GetTranslate()); + mTranslationTo.copyFrom(mpPanes[2]->GetTranslate()); + mTranslationFrom.copyFrom(mpPanes[2]->GetTranslate()); + + mParam = 0; + field_0x05E8 = 0.0f; + field_0x05E4 = 0.0f; + field_0x5F4 = 0; + + mHasDrawnThisTick = false; + + mStateMgr.changeState(StateID_Invisible); + return true; +} + +bool dLytMsgWindowSword_c::remove() { + mSwordText.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 < SWORD_NUM_ANIMS; i++) { + mAnm[i].remove(); + } + return true; +} + +void dLytMsgWindowSword_c::initializeState_Invisible() { + mBtn.resetToInvisble(); +} +void dLytMsgWindowSword_c::executeState_Invisible() { + if (mShouldBeOpen) { + mStateMgr.changeState(StateID_In); + } +} +void dLytMsgWindowSword_c::finalizeState_Invisible() {} + +void dLytMsgWindowSword_c::initializeState_In() { + mAnm[SWORD_ANIM_POSITION].setFrame(mParam); + mAnm[SWORD_ANIM_POSITION].setAnimEnable(true); + mLyt.calc(); + mAnm[SWORD_ANIM_POSITION].setAnimEnable(false); + + mTranslationTo = mTranslationOrig; + mTranslationTo.y = mpPanes[2]->GetTranslate().y; + mTranslationFrom = mTranslationTo; + + mAnm[SWORD_ANIM_IN].setAnimEnable(true); + mAnm[SWORD_ANIM_IN].setFrame(0.0f); + + mpPanes[2]->SetTranslate(mTranslationFrom); +} +void dLytMsgWindowSword_c::executeState_In() { + if (mTranslationFrom != mTranslationTo) { + mVec3_c v; + if (mAnm[SWORD_ANIM_IN].isEndReached()) { + v = mTranslationTo; + } else { + f32 ratio = mAnm[SWORD_ANIM_IN].getRatio(); + if (ratio > 1.0f) { + ratio = 1.0f; + } + v = mTranslationFrom + (mTranslationTo - mTranslationFrom) * ratio; + } + mpPanes[2]->SetTranslate(v); + } + + if (mAnm[SWORD_ANIM_IN].isEndReached()) { + mAnm[SWORD_ANIM_IN].setAnimEnable(false); + mStateMgr.changeState(StateID_Wait); + } +} +void dLytMsgWindowSword_c::finalizeState_In() {} + +void dLytMsgWindowSword_c::initializeState_Wait() { + field_0x5F4 = UnkTextThing::getInstance()->getField_0x7AE(); +} +void dLytMsgWindowSword_c::executeState_Wait() { + if (--field_0x5F4 > 0) { + return; + } + mStateMgr.changeState(StateID_Visible); +} +void dLytMsgWindowSword_c::finalizeState_Wait() {} + +void dLytMsgWindowSword_c::initializeState_Visible() { + nw4r::lyt::Size size = getTextBox()->GetSize(); + nw4r::lyt::Size fontSize = getTextBox()->GetFontSize(); // unused + nw4r::math::MTX34 transform = getTextBox()->GetGlobalMtx(); + + field_0x05E4 = transform._03 - size.width / 2; + field_0x05E8 = transform._13 + size.height / 2; + + getTextBox()->GetTextDrawRect(); // unused +} +void dLytMsgWindowSword_c::executeState_Visible() { + if (!mShouldBeOpen) { + mStateMgr.changeState(StateID_Out); + } +} +void dLytMsgWindowSword_c::finalizeState_Visible() {} + +void dLytMsgWindowSword_c::initializeState_Out() { + mTranslationFrom = mTranslationTo; + mAnm[SWORD_ANIM_OUT].setAnimEnable(true); + mAnm[SWORD_ANIM_OUT].setFrame(0.0f); +} +void dLytMsgWindowSword_c::executeState_Out() { + if (mTranslationFrom != mTranslationTo) { + mVec3_c v; + if (mAnm[SWORD_ANIM_OUT].isEndReached()) { + v = mTranslationFrom; + } else { + // TODO floats + v = mpPanes[2]->GetTranslate(); + v += (mTranslationTo - v) / 2.0f; + } + mpPanes[2]->SetTranslate(v); + } + + if (mAnm[SWORD_ANIM_OUT].isEndReached()) { + mAnm[SWORD_ANIM_OUT].setAnimEnable(false); + mStateMgr.changeState(StateID_Visible); + } +} +void dLytMsgWindowSword_c::finalizeState_Out() {} + +bool dLytMsgWindowSword_c::execute() { + mStateMgr.executeState(); + + for (int i = 0; i < SWORD_NUM_ANIMS; i++) { + if (mAnm[i].isEnabled()) { + mAnm[i].play(); + } + } + + mLyt.calc(); + mNodes[0].mpLytPane->execute(); + mHasDrawnThisTick = false; + return true; +} + +extern "C" f32 lbl_805751A4; + +void dLytMsgWindowSword_c::draw() { + mLyt.draw(); + + for (int i = 0; i < 1023; i++) { + if (mCharacterData[i].displayTimerMaybe >= 0) { + if (!mHasDrawnThisTick) { + mCharacterData[i].displayTimerMaybe += 1; + } + wchar_t str[2]; + // FPR regswaps + f32 x = field_0x05E4 + mCharacterData[i].posX; + x /= lbl_805751A4; + f32 y = field_0x05E8 + mCharacterData[i].posY; + + str[0] = mCharacterData[i].character; + str[1] = 0; + + nw4r::math::VEC3 v(x, y, 0.0f); + mSwordText.draw(str, mCharacterData[i].displayTimerMaybe, v, mCharacterData[i].field_0x08); + if (mCharacterData[i].displayTimerMaybe >= mSwordText.fn_80120DB0()) { + mCharacterData[i].displayTimerMaybe = -1; + } + } + } + + if (!mHasDrawnThisTick) { + mHasDrawnThisTick = true; + } +} + +void dLytMsgWindowSword_c::open(dAcObjBase_c *obj, u32 param) { + mpActor = obj; + mParam = param; + mShouldBeOpen = true; +} + +bool dLytMsgWindowSword_c::isDoneOpening() const { + if (*mStateMgr.getStateID() == StateID_In || *mStateMgr.getStateID() == StateID_Wait) { + return false; + } + return true; +} + +void dLytMsgWindowSword_c::close() { + mShouldBeOpen = false; +} + +bool dLytMsgWindowSword_c::isDoneClosing() const { + return !(*mStateMgr.getStateID() == StateID_Out); +} + +bool dLytMsgWindowSword_c::setText(const wchar_t *text) { + int foundIdx = 1023; + for (int i = 0; i < 1023; i++) { + if (mCharacterData[i].displayTimerMaybe >= 0 && foundIdx > mCharacterData[i].field_0x0C) { + foundIdx = mCharacterData[i].field_0x0C; + } + } + + // How is text bounds-checked here???? + for (int i = 0; i < 1023; i++) { + if (i < foundIdx) { + mTextBuf[i] = text[i]; + } else { + mTextBuf[i] = L' '; + } + } + + mpTextboxes[0]->SetTagProcessor(mpTagProcessor); + mpTextboxes[1]->SetTagProcessor(mpTagProcessor); + mpTextboxes[0]->setTextWithTextProcessor(mTextBuf, mpTagProcessor, 0); + mpTextboxes[1]->setTextWithTextProcessor(mTextBuf, mpTagProcessor, 0); + return foundIdx == 1023; +} |
