diff --git a/data/file_list.yml b/data/file_list.yml index 4fd8542c19..0327b1cfd4 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -145611,97 +145611,97 @@ Sequence/HakoniwaStateDemoEnding.o: label: - _ZN23HakoniwaStateDemoEndingC1EP16HakoniwaSequencePN2al10WipeHolderEPNS2_21ScreenCaptureExecutorEP24HakoniwaStateDeleteSceneP19WorldResourceLoaderP14GameDataHolder - _ZN23HakoniwaStateDemoEndingC2EP16HakoniwaSequencePN2al10WipeHolderEPNS2_21ScreenCaptureExecutorEP24HakoniwaStateDeleteSceneP19WorldResourceLoaderP14GameDataHolder - status: NotDecompiled + status: Matching - offset: 0x511c58 size: 92 label: - _ZN23HakoniwaStateDemoEndingD1Ev - _ZN23HakoniwaStateDemoEndingD2Ev - status: NotDecompiled + status: Matching - offset: 0x511cb4 size: 100 label: _ZN23HakoniwaStateDemoEndingD0Ev - status: NotDecompiled + status: Matching - offset: 0x511d18 size: 92 label: _ZN23HakoniwaStateDemoEnding4initEv - status: NotDecompiled + status: Matching - offset: 0x511d74 size: 92 label: _ZN23HakoniwaStateDemoEnding6appearEv - status: NotDecompiled + status: Matching - offset: 0x511dd0 size: 44 label: _ZN23HakoniwaStateDemoEnding4killEv - status: NotDecompiled + status: Matching - offset: 0x511dfc size: 96 label: _ZN23HakoniwaStateDemoEnding20exeLoadWorldResourceEv - status: NotDecompiled + status: Matching - offset: 0x511e5c size: 92 label: _ZN23HakoniwaStateDemoEnding26exeLoadWorldResourceSecondEv - status: NotDecompiled + status: Matching - offset: 0x511eb8 size: 376 label: _ZN23HakoniwaStateDemoEnding7exeLoadEv - status: NotDecompiled + status: Matching - offset: 0x512030 size: 92 label: _ZN23HakoniwaStateDemoEnding13exeDemoEndingEv - status: NotDecompiled + status: Matching - offset: 0x51208c size: 152 label: _ZN23HakoniwaStateDemoEnding12exeEndEndingEv - status: NotDecompiled + status: Matching - offset: 0x512124 size: 412 label: _ZN23HakoniwaStateDemoEnding16exeLoadStaffRollEv - status: NotDecompiled + status: Matching - offset: 0x5122c0 size: 120 label: _ZN23HakoniwaStateDemoEnding16exeDemoStaffRollEv - status: NotDecompiled + status: Matching - offset: 0x512338 size: 108 label: _ZN23HakoniwaStateDemoEnding6exeEndEv - status: NotDecompiled + status: Matching - offset: 0x5123a4 size: 8 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_130HakoniwaStateDemoEndingNrvLoad7executeEPN2al11NerveKeeperE + status: Matching - offset: 0x5123ac size: 8 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_135HakoniwaStateDemoEndingNrvEndEnding7executeEPN2al11NerveKeeperE + status: Matching - offset: 0x5123b4 size: 112 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_129HakoniwaStateDemoEndingNrvEnd7executeEPN2al11NerveKeeperE + status: Matching - offset: 0x512424 size: 100 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_143HakoniwaStateDemoEndingNrvLoadWorldResource7executeEPN2al11NerveKeeperE + status: Matching - offset: 0x512488 size: 96 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_149HakoniwaStateDemoEndingNrvLoadWorldResourceSecond7executeEPN2al11NerveKeeperE + status: Matching - offset: 0x5124e8 size: 92 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_136HakoniwaStateDemoEndingNrvDemoEnding7executeEPN2al11NerveKeeperE + status: Matching - offset: 0x512544 size: 8 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_139HakoniwaStateDemoEndingNrvLoadStaffRoll7executeEPN2al11NerveKeeperE + status: Matching - offset: 0x51254c size: 120 - label: '' - status: NotDecompiled + label: _ZNK12_GLOBAL__N_139HakoniwaStateDemoEndingNrvDemoStaffRoll7executeEPN2al11NerveKeeperE + status: Matching - offset: 0x5125c4 size: 32 - label: '' - status: NotDecompiled + label: _GLOBAL__sub_I_HakoniwaStateDemoEnding.cpp + status: Matching Sequence/HakoniwaStateDemoOpening.o: '.text': - offset: 0x5125e4 diff --git a/lib/al/Library/Nerve/NerveStateBase.h b/lib/al/Library/Nerve/NerveStateBase.h index 38a9a5fba8..cce49f7a68 100644 --- a/lib/al/Library/Nerve/NerveStateBase.h +++ b/lib/al/Library/Nerve/NerveStateBase.h @@ -40,6 +40,9 @@ class HostStateBase : public NerveStateBase { T* getHost() const { return mHost; } +protected: + T** getHostPtr() { return &mHost; } + private: T* mHost; }; diff --git a/lib/al/Library/Play/Layout/WipeHolder.h b/lib/al/Library/Play/Layout/WipeHolder.h index bbfc234aad..f54c0bcacd 100644 --- a/lib/al/Library/Play/Layout/WipeHolder.h +++ b/lib/al/Library/Play/Layout/WipeHolder.h @@ -24,12 +24,19 @@ class WipeHolder { bool isOpenEnd() const; bool isCloseWipe(const char* name) const; + bool isClose() const { return mIsClose; } + private: s32 mMaxWipeCount; s32 mWipeCount; - void* _8; + s32 mCurrentWipeIndex; + u32 _c; WipeSimple** mWipes; - void* filler[4]; + bool mIsClose; + u8 _19[7]; + void* _20; + void* _28; + s32 _30; }; } // namespace al diff --git a/lib/al/Library/Scene/Scene.h b/lib/al/Library/Scene/Scene.h index 3640b4cadf..713d0a8acc 100644 --- a/lib/al/Library/Scene/Scene.h +++ b/lib/al/Library/Scene/Scene.h @@ -83,6 +83,8 @@ class Scene : public NerveExecutor, DrawSystemInfo* getDrawSystemInfo() const { return mDrawSystemInfo; } + bool isAlive() const { return mIsAlive; } + private: bool mIsAlive = false; sead::FixedSafeString<0x40> mName; diff --git a/lib/al/Library/Sequence/Sequence.h b/lib/al/Library/Sequence/Sequence.h index ee07255dd6..6a743256f1 100644 --- a/lib/al/Library/Sequence/Sequence.h +++ b/lib/al/Library/Sequence/Sequence.h @@ -6,13 +6,24 @@ #include "Library/Nerve/NerveExecutor.h" #include "Library/Sequence/IUseSceneCreator.h" +namespace sead { +class Heap; +} // namespace sead + +namespace alSceneFunction { +class SceneFactory; +} // namespace alSceneFunction + namespace al { struct GameSystemInfo; struct DrawSystemInfo; struct SequenceInitInfo; struct AudioSystemInfo; +struct AudioDirectorInitInfo; +class GameDataHolderBase; class AudioDirector; class Scene; +class ScreenCaptureExecutor; class Sequence : public NerveExecutor, public IUseAudioKeeper, public IUseSceneCreator { public: @@ -43,6 +54,10 @@ class Sequence : public NerveExecutor, public IUseAudioKeeper, public IUseSceneC DrawSystemInfo* getDrawInfo() const { return mDrawSystemInfo; } + AudioDirector* getAudioDirector() const { return mAudioDirector; } + + void setNextScene(Scene* scene) { mNextScene = scene; } + private: sead::FixedSafeString<0x40> mName; Scene* mCurrentScene = nullptr; @@ -53,4 +68,25 @@ class Sequence : public NerveExecutor, public IUseAudioKeeper, public IUseSceneC DrawSystemInfo* mDrawSystemInfo = nullptr; bool mIsAlive = true; }; + +void initSceneCreator(IUseSceneCreator* sceneCreator, const SequenceInitInfo& initInfo, + GameDataHolderBase* gameDataHolder, AudioDirector* audioDirector, + ScreenCaptureExecutor* screenCaptureExecutor, + alSceneFunction::SceneFactory* sceneFactory); +Scene* createSceneAndInit(IUseSceneCreator* sceneCreator, const char* stageName, + const char* sceneName, s32 scenarioNo, const char* sequenceParam); +void createSceneAndUseInitThread(IUseSceneCreator* sceneCreator, const char* stageName, + s32 priority, const char* sceneName, s32 scenarioNo, + const char* sequenceParam); +void setSceneAndInit(IUseSceneCreator* sceneCreator, Scene* scene, const char* stageName, + s32 scenarioNo, const char* sequenceParam); +void setSceneAndUseInitThread(IUseSceneCreator* sceneCreator, Scene* scene, s32 priority, + const char* stageName, s32 scenarioNo, const char* sequenceParam, + sead::Heap* heap); +bool tryEndSceneInitThread(IUseSceneCreator* sceneCreator); +bool isExistSceneInitThread(const IUseSceneCreator* sceneCreator); +void initAudioDirector(Sequence* sequence, AudioSystemInfo* audioSystemInfo, + AudioDirectorInitInfo& initInfo); +void setSequenceAudioKeeperToSceneSeDirector(Sequence* sequence, Scene* scene); +void setSequenceNameForActorPickTool(Sequence* sequence, Scene* scene); } // namespace al diff --git a/src/Scene/EndingScene.h b/src/Scene/EndingScene.h new file mode 100644 index 0000000000..f412774d22 --- /dev/null +++ b/src/Scene/EndingScene.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include + +#include "Library/Scene/Scene.h" + +namespace al { +struct ActorInitInfo; +class LayoutInitInfo; +struct SceneInitInfo; +class StageInfo; +class WipeHolder; +} // namespace al + +class EndingScene : public al::Scene { +public: + explicit EndingScene(al::WipeHolder* wipeHolder); + + void init(const al::SceneInitInfo& initInfo) override; + void appear() override; + void kill() override; + void control() override; + void drawMain() const override; + + void exePlay(); + bool isLoadEnd() const; + void exeSkipProc(); + void initLayout(const al::LayoutInitInfo& layoutInitInfo); + void initPlacement(const al::ActorInitInfo& actorInitInfo); + void initPlacementSky(const al::StageInfo* stageInfo, const al::ActorInitInfo& actorInitInfo); + void initPlacementDemo(const al::StageInfo* stageInfo, const al::ActorInitInfo& actorInitInfo); + void initPlacementObject(const al::StageInfo* stageInfo, const al::ActorInitInfo& actorInitInfo, + const char* placementKey); + + void setLoadEnd(bool isLoadEnd) { mIsLoadEnd = isLoadEnd; } + +private: + sead::FixedSafeString<64> mStageName; + u8 _130[0x10]; + bool mIsLoadEnd = false; + u8 _141[7]; + void* _148 = nullptr; + s32 _150 = 1; + u8 _154[4]; + void* _158 = nullptr; + s32 _160 = 0; + u8 _164[4]; + void* _168 = nullptr; + void* _170 = nullptr; + void* _178 = nullptr; + void* _180 = nullptr; + al::WipeHolder* mWipeHolder = nullptr; +}; + +static_assert(sizeof(EndingScene) == 0x190, "EndingScene size"); diff --git a/src/Scene/StaffRollScene.h b/src/Scene/StaffRollScene.h new file mode 100644 index 0000000000..602a64a348 --- /dev/null +++ b/src/Scene/StaffRollScene.h @@ -0,0 +1,62 @@ +#pragma once + +#include + +#include "Library/Message/IUseMessageSystem.h" +#include "Library/Scene/Scene.h" + +namespace al { +struct ActorInitInfo; +class LayoutInitInfo; +class MessageSystem; +class Nerve; +struct SceneInitInfo; +class StageInfo; +class WipeHolder; +} // namespace al + +class StaffRollScene : public al::Scene, public al::IUseMessageSystem { +public: + explicit StaffRollScene(al::WipeHolder* wipeHolder); + + void init(const al::SceneInitInfo& initInfo) override; + void appear() override; + void kill() override; + void control() override; + void drawMain() const override; + const al::MessageSystem* getMessageSystem() const override; + + void initRollLineData(); + void exeTitleLogo(); + void exeRollLine(); + void initCurrentRollLines(); + void initSlideShowFrame(); + void updateRollLine(); + void updateSlideShow(); + void tryChangeToSkipConfirm(const al::Nerve* nextNerve); + void exeThank(); + void dropAllRollLine(); + void exeShowPicture(); + void exeRight(); + void exeConfirm(); + void exeSkipProc(); + void exeSkipWipe(); + void killRollLine(); + s32 getMyNerveStep() const; + void initLayout(const al::LayoutInitInfo& layoutInitInfo); + f32 calcNameRollTimeRate(f32 rate); + void dropCurrentToStock(); + void initPlacement(const al::ActorInitInfo& actorInitInfo); + void initPlacementSky(const al::StageInfo* stageInfo, const al::ActorInitInfo& actorInitInfo); + void initPlacementObject(const al::StageInfo* stageInfo, const al::ActorInitInfo& actorInitInfo, + const char* placementKey); + void initPlacementDemo(const al::StageInfo* stageInfo, const al::ActorInitInfo& actorInitInfo); + bool isCanSkip(); + +private: + const al::MessageSystem* mMessageSystem = nullptr; + al::WipeHolder* mWipeHolder = nullptr; + u8 _f0[0x6160]; +}; + +static_assert(sizeof(StaffRollScene) == 0x6250, "StaffRollScene size"); diff --git a/src/Sequence/HakoniwaStateDeleteScene.h b/src/Sequence/HakoniwaStateDeleteScene.h new file mode 100644 index 0000000000..96bfb73cb3 --- /dev/null +++ b/src/Sequence/HakoniwaStateDeleteScene.h @@ -0,0 +1,37 @@ +#pragma once + +#include + +#include "Library/Nerve/NerveStateBase.h" +#include "Library/Sequence/Sequence.h" + +class WorldResourceLoader; + +namespace al { +class AsyncFunctorThread; +class Scene; +} // namespace al + +class HakoniwaStateDeleteScene : public al::HostStateBase { +public: + HakoniwaStateDeleteScene(al::Sequence* sequence, WorldResourceLoader* resourceLoader); + + void appear() override; + void kill() override; + + void deleteScene(); + void start(al::Scene* scene, bool destroyResource, bool finalizeAudio, s32 stopSeFrame); + void exePrepare(); + void exeFinalizeAudio(); + void exeDeleteScene(); + +private: + al::Scene* mScene = nullptr; + al::AsyncFunctorThread* mDeleteSceneThread = nullptr; + bool mIsDestroyResource = false; + bool mIsFinalizeAudio = false; + s32 mStopSeFrame = 0; + WorldResourceLoader* mResourceLoader = nullptr; +}; + +static_assert(sizeof(HakoniwaStateDeleteScene) == 0x40, "HakoniwaStateDeleteScene size"); diff --git a/src/Sequence/HakoniwaStateDemoEnding.cpp b/src/Sequence/HakoniwaStateDemoEnding.cpp new file mode 100644 index 0000000000..5fb179ef8e --- /dev/null +++ b/src/Sequence/HakoniwaStateDemoEnding.cpp @@ -0,0 +1,235 @@ +#include "Sequence/HakoniwaStateDemoEnding.h" + +#include +#include +#include + +#include "Library/Audio/System/AudioKeeperFunction.h" +#include "Library/Bgm/BgmLineFunction.h" +#include "Library/Memory/HeapUtil.h" +#include "Library/Nerve/NerveSetupUtil.h" +#include "Library/Nerve/NerveUtil.h" +#include "Library/Play/Layout/WipeHolder.h" +#include "Library/Resource/ResourceFunction.h" +#include "Library/Scene/Scene.h" +#include "Library/Screen/ScreenFunction.h" +#include "Library/Sequence/Sequence.h" +#include "Project/Memory/SceneHeapSetter.h" + +#include "Scene/EndingScene.h" +#include "Scene/StaffRollScene.h" +#include "Sequence/HakoniwaSequence.h" +#include "Sequence/HakoniwaStateDeleteScene.h" +#include "Sequence/WorldResourceLoader.h" +#include "System/GameDataFunction.h" + +const s32 cDefaultPriority = sead::Thread::cDefaultPriority; +const s32 cPriority = cDefaultPriority + 3; + +namespace { +NERVE_IMPL(HakoniwaStateDemoEnding, Load); +NERVE_IMPL(HakoniwaStateDemoEnding, EndEnding); +NERVE_IMPL(HakoniwaStateDemoEnding, End); +NERVE_IMPL(HakoniwaStateDemoEnding, LoadWorldResource); +NERVE_IMPL(HakoniwaStateDemoEnding, LoadWorldResourceSecond); +NERVE_IMPL(HakoniwaStateDemoEnding, DemoEnding); +NERVE_IMPL(HakoniwaStateDemoEnding, LoadStaffRoll); +NERVE_IMPL(HakoniwaStateDemoEnding, DemoStaffRoll); + +NERVES_MAKE_NOSTRUCT(HakoniwaStateDemoEnding, Load, DemoEnding, LoadStaffRoll, DemoStaffRoll); +NERVES_MAKE_STRUCT(HakoniwaStateDemoEnding, LoadWorldResource, EndEnding, End, + LoadWorldResourceSecond); +} // namespace + +HakoniwaStateDemoEnding::HakoniwaStateDemoEnding(HakoniwaSequence* sequence, + al::WipeHolder* wipeHolder, + al::ScreenCaptureExecutor* screenCaptureExecutor, + HakoniwaStateDeleteScene* stateDeleteScene, + WorldResourceLoader* resourceLoader, + GameDataHolder* gameDataHolder) + : al::HostStateBase("エンディングデモ", sequence), mWipeHolder(wipeHolder), + mScreenCaptureExecutor(screenCaptureExecutor), mStateDeleteScene(stateDeleteScene), + mResourceLoader(resourceLoader), mGameDataHolder(gameDataHolder) {} + +HakoniwaStateDemoEnding::~HakoniwaStateDemoEnding() { + if (nn::oe::IsUserInactivityDetectionTimeExtended()) { + nn::oe::SetUserInactivityDetectionTimeExtended(false); + nn::oe::IsUserInactivityDetectionTimeExtended(); + } + + if (mCurrentScene) + delete mCurrentScene; + mCurrentScene = nullptr; +} + +void HakoniwaStateDemoEnding::init() { + initNerve(&NrvHakoniwaStateDemoEnding.LoadWorldResource, 2); + al::addNerveState(this, mStateDeleteScene, &NrvHakoniwaStateDemoEnding.EndEnding, + "シーン破棄[エンディング]"); + al::addNerveState(this, mStateDeleteScene, &NrvHakoniwaStateDemoEnding.End, + "シーン破棄[スタッフロール]"); +} + +void HakoniwaStateDemoEnding::appear() { + al::NerveStateBase::appear(); + nn::oe::SetUserInactivityDetectionTimeExtended(true); + + if (mResourceLoader->getLoadWorldId() == GameDataFunction::getWorldIndexMoon()) + al::setNerve(this, &NrvHakoniwaStateDemoEnding.LoadWorldResource); + else + al::setNerve(this, &NrvHakoniwaStateDemoEnding.LoadWorldResourceSecond); +} + +void HakoniwaStateDemoEnding::kill() { + nn::oe::SetUserInactivityDetectionTimeExtended(false); + al::NerveStateBase::kill(); +} + +void HakoniwaStateDemoEnding::exeLoadWorldResource() { + if (al::isFirstStep(this)) + mResourceLoader->requestLoadWorldHomeStageResource(GameDataFunction::getWorldIndexMoon(), + 1); + + if (mResourceLoader->isEndLoadWorldResource()) + al::setNerve(this, &Load); +} + +void HakoniwaStateDemoEnding::exeLoadWorldResourceSecond() { + if (al::isFirstStep(this)) + mResourceLoader->requestLoadWorldResource(GameDataFunction::getWorldIndexMoon()); + + if (mResourceLoader->isEndLoadWorldResource()) + al::setNerve(this, &NrvHakoniwaStateDemoEnding.LoadWorldResource); +} + +void HakoniwaStateDemoEnding::exeLoad() { + HakoniwaSequence** sequence; + + if (al::isFirstStep(this)) { + const char* stageName = "DemoEndingStage"; + al::createSceneHeap(stageName, true); + al::setCurrentCategoryName("シーン"); + + { + al::SceneHeapSetter heapSetter; + + EndingScene* scene = new EndingScene(mWipeHolder); + mCurrentScene = scene; + scene->setLoadEnd(true); + + sequence = getHostPtr(); + alAudioSystemFunction::resetDataDependedStage((*sequence)->getAudioDirector(), + stageName, 1); + al::setSceneAndUseInitThread(*sequence, mCurrentScene, cPriority, stageName, 1, + "Sequence=ProductSequence", nullptr); + } + } else { + sequence = getHostPtr(); + } + + if (al::tryEndSceneInitThread(*sequence)) { + al::setSequenceAudioKeeperToSceneSeDirector(*sequence, mCurrentScene); + mScreenCaptureExecutor->offDraw(); + mCurrentScene->appear(); + (*sequence)->setNextScene(mCurrentScene); + + if (!mWipeHolder->isOpenEnd()) + mWipeHolder->startOpen(-1); + + al::getSceneHeap()->adjust(); + al::setSequenceNameForActorPickTool(*sequence, mCurrentScene); + al::setNerve(this, &DemoEnding); + } +} + +void HakoniwaStateDemoEnding::exeDemoEnding() { + getHost()->updatePadSystem(); + + if (!mCurrentScene->isAlive()) { + mScreenCaptureExecutor->requestCapture(true, 0); + al::setNerve(this, &NrvHakoniwaStateDemoEnding.EndEnding); + } +} + +void HakoniwaStateDemoEnding::exeEndEnding() { + if (al::isFirstStep(this)) { + mStateDeleteScene->start(mCurrentScene, true, false, 0); + al::stopBgm(getHost(), "Ending", -1); + } + + if (al::updateNerveState(this)) { + mCurrentScene = nullptr; + if (!GameDataFunction::isGameClear(mGameDataHolder)) + mResourceLoader->tryDestroyWorldResource(); + al::setNerve(this, &LoadStaffRoll); + } +} + +void HakoniwaStateDemoEnding::exeLoadStaffRoll() { + HakoniwaSequence** sequence; + + if (al::isFirstStep(this)) { + const char* stageName = "StaffRollStage"; + al::createSceneHeap(stageName, true); + al::setCurrentCategoryName("シーン"); + + { + al::SceneHeapSetter heapSetter; + + mCurrentScene = new StaffRollScene(mWipeHolder); + + sequence = getHostPtr(); + alAudioSystemFunction::resetDataDependedStage((*sequence)->getAudioDirector(), + stageName, 1); + al::setSceneAndUseInitThread(*sequence, mCurrentScene, cPriority, stageName, 1, + "Sequence=ProductSequence", nullptr); + } + } else { + sequence = getHostPtr(); + } + + if (al::tryEndSceneInitThread(*sequence)) { + al::setSequenceAudioKeeperToSceneSeDirector(*sequence, mCurrentScene); + mScreenCaptureExecutor->offDraw(); + mCurrentScene->appear(); + (*sequence)->setNextScene(mCurrentScene); + al::getSceneHeap()->adjust(); + al::setSequenceNameForActorPickTool(*sequence, mCurrentScene); + + if (!GameDataFunction::isGameClear(mGameDataHolder)) { + mResourceLoader->tryDestroyWorldResource(); + mResourceLoader->requestLoadWorldHomeStageResource( + GameDataFunction::getWorldIndexPeach(), 2); + } + + if (!mWipeHolder->isOpenEnd()) + mWipeHolder->startOpen(-1); + + al::setNerve(this, &DemoStaffRoll); + } +} + +void HakoniwaStateDemoEnding::exeDemoStaffRoll() { + getHost()->updatePadSystem(); + + if (!mCurrentScene->isAlive()) { + mScreenCaptureExecutor->requestCapture(true, 0); + + if (!mWipeHolder->isClose()) + mWipeHolder->startClose("FadeBlack", -1); + + al::setNerve(this, &NrvHakoniwaStateDemoEnding.End); + } +} + +void HakoniwaStateDemoEnding::exeEnd() { + if (al::isFirstStep(this)) { + mStateDeleteScene->start(mCurrentScene, true, false, 0); + return; + } + + if (al::updateNerveState(this)) { + mCurrentScene = nullptr; + kill(); + } +} diff --git a/src/Sequence/HakoniwaStateDemoEnding.h b/src/Sequence/HakoniwaStateDemoEnding.h new file mode 100644 index 0000000000..0747d471d2 --- /dev/null +++ b/src/Sequence/HakoniwaStateDemoEnding.h @@ -0,0 +1,50 @@ +#pragma once + +#include + +#include "Library/Nerve/NerveStateBase.h" + +#include "System/GameDataHolderAccessor.h" + +class GameDataHolder; +class HakoniwaSequence; +class HakoniwaStateDeleteScene; +class WorldResourceLoader; + +namespace al { +class Scene; +class ScreenCaptureExecutor; +class WipeHolder; +} // namespace al + +class HakoniwaStateDemoEnding : public al::HostStateBase { +public: + HakoniwaStateDemoEnding(HakoniwaSequence* sequence, al::WipeHolder* wipeHolder, + al::ScreenCaptureExecutor* screenCaptureExecutor, + HakoniwaStateDeleteScene* stateDeleteScene, + WorldResourceLoader* resourceLoader, GameDataHolder* gameDataHolder); + ~HakoniwaStateDemoEnding() override; + + void init() override; + void appear() override; + void kill() override; + + void exeLoadWorldResource(); + void exeLoadWorldResourceSecond(); + void exeLoad(); + void exeDemoEnding(); + void exeEndEnding(); + void exeLoadStaffRoll(); + void exeDemoStaffRoll(); + void exeEnd(); + +private: + al::Scene* mCurrentScene = nullptr; + al::WipeHolder* mWipeHolder = nullptr; + al::ScreenCaptureExecutor* mScreenCaptureExecutor = nullptr; + HakoniwaStateDeleteScene* mStateDeleteScene = nullptr; + WorldResourceLoader* mResourceLoader = nullptr; + GameDataHolderAccessor mGameDataHolder; +}; + +static_assert(sizeof(HakoniwaStateDemoEnding) == 0x50, "HakoniwaStateDemoEnding size");