NSMBW-Decomp
A decompilation of New Super Mario Bros. Wii
Loading...
Searching...
No Matches
d_pausewindow.cpp
1#include <game/bases/d_pausewindow.hpp>
2#include <game/bases/d_game_com.hpp>
3#include <game/bases/d_scene.hpp>
4#include <game/bases/d_cursor_select.hpp>
5#include <game/bases/d_info.hpp>
6#include <game/bases/d_s_world_map_static.hpp>
7#include <game/bases/d_wm_lib.hpp>
8#include <game/snd/snd_audio_mgr.hpp>
12
13ACTOR_PROFILE(PAUSEWINDOW, Pausewindow_c, 0);
14
16STATE_DEFINE(Pausewindow_c, OpenAnimeEndWait);
17STATE_DEFINE(Pausewindow_c, ButtonChangeAnimeEndWait);
18STATE_DEFINE(Pausewindow_c, PauseDisp);
19STATE_DEFINE(Pausewindow_c, HitAnimeEndWait);
20STATE_DEFINE(Pausewindow_c, ClouseAnimeEndWait);
21
23
24Pausewindow_c::Pausewindow_c() :
25 mStateMgr(*this, StateID_InitWait),
26 mHasLoadedLayout(false)
27{
29}
30
31Pausewindow_c::~Pausewindow_c() {}
32
33
35 static const char *AnmNameTbl[ANIM_NAME_COUNT] = {
36 "pauseMenu_16_inWindow.brlan",
37 "pauseMenu_16_loopWindow.brlan",
38 "pauseMenu_16_outWindow.brlan",
39 "pauseMenu_16_onButton.brlan",
40 "pauseMenu_16_idleButton.brlan",
41 "pauseMenu_16_offButon.brlan",
42 "pauseMenu_16_hitButton.brlan"
43 };
44
45 static const char *GROUP_NAME_DT[ANIM_COUNT] = {
46 "A00_inWindow", "A00_inWindow", "A00_inWindow",
47 "B00_tuzukuButton", "B02_menuButton",
48 "B00_tuzukuButton", "B02_menuButton",
49 "B00_tuzukuButton", "B02_menuButton",
50 "B00_tuzukuButton", "B02_menuButton"
51 };
52
53 static const int ANIME_INDEX_TBL[ANIM_COUNT] = {
54 inWindow, loopWindow, outWindow,
55 onButton, onButton,
56 idleButton, idleButton,
57 offButon, offButon,
58 hitButton, hitButton
59 };
60
61 static const char *textBox[] = {
62 "T_tuzukeru_00", "T_tuzukeru_01",
63 "T_modoru_00", "T_modoru_01"
64 };
65 static const int msgIdTbl[ARRAY_SIZE(textBox)] = {
66 MSG_PAUSE_CONTINUE, MSG_PAUSE_CONTINUE,
67 MSG_PAUSE_EXIT, MSG_PAUSE_EXIT
68 };
69
70 static const char *textBox2[] = {
71 "T_world_00", "T_hyphen_00", "T_multiText_00"
72 };
73 static const int msgIdTbl2[ARRAY_SIZE(textBox2)] = {
74 MSG_WM_WORLD, MSG_WM_HYPHEN, MSG_WM_FREE_MODE
75 };
76
77 static const char *PPANE_NAME_DT[P_COUNT] = {
78 "P_SBBase_00",
79 "P_SBBase_02",
80 "P_shadowBlack",
81 "P_coin_00"
82 };
83
84 static const char *WPANE_NAME_DT[W_COUNT] = {
85 "W_N_pauseMenu_00"
86 };
87
88 static const char *T_PANE_NAME_TBL[T_COUNT] = {
89 "T_tuzukeru_00", "T_tuzukeru_01",
90 "T_modoru_00", "T_modoru_01",
91 "T_worldNum_00", "T_corseNum_00",
92 "T_corsePic_00",
93 "T_osusumeText_00"
94 };
95
96 static const char *NPANE_NAME_DT[N_COUNT] = {
97 "N_worldText_00",
98 "N_osusumeText_00",
99 "N_multiText_00"
100 };
101
102 if (mHasLoadedLayout) {
103 return SUCCEEDED;
104 }
105
106 if (!mLayout.ReadResource("pauseMenu/pauseMenu.arc", false)) {
107 return NOT_READY;
108 }
109
110 mLayout.build("pauseMenu_16.brlyt", nullptr);
111 mLayout.AnimeResRegister(AnmNameTbl, ANIM_NAME_COUNT);
112 mLayout.GroupRegister(GROUP_NAME_DT, ANIME_INDEX_TBL, ANIM_COUNT);
113 mLayout.TPaneNameRegister(textBox, msgIdTbl, BMG_CATEGORY_PAUSE_WINDOW, ARRAY_SIZE(textBox));
114 mLayout.TPaneNameRegister(textBox2, msgIdTbl2, BMG_CATEGORY_WORLD_MAP, ARRAY_SIZE(textBox2));
115 mLayout.PPaneRegister(PPANE_NAME_DT, mpPicturePanes, P_COUNT);
116 mLayout.WPaneRegister(WPANE_NAME_DT, mpWindowPanes, W_COUNT);
117 mLayout.TPaneRegister(T_PANE_NAME_TBL, mpTextBoxes, T_COUNT);
118 mLayout.NPaneRegister(NPANE_NAME_DT, mpNullPanes, N_COUNT);
119
120 mLayout.mDrawOrder = 141;
121 mIsActive = false;
122 mHasLoadedLayout = true;
123 mIsAnimating = false;
124 mColor = 0;
125 mToTitle = false;
126 mButtonHit = false;
127
128 if (
129 dGameCom::isNowCourseClear() ||
130 dScene_c::m_nowScene != fProfile::STAGE ||
131 dInfo_c::m_startGameInfo.mLevel1 == STAGE_CANNON
132 ) {
133 mpPicturePanes[P_shadowBlack]->setVisible(false);
134 } else {
135 mpPicturePanes[P_shadowBlack]->setVisible(true);
136 }
137 if (
138 dInfo_c::m_startGameInfo.mLevel1 == STAGE_ENEMY ||
139 dInfo_c::m_startGameInfo.mLevel1 == STAGE_ENEMY_2 ||
140 dInfo_c::m_startGameInfo.mLevel1 == STAGE_ENEMY_3
141 ) {
142 mpPicturePanes[P_shadowBlack]->setVisible(true);
143 }
145
146 mLayout.AllAnimeEndSetup();
147 return SUCCEEDED;
148}
149
152 mStateMgr.executeState();
153 mLayout.AnimePlay();
154 mLayout.calc();
155 }
156 return SUCCEEDED;
157}
158
161 mLayout.entry();
162 }
163 return SUCCEEDED;
164}
165
167 if (!mLayout.doDelete()) {
168 return NOT_READY;
169 }
170 m_instance = nullptr;
171 return SUCCEEDED;
172}
173
175 MsgRes_c *msgRes = dMessage_c::getMesRes();
176 dInfo_c *info = dInfo_c::getInstance();
177 u8 world = info->getWorld();
178 u8 course = info->getCourse();
179 if (info->getWorld() > WORLD_USED_COUNT) {
180 world = WORLD_USED_COUNT;
181 }
182 info->mDisplayCourseWorld = world + 1;
183 mpTextBoxes[T_worldNum_00]->setMessage(msgRes, BMG_CATEGORY_WORLD_MAP, MSG_WM_WORLD_NUM, 0);
184 int msgID;
185 switch (course) {
186 case STAGE_GHOST_HOUSE:
187 msgID = MSG_WM_ICON_GHOST_HOUSE;
188 break;
189 case STAGE_TOWER:
190 case STAGE_TOWER_2:
191 msgID = MSG_WM_ICON_TOWER;
192 break;
193 case STAGE_CASTLE:
194 case STAGE_CASTLE_2:
195 if (world != LAST_WORLD) {
196 msgID = MSG_WM_ICON_CASTLE;
197 } else {
198 msgID = MSG_WM_ICON_LAST_WORLD_CASTLE;
199 }
200 break;
201 case STAGE_KINOKO_HOUSE:
202 case STAGE_KINOKO_HOUSE_2:
203 case STAGE_KINOKO_HOUSE_3:
204 case STAGE_KINOKO_HOUSE_4:
205 case STAGE_KINOKO_HOUSE_5:
206 case STAGE_KINOKO_HOUSE_6:
207 case STAGE_KINOKO_HOUSE_7:
208 if (dScWMap_c::IsCourseType(world, course, dScWMap_c::COURSE_TYPE_KINOKO_HOUSE_1UP)) {
209 msgID = MSG_WM_ICON_KINOKO_HOUSE_1UP;
210 } else if (dScWMap_c::IsCourseType(world, course, dScWMap_c::COURSE_TYPE_KINOKO_HOUSE_STAR)) {
211 msgID = MSG_WM_ICON_KINOKO_HOUSE_STAR;
212 } else {
213 msgID = MSG_WM_ICON_KINOKO_HOUSE;
214 }
215 break;
217 if (dWmLib::isStartPointKinokoHouseStar()) {
218 msgID = MSG_WM_ICON_KINOKO_HOUSE_STAR;
219 } else if (dWmLib::isStartPointKinokoHouseRed()) {
220 msgID = MSG_WM_ICON_KINOKO_HOUSE;
221 } else {
222 msgID = MSG_WM_ICON_KINOKO_HOUSE_1UP;
223 }
224 break;
225 case STAGE_ENEMY:
226 case STAGE_ENEMY_2:
227 case STAGE_ENEMY_3:
228 msgID = MSG_WM_ICON_RESCUE;
229 break;
230 case STAGE_CANNON:
231 msgID = MSG_WM_ICON_CANNON;
232 break;
233 case STAGE_PEACH_CASTLE:
234 msgID = MSG_WM_ICON_PEACH_CASTLE;
235 break;
236 case STAGE_UNK37:
237 msgID = MSG_WM_ICON_ANCHOR;
238 break;
239 case STAGE_DOOMSHIP:
240 if (dWmLib::isKoopaShipAnchor()) {
241 msgID = MSG_WM_ICON_ANCHOR;
242 } else {
243 msgID = MSG_WM_ICON_AIRSHIP;
244 }
245 break;
246 default:
247 info->mDisplayCourseNum = course + 1;
248 mpTextBoxes[T_corseNum_00]->setVisible(true);
249 mpTextBoxes[T_corseNum_00]->setMessage(msgRes, BMG_CATEGORY_WORLD_MAP, MSG_WM_COURSE_NUM, 0);
250 mpTextBoxes[T_corsePic_00]->setVisible(false);
251 return;
252 }
253 mpTextBoxes[T_corseNum_00]->setVisible(false);
254 mpTextBoxes[T_corsePic_00]->setVisible(true);
255 mpTextBoxes[T_corsePic_00]->setMessage(msgRes, BMG_CATEGORY_WORLD_MAP, msgID, 0);
256}
257
259 mpNullPanes[N_worldText_00]->setVisible(true);
260 mpNullPanes[N_osusumeText_00]->setVisible(false);
261 mpNullPanes[N_multiText_00]->setVisible(false);
262 MsgRes_c *msgRes = dMessage_c::getMesRes();
263 dInfo_c *info = dInfo_c::m_instance;
264 int pageIndex = info->mCourseSelectIndexInPage;
265 if (pageIndex >= 10) {
266 pageIndex -= 10;
267 }
268 if (
269 dInfo_c::mGameFlag & dInfo_c::GAME_FLAG_IS_COIN_COURSE &&
270 info->mCourseSelectPageNum == 0 &&
271 pageIndex < 5
272 ) {
273 mpTextBoxes[T_corseNum_00]->setVisible(true);
274 mpTextBoxes[T_corsePic_00]->setVisible(false);
275 // [Bug: This should also do the following so that the world number isn't shown too:]
276 // mpTextBoxes[T_worldNum_00]->setVisible(false);
277 mpPicturePanes[P_coin_00]->setVisible(true);
278 info->mDisplayCourseNum = pageIndex + 1;
279 mpTextBoxes[T_corseNum_00]->setMessage(msgRes, BMG_CATEGORY_WORLD_MAP, MSG_WM_COURSE_NUM, 0);
280 } else {
281 mpPicturePanes[P_coin_00]->setVisible(false);
283 }
284}
285
287 static const int PANE_IDX_TBL[] = {
288 P_SBBase_00,
289 P_SBBase_02
290 };
291 dGameCom::SelectCursorSetup(mpPicturePanes[PANE_IDX_TBL[mNextButton]], 0, false);
292}
293
294void Pausewindow_c::initializeState_InitWait() {}
295void Pausewindow_c::executeState_InitWait() {
296 mNextButton = 0;
297 mIsActive = true;
298 dGameCom::WindowPaneColorSet(mpWindowPanes[W_N_pauseMenu_00], mColor);
299 if (mToTitle) {
300 MsgRes_c *msgRes = dMessage_c::getMesRes();
301 mpTextBoxes[T_tuzukeru_00]->setMessage(msgRes, BMG_CATEGORY_MAIN_MENU, MSG_MAIN_MENU_CONTINUE, 0);
302 mpTextBoxes[T_tuzukeru_01]->setMessage(msgRes, BMG_CATEGORY_MAIN_MENU, MSG_MAIN_MENU_CONTINUE, 0);
303 mpTextBoxes[T_modoru_00]->setMessage(msgRes, BMG_CATEGORY_MAIN_MENU, MSG_MAIN_MENU_TITLE_SCREEN, 0);
304 mpTextBoxes[T_modoru_01]->setMessage(msgRes, BMG_CATEGORY_MAIN_MENU, MSG_MAIN_MENU_TITLE_SCREEN, 0);
305 }
307}
308void Pausewindow_c::finalizeState_InitWait() {}
309
310void Pausewindow_c::initializeState_OpenAnimeEndWait() {
311 mIsAnimating = true;
312 mLayout.AllAnimeEndSetup();
313 mLayout.ReverseAnimeStartSetup(ANIM_ON_TUZUKU, false);
314 mLayout.ReverseAnimeStartSetup(ANIM_ON_MENU, false);
315 mLayout.AnimeStartSetup(ANIM_IN_WINDOW, false);
316}
317void Pausewindow_c::executeState_OpenAnimeEndWait() {
318 if (!mLayout.isAllAnime()) {
320 }
321}
322void Pausewindow_c::finalizeState_OpenAnimeEndWait() {
323 mIsAnimating = false;
324 mClose = false;
325 mButtonHit = false;
326 mActiveButton = -1;
327}
328
329void Pausewindow_c::initializeState_ButtonChangeAnimeEndWait() {
330 mLayout.AllAnimeEndSetup();
331 mIsAnimating = true;
332 if (mActiveButton >= 0) {
333 mLayout.AnimeStartSetup(ANIM_OFF_TUZUKU + mActiveButton, false);
334 }
336 mLayout.AnimeStartSetup(ANIM_ON_TUZUKU + mNextButton, false);
337}
338void Pausewindow_c::executeState_ButtonChangeAnimeEndWait() {
339 if (!mLayout.isAnime(-1)) {
340 mStateMgr.changeState(StateID_PauseDisp);
341 }
342}
343void Pausewindow_c::finalizeState_ButtonChangeAnimeEndWait() {
344 mIsAnimating = false;
345}
346
347void Pausewindow_c::initializeState_PauseDisp() {
349}
350void Pausewindow_c::executeState_PauseDisp() {
351 if (mClose) {
353 } else if (mButtonHit) {
355 } else {
356 if (mActiveButton != mNextButton) {
357 SndAudioMgr::sInstance->startSystemSe(SE_SYS_CURSOR, 1);
359 }
360 }
361}
362void Pausewindow_c::finalizeState_PauseDisp() {
363 dSelectCursor_c::m_instance->Cancel(0);
364}
365
366void Pausewindow_c::initializeState_HitAnimeEndWait() {
367 mIsAnimating = true;
368 mLayout.AnimeStartSetup(ANIM_HIT_TUZUKU + mNextButton, false);
369}
370void Pausewindow_c::executeState_HitAnimeEndWait() {
371 if (!mLayout.isAnime(-1)) {
373 }
374}
375void Pausewindow_c::finalizeState_HitAnimeEndWait() {
376 mIsAnimating = false;
377}
378
379void Pausewindow_c::initializeState_ClouseAnimeEndWait() {
380 mIsAnimating = true;
381 mLayout.AnimeStartSetup(ANIM_OUT_WINDOW, false);
382}
383void Pausewindow_c::executeState_ClouseAnimeEndWait() {
384 if (!mLayout.isAnime(-1)) {
385 mIsActive = false;
386 mStateMgr.changeState(StateID_InitWait);
387 }
388}
389void Pausewindow_c::finalizeState_ClouseAnimeEndWait() {
390 mIsAnimating = false;
391}
Display a menu that appears when the game is paused inside a course.
nw4r::lyt::Pane * mpNullPanes[N_COUNT]
The null panes of the view.
virtual int create()
do method for the create operation.
static sFStateID_c< Pausewindow_c > StateID_ButtonChangeAnimeEndWait
Waiting for the button change animation to finish.
virtual int draw()
do method for the draw operation.
static Pausewindow_c * m_instance
The static instance of the pause window.
int mColor
The color of the window. Use a value from 0-3 (one per player).
static sFStateID_c< Pausewindow_c > StateID_ClouseAnimeEndWait
Waiting for the close animation to finish. Goes back to InitWait.
sFStateMgr_c< Pausewindow_c, sStateMethodUsr_FI_c > mStateMgr
The state manager for the window.
static sFStateID_c< Pausewindow_c > StateID_HitAnimeEndWait
Waiting for the button hit animation to finish and goes to ClouseAnimeEndWait after.
void setWorldCourseWrite()
Sets the world number and course number / icon.
bool mButtonHit
Whether one of the buttons was hit.
void SelectCursorSetup()
Sets up the cursor for the buttons.
nw4r::lyt::Window * mpWindowPanes[W_COUNT]
The window panes of the view.
bool mHasLoadedLayout
Whether the layout has been loaded.
int mNextButton
The button to be activated next (when the cursor moves).
virtual int doDelete()
do method for the delete operation.
static sFStateID_c< Pausewindow_c > StateID_OpenAnimeEndWait
Waiting for the window to finish the opening animation.
virtual int execute()
do method for the execute operation.
bool mClose
Whether the window was closed via the back button.
bool mIsActive
Whether the window is currently open.
void TitleDispChkWrite()
Sets the visibility of the panes based on the game mode.
static sFStateID_c< Pausewindow_c > StateID_InitWait
Initial state. Switches to OpenAnimeEndWait immediately.
LytTextBox_c * mpTextBoxes[T_COUNT]
The textboxes of the view.
bool mToTitle
Whether to show "Title Screen" instead of "Exit". [This seems to never be set in-game].
nw4r::lyt::Picture * mpPicturePanes[P_COUNT]
The picture panes of the view.
LytBase_c mLayout
The layout for the window.
int mActiveButton
The button currently active.
bool mIsAnimating
Whether an animation is currently playing.
static sFStateID_c< Pausewindow_c > StateID_PauseDisp
Showing the pause window.
static unsigned int mGameFlag
See GAME_FLAG_e.
Definition d_info.hpp:68
static ProfileName m_nowScene
The profile name of the current scene.
Definition d_scene.hpp:56
@ NOT_READY
The step could not completed at this time.
Definition f_base.hpp:39
@ SUCCEEDED
The step was completed successfully.
Definition f_base.hpp:40
@ STAGE_START_KINOKO_HOUSE
The toad house on the starting node of each world.
@ STAGE_CASTLE_2
@ STAGE_TOWER_2
#define ACTOR_PROFILE(profName, className, properties)
Creates an actor profile, using the profile number as the execute and draw order value.
Definition f_profile.hpp:29
#define STATE_DEFINE(class, name)
Defines a state.
Definition s_State.hpp:32