1#include "Scene/TitleMenuScene.h"
2
3#include <common/aglDrawContext.h>
4#include <common/aglRenderBuffer.h>
5#include <gfx/seadFrameBuffer.h>
6#include <gfx/seadViewport.h>
7
8#include "Library/Area/AreaObjDirector.h"
9#include "Library/Audio/AudioDirectorInitInfo.h"
10#include "Library/Audio/System/AudioKeeperFunction.h"
11#include "Library/Base/StringUtil.h"
12#include "Library/Camera/CameraUtil.h"
13#include "Library/Controller/InputFunction.h"
14#include "Library/Controller/PadRumbleDirector.h"
15#include "Library/Draw/ChromakeyDrawer.h"
16#include "Library/Draw/GraphicsFunction.h"
17#include "Library/Draw/GraphicsSystemInfo.h"
18#include "Library/Draw/ViewRenderer.h"
19#include "Library/Framework/GameFrameworkNx.h"
20#include "Library/Layout/LayoutActionFunction.h"
21#include "Library/Layout/LayoutActorUtil.h"
22#include "Library/Layout/LayoutInitInfo.h"
23#include "Library/Layout/LayoutUtil.h"
24#include "Library/LiveActor/ActorActionFunction.h"
25#include "Library/LiveActor/ActorInitInfo.h"
26#include "Library/LiveActor/LiveActorKit.h"
27#include "Library/Math/MathUtil.h"
28#include "Library/Nerve/NerveSetupUtil.h"
29#include "Library/Nerve/NerveUtil.h"
30#include "Library/Placement/PlacementInfo.h"
31#include "Library/Play/Layout/SimpleLayoutAppearWaitEnd.h"
32#include "Library/Play/Layout/WindowConfirm.h"
33#include "Library/Play/Layout/WipeSimple.h"
34#include "Library/Player/PlayerUtil.h"
35#include "Library/Projection/Projection.h"
36#include "Library/Scene/Scene.h"
37#include "Library/Scene/SceneObjUtil.h"
38#include "Library/Scene/SceneUtil.h"
39#include "Library/Screen/ScreenFunction.h"
40#include "Library/Se/SeFunction.h"
41
42#include "Demo/ProjectDemoDirector.h"
43#include "Layout/BootLayout.h"
44#include "Scene/ProjectActorFactory.h"
45#include "Scene/ProjectAreaFactory.h"
46#include "Scene/ProjectCameraPoserFactory.h"
47#include "Scene/SceneObjFactory.h"
48#include "Scene/StageScene.h"
49#include "Scene/StageSceneStatePauseMenu.h"
50#include "System/Application.h"
51#include "System/GameDataFunction.h"
52#include "System/GameDataHolder.h"
53#include "System/GameDataHolderAccessor.h"
54#include "Util/SpecialBuildUtil.h"
55#include "Util/StageLayoutFunction.h"
56
57namespace {
58NERVE_IMPL(TitleMenuScene, Appear);
59NERVE_IMPL(TitleMenuScene, LoadAppear);
60NERVE_IMPL(TitleMenuScene, Menu);
61NERVE_IMPL(TitleMenuScene, LoadWait);
62NERVE_IMPL(TitleMenuScene, Wipe);
63
64NERVES_MAKE_NOSTRUCT(TitleMenuScene, LoadWait);
65NERVES_MAKE_STRUCT(TitleMenuScene, Appear, LoadAppear, Menu, Wipe);
66} // namespace
67
68TitleMenuScene::TitleMenuScene() : al::Scene("TitleMenuScene") {}
69
70TitleMenuScene::~TitleMenuScene() {
71 Application::instance()->getGameFramework()->enableClearRenderBuffer();
72 if (mChromakeyDrawer)
73 mChromakeyDrawer->finalize();
74}
75
76void TitleMenuScene::init(const al::SceneInitInfo& info) {
77 initDrawSystemInfo(initInfo: info);
78 initAndLoadStageResource(stageName: "SandWorldHomeStage", scenarioNo: 1);
79 al::SceneObjHolder* sceneObjHolder = SceneObjFactory::createSceneObjHolder();
80 initSceneObjHolder(sceneObjHolder);
81
82 al::setSceneObj(user: this, GameDataFunction::getGameDataHolder(holder: info.gameDataHolder),
83 sceneObjId: SceneObjID_GameDataHolder);
84
85 initSceneStopCtrl();
86
87 al::GraphicsInitArg graphicsInitArg(al::getSceneDrawContext(scene: this),
88 al::getSceneFrameBufferConsole(scene: this));
89 graphicsInitArg._3c = true;
90 graphicsInitArg._10 = 1 << graphicsInitArg.atmosScatterViewNum;
91 graphicsInitArg._6 = true;
92
93 initLiveActorKitWithGraphics(graphicsInitArg, initInfo: info, maxActors: 1024, maxPlayers: 1, maxCameras: 1);
94 al::initGraphicsSystemInfo(scene: this, name: "SandWorldHomeStage", index: 1);
95
96 getLiveActorKit()->getGraphicsSystemInfo()->set_2f4(2);
97
98 getLiveActorKit()->initHitSensorDirector();
99
100 getLiveActorKit()->setDemoDirector(new ProjectDemoDirector(
101 getLiveActorKit()->getPlayerHolder(), getLiveActorKit()->getGraphicsSystemInfo()));
102
103 al::AudioDirectorInitInfo audioDirectorInitInfo;
104 al::initAudioDirector3D(scene: this, sceneInfo: info, audioDirectorInfo&: audioDirectorInitInfo);
105
106 al::initSceneAudioKeeper(scene: this, sceneInfo: info, name: nullptr);
107 alAudioSystemFunction::disableAudioMaximizer(info.gameSysInfo);
108
109 ProjectCameraPoserFactory* projectCameraPoserFactory = new ProjectCameraPoserFactory();
110 al::initCameraDirectorWithoutStageResource(scene: this, cameraPoserFactory: projectCameraPoserFactory);
111
112 al::setCameraAspect(scene: this, aspectA: al::getSceneFrameBufferMainAspect(scene: this), aspectB: -1.0f);
113
114 al::AreaObjDirector* areaObjDirector = getLiveActorKit()->getAreaObjDirector();
115 ProjectAreaFactory* projectAreaFactory = new ProjectAreaFactory();
116 areaObjDirector->init(factory: projectAreaFactory);
117
118 al::initPadRumble(scene: this, sceneInfo: info);
119
120 initLayoutKit(initInfo: info);
121 al::LayoutInitInfo layoutInitInfo;
122 al::initLayoutInitInfo(layoutInfo: &layoutInitInfo, scene: this, sceneInfo: info);
123
124 al::PlacementInfo placementInfo;
125 al::ActorInitInfo actorInitInfo;
126
127 ProjectActorFactory* projectActorFactory = new ProjectActorFactory();
128
129 al::initActorInitInfo(actorInitInfo: &actorInitInfo, scene: this, placementInfo: &placementInfo, layoutInfo: &layoutInitInfo,
130 actorFactory: projectActorFactory, sceneMsgCtrl: nullptr, gameDataHolderBase: info.gameDataHolder);
131
132 initNerve(nerve: &NrvTitleMenuScene.Appear, stateCount: 1);
133
134 if (rs::isModeE3LiveRom())
135 al::setNerve(user: this, nerve: &NrvTitleMenuScene.LoadAppear);
136
137 mBootLayout = new BootLayout(layoutInitInfo);
138
139 if (!rs::isModeE3LiveRom())
140 mBootLayout->startWipe();
141
142 mFadeBlack = new al::WipeSimple("フェード", "FadeBlack", layoutInitInfo, nullptr);
143 mWindowConfirm = new al::WindowConfirm(layoutInitInfo, "WindowConfirm", "WindowConfirm");
144 mLayoutMenu =
145 new al::SimpleLayoutAppearWaitEnd("ポーズメニュー", "Menu", layoutInitInfo, nullptr, false);
146 mLayoutMenu->kill();
147 mLayoutContinueLoading = new al::SimpleLayoutAppearWaitEnd("ロード", "ContinueLoading",
148 layoutInitInfo, nullptr, false);
149 mLayoutContinueLoading->kill();
150 mLayoutParBG = new al::SimpleLayoutAppearWaitEnd(mLayoutContinueLoading, "ロード[BG]", "ParBG",
151 layoutInitInfo, nullptr);
152
153 mStatePauseMenu = new StageSceneStatePauseMenu(
154 "ポーズメニュー", this, mLayoutMenu, (GameDataHolder*)info.gameDataHolder, info,
155 actorInitInfo, layoutInitInfo, mWindowConfirm, nullptr, true, nullptr);
156
157 al::initNerveState(user: this, state: mStatePauseMenu, nerve: &NrvTitleMenuScene.Menu, hostName: "ポーズメニュー");
158
159 alPlayerFunction::registerPlayer(
160 mStatePauseMenu->getMarioActor(),
161 al::createPadRumbleKeeper(mStatePauseMenu->getMarioActor(), al::getMainControllerPort()));
162
163 mChromakeyDrawer = new al::ChromakeyDrawer(getLiveActorKit()->getGraphicsSystemInfo(),
164 al::getSceneExecuteDirector(scene: this),
165 getLiveActorKit()->getEffectSystem());
166
167 endInit(initInfo: actorInitInfo);
168}
169
170void TitleMenuScene::appear() {
171 al::Scene::appear();
172 Application::instance()->getGameFramework()->disableClearRenderBuffer();
173}
174
175void TitleMenuScene::control() {}
176
177void TitleMenuScene::drawMain() const {
178 agl::DrawContext* drawContext = al::getSceneDrawContext(scene: this);
179 agl::RenderBuffer* frameBuffer = al::getSceneFrameBufferMain(scene: this);
180
181 sead::Viewport viewport(*frameBuffer);
182 viewport.apply(drawContext, buffer: *frameBuffer);
183
184 const sead::LookAtCamera& lookAtCamera = al::getLookAtCamera(user: this, viewIdx: 0);
185 const al::Projection& projection = al::getProjection(user: this, viewIdx: 0);
186 if (al::isLessEqualStep(user: this, step: 1))
187 getLiveActorKit()->getGraphicsSystemInfo()->getViewRenderer()->drawView(
188 0, getDrawSystemInfo(), projection, lookAtCamera, frameBuffer, viewport, true, false,
189 false);
190
191 viewport.apply(drawContext, buffer: *frameBuffer);
192 frameBuffer->bind(draw_context: drawContext);
193 frameBuffer->clear(draw_context: drawContext, clr_flag: 3, color: sead::Color4f::cBlack, depth: al::getDepthClearValue(), stencil: 0);
194
195 al::drawKit(scene: this, name: "2Dバック(メイン画面)");
196 mChromakeyDrawer->setPhysicalArea(frameBuffer->getPhysicalArea().getMax() -
197 frameBuffer->getPhysicalArea().getMin());
198 mChromakeyDrawer->drawChromakey(drawContext, projection, lookAtCamera, frameBuffer, viewport,
199 "3D(クロマキーキャラクター)",
200 "Zプリパス[NPCクロマキー]", nullptr);
201
202 al::setRenderBuffer(getLayoutKit(), frameBuffer);
203
204 sead::Viewport layoutViewport(0.0f, 0.0f, al::getLayoutDisplayWidth(),
205 al::getLayoutDisplayHeight());
206 layoutViewport.apply(drawContext, buffer: *frameBuffer);
207 frameBuffer->bind(draw_context: drawContext);
208
209 al::drawKit(scene: this, name: "2Dベース(メイン画面)");
210 al::drawKit(scene: this, name: "2Dオーバー(メイン画面)");
211}
212
213bool TitleMenuScene::isEnableKill() const {
214 return al::isNerve(user: this, nerve: &LoadWait) && al::isGreaterEqualStep(user: this, step: 140) &&
215 mLoadCompleteCounter > 15;
216}
217
218bool TitleMenuScene::isChangeLanguage() const {
219 return mStatePauseMenu->isChangeLanguage();
220}
221
222const char* TitleMenuScene::getLanguage() const {
223 return mStatePauseMenu->getLanguage();
224}
225
226bool TitleMenuScene::isNewGame() const {
227 if (mStatePauseMenu->isLoadData() &&
228 GameDataFunction::isNewSaveDataByFileId(mLayoutMenu, fileId: mStatePauseMenu->getSelectedFileId()))
229 return true;
230 else
231 return mStatePauseMenu->isNewGame();
232}
233
234void TitleMenuScene::startLoadDirect(bool isGameLoad) {
235 setScenario();
236 mBootLayout->kill();
237 mLayoutContinueLoading->startWait();
238
239 if (isGameLoad)
240 al::startAction(layout: mLayoutContinueLoading, actionName: "GameLoad", paneName: "Type");
241 else
242 al::startAction(layout: mLayoutContinueLoading, actionName: "TitleLoad", paneName: "Type");
243
244 al::startAction(layout: mLayoutContinueLoading, actionName: "Loop", paneName: "Loop");
245 mLayoutParBG->startWait();
246 al::setNerve(user: this, nerve: &LoadWait);
247}
248
249void TitleMenuScene::setScenario() {
250 al::StringTmp<256> scenarioLabel;
251 al::StringTmp<256> stageLabel;
252 bool isNextScenario = false;
253
254 if (rs::tryGetMapMainScenarioLabel(&scenarioLabel, &stageLabel, &isNextScenario, this)) {
255 if (isNextScenario) {
256 if (rs::trySetPaneStageMessageIfExist(mLayoutContinueLoading, "TxtScenario",
257 scenarioLabel.cstr(), stageLabel.cstr()))
258 return;
259 } else {
260 if (rs::trySetPaneSystemMessageIfExist(mLayoutContinueLoading, "TxtScenario",
261 stageLabel.cstr(), scenarioLabel.cstr()))
262 return;
263 }
264 }
265
266 al::hidePane(mLayoutContinueLoading, "TxtGoal");
267 al::hidePane(mLayoutContinueLoading, "TxtScenario");
268}
269
270void TitleMenuScene::setLoadPercent(f32 percent) {
271 if (!mIsCancelLoadResource)
272 mLoadPercent = percent;
273}
274
275bool TitleMenuScene::isCancelLoadWorldResource() const {
276 return mIsCancelLoadResource;
277}
278
279void TitleMenuScene::startLoadWorldResource() {
280 mIsCancelLoadResource = false;
281 mLoadPercent = 0.0f;
282 mLoadPercentBuffered = 0.0f;
283}
284
285void TitleMenuScene::exeAppear() {
286 if (al::isFirstStep(user: this)) {
287 al::startSe(mBootLayout, "TitleCall");
288 mStatePauseMenu->startPauseCamera();
289 }
290
291 if (al::isStep(user: this, step: 2)) {
292 mLayoutMenu->startWait();
293 al::startAction(layout: mLayoutMenu, actionName: "Boot", paneName: "Boot");
294 mStatePauseMenu->setAfterTitle();
295 }
296
297 if (!rs::isModeE3LiveRom() && al::isStep(user: this, step: 150)) {
298 mStatePauseMenu->appearMarioModel();
299 mStatePauseMenu->startActionMario("PauseMenuStart");
300 }
301
302 al::updateKitListPrev(scene: this);
303 al::updateKitList(scene: this, name: "カメラ");
304 rs::requestGraphicsPresetAndCubeMapPause(this);
305 al::updateKitList(scene: this, name: "デモ");
306 al::updateKitList(scene: this, name: "2D(ポーズ無視)");
307 al::updateKitListPost(scene: this);
308 al::updateKitListPostOnNerveEnd(scene: this);
309
310 if (al::isGreaterEqualStep(user: this, step: 3) && al::isActionEnd(layout: mLayoutMenu, paneName: "Boot") &&
311 al::isActionEnd(actor: mStatePauseMenu->getMarioActor()))
312 al::setNerve(user: this, nerve: &NrvTitleMenuScene.Menu);
313}
314
315void TitleMenuScene::exeMenu() {
316 if (rs::isModeE3LiveRom()) {
317 al::setNerve(user: this, nerve: &NrvTitleMenuScene.LoadAppear);
318 return;
319 }
320
321 if (al::isFirstStep(user: this)) {
322 mStatePauseMenu->startActionMario("PauseMenuContinue");
323 mStatePauseMenu->startAfterTitle();
324 }
325
326 if (al::updateNerveState(user: this)) {
327 setScenario();
328 mLayoutContinueLoading->appear();
329 al::startAction(layout: mLayoutContinueLoading, actionName: "Loop", paneName: "Loop");
330 mLayoutParBG->startWait();
331
332 al::setActionFrame(layout: mLayoutParBG, frame: mBootLayout->getBgFrame(), paneName: nullptr);
333
334 al::startAction(layout: mLayoutContinueLoading, actionName: "TitleLoad", paneName: "Type");
335 al::updateKitListPostOnNerveEnd(scene: this);
336
337 al::setNerve(user: this, nerve: &NrvTitleMenuScene.LoadAppear);
338 return;
339 }
340
341 if (mStatePauseMenu->isModeSelectEnd() || mStatePauseMenu->isLoadData()) {
342 mStatePauseMenu->kill();
343 al::updateKitListPostOnNerveEnd(scene: this);
344 al::setNerve(user: this, nerve: &NrvTitleMenuScene.Wipe);
345 return;
346 }
347
348 al::updateKitListPostOnNerveEnd(scene: this);
349}
350
351void TitleMenuScene::exeWipe() {
352 if (al::isFirstStep(user: this))
353 mFadeBlack->startClose(frames: -1);
354
355 al::updateKit(scene: this);
356 al::updateGraphicsPrev(scene: this);
357
358 if (mFadeBlack->isCloseEnd()) {
359 mStatePauseMenu->killAllOptionLayout();
360 mLayoutMenu->kill();
361 mFadeBlack->startOpen(frames: -1);
362 mWindowConfirm->kill();
363
364 if (mStatePauseMenu->isLoadData()) {
365 mIsCancelLoadResource = true;
366 mLoadPercent = 0.0f;
367 mLoadPercentBuffered = 0.0f;
368 GameDataHolderAccessor(this)->receiveSetPlayingFileIdMsg();
369
370 s32 fileId = GameDataHolderAccessor(this)->getPlayingFileId();
371 GameDataHolderAccessor(this)->setPlayingFileId(fileId);
372
373 GameDataHolderAccessor(this)->setRequireSave();
374 }
375
376 setScenario();
377 mLayoutContinueLoading->startWait();
378 mLayoutParBG->startWait();
379 al::setActionFrame(layout: mLayoutParBG, frame: mBootLayout->getBgFrame(), paneName: nullptr);
380 al::startAction(layout: mLayoutContinueLoading, actionName: "Loop", paneName: "Loop");
381
382 al::setNerve(user: this, nerve: &LoadWait);
383 }
384}
385
386void TitleMenuScene::exeLoadAppear() {
387 al::updateKit(scene: this);
388 al::updateGraphicsPrev(scene: this);
389 if (al::isFirstStep(user: this))
390 al::setActionFrame(layout: mLayoutParBG, frame: mBootLayout->getBgFrame(), paneName: nullptr);
391 if (mLayoutContinueLoading->isWait())
392 al::setNerve(user: this, nerve: &LoadWait);
393}
394
395void TitleMenuScene::exeLoadWait() {
396 if (al::isFirstStep(user: this)) {
397 if (GameDataFunction::isPayShineAllInAllWorld(accessor: this))
398 al::startAction(layout: mLayoutContinueLoading, actionName: "HomeComplete", paneName: "HomeType");
399 else if (GameDataFunction::isGameClear(accessor: this))
400 al::startAction(layout: mLayoutContinueLoading, actionName: "HomeClear", paneName: "HomeType");
401 else
402 al::startAction(layout: mLayoutContinueLoading, actionName: "HomeNormal", paneName: "HomeType");
403 }
404
405 f32 percent;
406 if (al::isGreaterEqualStep(user: this, step: 140))
407 percent = mLoadPercent;
408 else
409 percent = al::lerpValue(a: 0.0f, b: mLoadPercent, t: al::calcNerveRate(user: this, max: 140));
410
411 mLoadPercentBuffered = percent;
412
413 if (percent > 100.0f)
414 ++mLoadCompleteCounter;
415
416 al::startFreezeAction(layout: mLayoutContinueLoading, actionName: "ProgressBar",
417 frame: sead::Mathf::clampMax(val: percent, max_: 100.0f), paneName: "ProgressBar");
418 al::updateKit(scene: this);
419 al::updateGraphicsPrev(scene: this);
420}
421