Sword somewhat ok, though not well understood

This commit is contained in:
robojumper
2025-04-04 21:14:40 +02:00
parent 4612c35f45
commit af4a1cfdb0
20 changed files with 858 additions and 144 deletions
+5 -5
View File
@@ -212,7 +212,7 @@ void dLytCommonIconItemPart1_c::setOff() {
}
}
void dLytCommonIconItemPart1_c::startDecide() {
void dLytCommonIconItemPart1_c::startConfirm() {
mAnm[ITEM_PART_1_ANIM_DECIDE].setForwardOnce();
mAnm[ITEM_PART_1_ANIM_DECIDE].setToStart();
mAnm[ITEM_PART_1_ANIM_DECIDE].setAnimEnable(true);
@@ -545,7 +545,7 @@ void dLytCommonIconItemPart2_c::setOff() {
}
}
void dLytCommonIconItemPart2_c::startDecide() {
void dLytCommonIconItemPart2_c::startConfirm() {
mAnm[ITEM_PART_2_ANIM_DECIDE].setForwardOnce();
mAnm[ITEM_PART_2_ANIM_DECIDE].setToStart();
mAnm[ITEM_PART_2_ANIM_DECIDE].setAnimEnable(true);
@@ -849,10 +849,10 @@ void dLytCommonIconItem_c::setOff() {
}
}
void dLytCommonIconItem_c::startDecide() {
void dLytCommonIconItem_c::startConfirm() {
switch (mPart) {
case 0: mPart1.startDecide(); break;
case 1: mPart2.startDecide(); break;
case 0: mPart1.startConfirm(); break;
case 1: mPart2.startConfirm(); break;
case 2: break;
}
}
+39 -25
View File
@@ -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;
}
}
@@ -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;
}