diff --git a/data/file_list.yml b/data/file_list.yml index 0e7a7041..c1a29c88 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -272068,99 +272068,99 @@ Library/Play/Layout/WindowConfirm.o: - offset: 0x99ade0 size: 740 label: _ZN2al13WindowConfirmC2ERKNS_14LayoutInitInfoEPKcS5_ - status: NotDecompiled + status: Matching - offset: 0x99b0c4 size: 748 label: _ZN2al13WindowConfirmC1ERKNS_14LayoutInitInfoEPKcS5_ - status: NotDecompiled + status: Matching - offset: 0x99b3b0 size: 28 label: _ZN2al13WindowConfirm13setTxtMessageEPKDs - status: NotDecompiled + status: Matching - offset: 0x99b3cc size: 56 label: _ZN2al13WindowConfirm10setTxtListEiPKDs - status: NotDecompiled + status: Matching - offset: 0x99b404 size: 40 label: _ZN2al13WindowConfirm10setListNumEi - status: NotDecompiled + status: Matching - offset: 0x99b42c size: 8 label: _ZN2al13WindowConfirm12setCancelIdxEi - status: NotDecompiled + status: Matching - offset: 0x99b434 size: 652 label: _ZN2al13WindowConfirm6appearEv - status: NotDecompiled + status: Matching - offset: 0x99b6c0 size: 200 label: _ZN2al13WindowConfirm24appearWithChoicingCancelEv - status: NotDecompiled + status: Matching - offset: 0x99b788 size: 12 label: _ZN2al13WindowConfirm10isNerveEndEv - status: NotDecompiled + status: Matching - offset: 0x99b794 size: 120 label: _ZN2al13WindowConfirm6tryEndEv - status: NotDecompiled + status: Matching - offset: 0x99b80c size: 100 label: _ZN2al13WindowConfirm13isEnableInputEv - status: NotDecompiled + status: Matching - offset: 0x99b870 size: 104 label: _ZN2al13WindowConfirm5tryUpEv - status: NotDecompiled + status: Matching - offset: 0x99b8d8 size: 108 label: _ZN2al13WindowConfirm7tryDownEv - status: NotDecompiled + status: Matching - offset: 0x99b944 size: 144 label: _ZN2al13WindowConfirm9tryDecideEv - status: NotDecompiled + status: Matching - offset: 0x99b9d4 size: 128 label: _ZN2al13WindowConfirm19tryDecideWithoutEndEv - status: NotDecompiled + status: Matching - offset: 0x99ba54 size: 428 label: _ZN2al13WindowConfirm9tryCancelEv - status: NotDecompiled + status: Matching - offset: 0x99bc00 size: 148 label: _ZN2al13WindowConfirm15setCursorToPaneEv - status: NotDecompiled + status: Matching - offset: 0x99bc94 size: 412 label: _ZN2al13WindowConfirm19tryCancelWithoutEndEv - status: NotDecompiled + status: Matching - offset: 0x99be30 size: 4 label: _ZN2al13WindowConfirm7exeHideEv - status: NotDecompiled + status: Matching - offset: 0x99be34 size: 200 label: _ZN2al13WindowConfirm9exeAppearEv - status: NotDecompiled + status: Matching - offset: 0x99befc size: 816 label: _ZN2al13WindowConfirm7exeWaitEv - status: NotDecompiled + status: Matching - offset: 0x99c22c size: 304 label: _ZN2al13WindowConfirm9exeDecideEv - status: NotDecompiled + status: Matching - offset: 0x99c35c size: 16 label: _ZN2al13WindowConfirm14exeDecideAfterEv - status: NotDecompiled + status: Matching - offset: 0x99c36c size: 112 label: _ZN2al13WindowConfirm6exeEndEv - status: NotDecompiled + status: Matching - offset: 0x99c3dc size: 4 label: '' diff --git a/lib/al/Library/Play/Layout/WindowConfirm.cpp b/lib/al/Library/Play/Layout/WindowConfirm.cpp new file mode 100644 index 00000000..c8b68368 --- /dev/null +++ b/lib/al/Library/Play/Layout/WindowConfirm.cpp @@ -0,0 +1,340 @@ +#include "Library/Play/Layout/WindowConfirm.h" + +#include "Library/Base/StringUtil.h" +#include "Library/Layout/LayoutActionFunction.h" +#include "Library/Layout/LayoutActorUtil.h" +#include "Library/Layout/LayoutInitInfo.h" +#include "Library/Nerve/NerveSetupUtil.h" +#include "Library/Nerve/NerveUtil.h" + +namespace { +using namespace al; +NERVE_IMPL(WindowConfirm, Hide); +NERVE_IMPL(WindowConfirm, Appear); +NERVE_IMPL(WindowConfirm, End); +NERVE_IMPL(WindowConfirm, Decide); +NERVE_IMPL(WindowConfirm, Wait); +NERVE_IMPL(WindowConfirm, DecideAfter); + +NERVES_MAKE_NOSTRUCT(WindowConfirm, Hide, Appear, DecideAfter); +NERVES_MAKE_STRUCT(WindowConfirm, End, Decide, Wait); + +} // namespace + +namespace al { + +WindowConfirm::WindowConfirm(const LayoutInitInfo& info, const char* name, const char* actorName) + : LayoutActor(actorName) { + initLayoutActor(this, info, name); + + s32 paneChildNum = getPaneChildNum(this, "All"); + s32 i = 0; + + s32 numberOfPanes = 0; + for (i = 0; i < paneChildNum; i++) + numberOfPanes += isExistPane(this, StringTmp<64>("ParList%02d", i).cstr()); + + mParListArray.allocBuffer(numberOfPanes, nullptr, 8); + + for (i = 0; i < numberOfPanes; i++) { + LayoutActor* choiceActor = new LayoutActor(StringTmp<64>("選択肢%02d", i).cstr()); + initLayoutPartsActor(choiceActor, this, info, StringTmp<64>("ParList%02d", i).cstr(), + nullptr); + + mParListArray.pushBack(choiceActor); + } + + if (isExistPane(this, "ParHardKey")) { + mButtonActor = new LayoutActor("Aボタン"); + initLayoutPartsActor(mButtonActor, this, info, "ParHardKey"); + } + + mCursorActor = new LayoutActor("カーソル"); + initLayoutPartsActor(mCursorActor, this, info, "ParCursor"); + initNerve(&Hide); +} + +void WindowConfirm::setTxtMessage(const char16* message) { + setPaneString(this, "TxtMessage", message); +} + +void WindowConfirm::setTxtList(s32 index, const char16* message) { + setPaneString(mParListArray.at(index), "TxtContent", message); +} + +void WindowConfirm::setListNum(s32 num) { + mSelection.selectionType = (SelectionType)num; + if (mSelection.selectionType == SelectionType::List01) + setCancelIdx((s32)SelectionType::List00); + if (mSelection.selectionType == SelectionType::List02) + setCancelIdx((s32)SelectionType::HardKey); +} + +void WindowConfirm::setCancelIdx(s32 index) { + mSelection.cancelType = (SelectionType)index; +} + +void WindowConfirm::appear() { + if (isAlive()) + return; + + mSelection.prevSelectionType = SelectionType::HardKey; + mDirection = Direction::None; + + startAction(this, "Appear", nullptr); + switch (mSelection.selectionType) { + case SelectionType::HardKey: + startAction(this, "SelectHardKey", "Select"); + + hidePane(this, "ParCursor"); + hidePane(this, "ParHardKey"); + break; + case SelectionType::List00: + startAction(this, "SelectHardKey", "Select"); + startAction(mButtonActor, "Appear", nullptr); + + hidePane(this, "ParCursor"); + showPane(this, "ParHardKey"); + break; + case SelectionType::List01: + startAction(this, "Select2", "Select"); + startAction(mCursorActor, "Appear", nullptr); + startAction(mParListArray[(s32)SelectionType::HardKey], "Select", nullptr); + startAction(mParListArray[(s32)SelectionType::List00], "Wait", nullptr); + + showPane(this, "ParCursor"); + hidePane(this, "ParHardKey"); + break; + case SelectionType::List02: + startAction(this, "Select3", "Select"); + startAction(mCursorActor, "Appear", nullptr); + startAction(mParListArray[(s32)SelectionType::HardKey], "Select", nullptr); + startAction(mParListArray[(s32)SelectionType::List00], "Wait", nullptr); + startAction(mParListArray[(s32)SelectionType::List01], "Wait", nullptr); + + showPane(this, "ParCursor"); + hidePane(this, "ParHardKey"); + break; + default: + break; + } + LayoutActor::appear(); + setNerve(this, &Appear); +} + +void WindowConfirm::appearWithChoicingCancel() { + if (isAlive()) + return; + + appear(); + + if (mSelection.selectionType == SelectionType::List01) { + startAction(mParListArray[getPrevSelectionIdx()], "Wait", nullptr); + startAction(mParListArray[getCancelIdx()], "Select", nullptr); + } else if (mSelection.selectionType == SelectionType::List02) { + startAction(mParListArray[getPrevSelectionIdx()], "Wait", nullptr); + startAction(mParListArray[getCancelIdx()], "Select", nullptr); + } + + mSelection.prevSelectionType = mSelection.cancelType; +} + +bool WindowConfirm::isNerveEnd() { + return isNerve(this, &NrvWindowConfirm.End); +} + +bool WindowConfirm::tryEnd() { + if (isEnableInput()) { + mIsDecided = false; + setNerve(this, &NrvWindowConfirm.End); + return true; + } + return false; +} + +bool WindowConfirm::isEnableInput() { + if (mCooldown <= 0 && isNerve(this, &NrvWindowConfirm.Wait) && isGreaterEqualStep(this, 10)) { + mCooldown = 10; + return true; + } + return false; +} + +bool WindowConfirm::tryUp() { + if (isEnableInput()) { + mDirection = Direction::Up; + return true; + } + return false; +} + +bool WindowConfirm::tryDown() { + if (isEnableInput()) { + mDirection = Direction::Down; + return true; + } + return false; +} + +bool WindowConfirm::tryDecide() { + if (isEnableInput()) { + mIsDecided = false; + startHitReaction(this, "決定", nullptr); + setNerve(this, &NrvWindowConfirm.Decide); + return true; + } + return false; +} + +bool WindowConfirm::tryDecideWithoutEnd() { + if (isEnableInput()) { + mIsDecided = true; + setNerve(this, &NrvWindowConfirm.Decide); + return true; + } + return false; +} + +bool WindowConfirm::tryCancel() { + if (!isEnableInput()) + return false; + + if ((mSelection.selectionType == SelectionType::List01 || + mSelection.selectionType == SelectionType::List02) && + mSelection.prevSelectionType != mSelection.cancelType) { + startAction(mParListArray[getPrevSelectionIdx()], "Wait", nullptr); + startAction(mParListArray[getCancelIdx()], "Select", nullptr); + mSelection.prevSelectionType = mSelection.cancelType; + setCursorToPane(); + } + + startHitReaction(this, "キャンセル", nullptr); + mIsDecided = false; + setNerve(this, &NrvWindowConfirm.Decide); + return true; +} + +void WindowConfirm::setCursorToPane() { + if (mSelection.selectionType >= SelectionType::List01) { + sead::Vector3f trans = {1.0f, 1.0f, 1.0f}; + calcPaneTrans(&trans, mParListArray[getPrevSelectionIdx()], "Cursor"); + setPaneLocalTrans(this, "ParCursor", trans); + } +} + +bool WindowConfirm::tryCancelWithoutEnd() { + if (!isEnableInput()) + return false; + + if ((mSelection.selectionType == SelectionType::List01 || + mSelection.selectionType == SelectionType::List02) && + mSelection.prevSelectionType != mSelection.cancelType) { + startAction(mParListArray[getPrevSelectionIdx()], "Wait", nullptr); + startAction(mParListArray[getCancelIdx()], "Select", nullptr); + mSelection.prevSelectionType = mSelection.cancelType; + setCursorToPane(); + } + mIsDecided = true; + setNerve(this, &NrvWindowConfirm.Decide); + return true; +} + +void WindowConfirm::exeHide() {} + +void WindowConfirm::exeAppear() { + if (mSelection.selectionType == SelectionType::List01 || + mSelection.selectionType == SelectionType::List02) + setCursorToPane(); + if (isActionEnd(this, nullptr)) + setNerve(this, &NrvWindowConfirm.Wait); +} + +void WindowConfirm::exeWait() { + if (isFirstStep(this)) { + startAction(this, "Wait", nullptr); + mCooldown = -1; + } + + if (mSelection.selectionType == SelectionType::List01 || + mSelection.selectionType == SelectionType::List02) { + if (isActionPlaying(mCursorActor, "Appear", nullptr) && isActionEnd(mCursorActor, nullptr)) + startAction(mCursorActor, "Wait", nullptr); + } else { + if (mSelection.selectionType == SelectionType::List00) + if (isActionPlaying(mButtonActor, "Appear", nullptr) && + isActionEnd(mButtonActor, nullptr)) + startAction(mButtonActor, "Wait", nullptr); + } + + if (mDirection == Direction::Up) { + startAction(mParListArray[getPrevSelectionIdx()], "Wait", nullptr); + if (updateSelectionIdx(Direction::Up) < SelectionType::HardKey) + mSelection.prevSelectionType = (SelectionType)((s32)mSelection.selectionType - 1); + + startAction(mParListArray[getPrevSelectionIdx()], "Select", nullptr); + setCursorToPane(); + } + if (mDirection == Direction::Down) { + startAction(mParListArray[getPrevSelectionIdx()], "Wait", nullptr); + if (updateSelectionIdx(Direction::Down) >= mSelection.selectionType) + mSelection.prevSelectionType = SelectionType::HardKey; + + startAction(mParListArray[getPrevSelectionIdx()], "Select", nullptr); + setCursorToPane(); + } + + mDirection = Direction::None; + + if (mCooldown >= 0) + mCooldown--; +} + +void WindowConfirm::exeDecide() { + if (isFirstStep(this)) { + switch (mSelection.selectionType) { + case SelectionType::HardKey: + setNerve(this, &DecideAfter); + return; + case SelectionType::List00: + startAction(mButtonActor, "PageEnd", nullptr); + break; + case SelectionType::List01: + case SelectionType::List02: + startAction(mParListArray[getPrevSelectionIdx()], "Decide", nullptr); + startAction(mCursorActor, "End", nullptr); + break; + default: + break; + } + } + + switch (mSelection.selectionType) { + case SelectionType::List00: + if (isActionEnd(mButtonActor, nullptr)) + setNerve(this, &DecideAfter); + return; + case SelectionType::List01: + case SelectionType::List02: + if (isActionEnd(mParListArray[getPrevSelectionIdx()], nullptr)) + setNerve(this, &DecideAfter); + return; + default: + break; + } +} + +void WindowConfirm::exeDecideAfter() { + setNerveAtGreaterEqualStep(this, &NrvWindowConfirm.End, 0); +} + +void WindowConfirm::exeEnd() { + if (!mIsDecided) { + if (isFirstStep(this)) + startAction(this, "End", nullptr); + + if (isActionEnd(this, nullptr)) + kill(); + } +} + +} // namespace al diff --git a/lib/al/Library/Play/Layout/WindowConfirm.h b/lib/al/Library/Play/Layout/WindowConfirm.h index ba4aff07..d3df4e12 100644 --- a/lib/al/Library/Play/Layout/WindowConfirm.h +++ b/lib/al/Library/Play/Layout/WindowConfirm.h @@ -24,16 +24,17 @@ public: }; struct Selection { - SelectionType selectionType; - SelectionType prevSelectionType; + SelectionType selectionType = SelectionType::None; + SelectionType prevSelectionType = SelectionType::None; + SelectionType cancelType = SelectionType::None; }; - WindowConfirm(const LayoutInitInfo&, const char*, const char*); + WindowConfirm(const LayoutInitInfo& info, const char* name, const char* actorName); - void setTxtMessage(const char16*); - void setTxtList(s32, const char16*); - void setListNum(s32); - void setCancelIdx(s32); + void setTxtMessage(const char16* message); + void setTxtList(s32 index, const char16* message); + void setListNum(s32 num); + void setCancelIdx(s32 index); void appear() override; void appearWithChoicingCancel(); bool isNerveEnd(); @@ -46,6 +47,7 @@ public: bool tryCancel(); void setCursorToPane(); bool tryCancelWithoutEnd(); + void exeHide(); void exeAppear(); void exeWait(); @@ -53,14 +55,31 @@ public: void exeDecideAfter(); void exeEnd(); + s32 getSelectionIdx() { return (s32)mSelection.prevSelectionType; } + + s32 getPrevSelectionIdx() { return (s32)mSelection.prevSelectionType; } + + s32 getCancelIdx() { return (s32)mSelection.cancelType; } + + SelectionType getSelectionType() { return mSelection.selectionType; } + SelectionType getPrevSelectionType() { return mSelection.prevSelectionType; } + SelectionType getCancelType() { return mSelection.cancelType; } + + SelectionType updateSelectionIdx(Direction dir) { + if (dir == Direction::Up) + mSelection.prevSelectionType = (SelectionType)((s32)mSelection.prevSelectionType - 1); + else if (dir == Direction::Down) + mSelection.prevSelectionType = (SelectionType)((s32)mSelection.prevSelectionType + 1); + return mSelection.prevSelectionType; + } + private: - Direction mDirection; + Direction mDirection = Direction::None; Selection mSelection; - s32 mCancelIdx; - bool mIsDecided; - s32 mCooldown; + bool mIsDecided = false; + s32 mCooldown = -1; sead::PtrArray mParListArray; LayoutActor* mCursorActor; LayoutActor* mButtonActor;