diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6f42c3d0..f5f5296e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -65,7 +65,7 @@ jobs: run: python configure.py && ninja - name: Run progress script - run: python progress.py --verify-obj --verify-bin --progress-summary + run: python progress.py --verify-bin --progress-summary - name: Run DTK and objdiff to generate progress file for decomp.dev run: | diff --git a/include/constants/game_constants.h b/include/constants/game_constants.h index c715c3fb..515447ab 100644 --- a/include/constants/game_constants.h +++ b/include/constants/game_constants.h @@ -21,6 +21,8 @@ #define MAX_MAP_ACTOR_COUNT 1000 ///< The maximum number of map actors that can exist simultaneously. +#define MAX_SCORE 99999950 ///< The maximum score that can be achieved. + #define MAX_STOCK_ITEM 99 ///< The maximum inventory amount per item. #define MAX_EXTRA_MODE_SCORE 1000000 ///< The maximum possible score in Free Mode and Coin Battle. diff --git a/include/game/bases/d_2d/multi.hpp b/include/game/bases/d_2d/multi.hpp index ac3aac37..5424020d 100644 --- a/include/game/bases/d_2d/multi.hpp +++ b/include/game/bases/d_2d/multi.hpp @@ -9,6 +9,18 @@ namespace d2d { /// @brief Stores clipping settings for a layout. /// @unofficial struct ScissorMask { + ScissorMask() {} + ScissorMask(const mVec2_c &pos, const mVec2_c &size) : mPos(pos), mSize(size) { + mEnabled = true; + } + void setPos(const mVec2_c &pos) { mPos = pos; } + void setSize(const mVec2_c &size) { mSize = size; } + void set(const mVec2_c &pos, const mVec2_c &size) { + mPos = pos; + mSize = size; + } + void enable() { mEnabled = true; } + ScissorMask &operator=(const ScissorMask &other) { mPos = other.mPos; mSize = other.mSize; @@ -16,8 +28,8 @@ struct ScissorMask { return *this; } - nw4r::math::VEC2 mPos; - nw4r::math::VEC2 mSize; + mVec2_c mPos; + mVec2_c mSize; bool mEnabled; }; @@ -44,7 +56,7 @@ class Multi_c : public m2d::Base_c { nw4r::lyt::Picture *findPictureByName(const char *name); ///< Finds a picture pane by name. nw4r::lyt::Window *findWindowByName(const char *name); ///< Finds a window pane by name. -private: +protected: m2d::Layout_c mLayout; ///< The layout instance. nw4r::lyt::DrawInfo mDrawInfo; ///< The parameters for drawing the layout. diff --git a/include/game/bases/d_a_player_manager.hpp b/include/game/bases/d_a_player_manager.hpp index d254018e..5841bc0c 100644 --- a/include/game/bases/d_a_player_manager.hpp +++ b/include/game/bases/d_a_player_manager.hpp @@ -19,6 +19,8 @@ class daPyMng_c { static int mNum; static u8 mActPlayerInfo; + static int mScore; + static int mPlayerEntry[4]; static PLAYER_TYPE_e mPlayerType[4]; static int mPlayerMode[4]; static int mRest[4]; diff --git a/include/game/bases/d_game_com.hpp b/include/game/bases/d_game_com.hpp index ddb4aba6..b0bc5205 100644 --- a/include/game/bases/d_game_com.hpp +++ b/include/game/bases/d_game_com.hpp @@ -99,7 +99,10 @@ namespace dGameCom { bool checkRectangleOverlap(mVec3_c *, mVec3_c *, mVec3_c *, mVec3_c *, float); ///< @unofficial + void SelectCursorSetup(); void SelectCursorSetup(nw4r::lyt::Pane *pane, int index, bool useSpecialDraw); + + void WindowPaneColorSet(nw4r::lyt::Window *, int); float getDispCenterY(); void DispSizeScale(nw4r::math::VEC2 &scale); @@ -107,9 +110,8 @@ namespace dGameCom { void LayoutDispNumber(const int &value, const int &fillLeft, LytTextBox_c *textBox, bool fillWidth); bool isNowCourseClear(); - void SelectCursorSetup(); - void SelectCursorSetup(nw4r::lyt::Pane *, int, bool); - void WindowPaneColorSet(nw4r::lyt::Window *, int); void initGame(); + void AreaLanguageFolder(const char *, char *); + void fn_800B37E0(mVec3_c &, bool); ///< @unofficial } diff --git a/include/game/bases/d_gamedisplay.hpp b/include/game/bases/d_gamedisplay.hpp new file mode 100644 index 00000000..008701df --- /dev/null +++ b/include/game/bases/d_gamedisplay.hpp @@ -0,0 +1,292 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace EGG { + +class Effect { +public: + enum ERecursive {}; + + Effect(); + virtual ~Effect(); + virtual void create(); + virtual void fade(); + virtual void followFade(); + virtual void kill(); + virtual void setDisableCalc(bool); + virtual void setDisableDraw(bool); + virtual void setDisableCalcDraw(bool); + virtual void setLife(unsigned short, EGG::Effect::ERecursive); + virtual void setEmitRatio(float, EGG::Effect::ERecursive); + virtual void setEmitInterval(unsigned short, EGG::Effect::ERecursive); + virtual void setEmitEmitDiv(unsigned short, EGG::Effect::ERecursive); + virtual void setInitVelocityRandom(signed char, EGG::Effect::ERecursive); + virtual void setPowerYAxis(float, EGG::Effect::ERecursive); + virtual void setPowerRadiationDir(float, EGG::Effect::ERecursive); + virtual void setPowerSpecDir(float, EGG::Effect::ERecursive); + virtual void setPowerSpecDirAdd(float, EGG::Effect::ERecursive); + virtual void setSpecDir(const nw4r::math::VEC3&, EGG::Effect::ERecursive); + virtual void setSpecDirAdd(const nw4r::math::VEC3&, EGG::Effect::ERecursive); + virtual void setVelocity(const nw4r::math::VEC3&); + virtual void setColor(unsigned char, unsigned char, unsigned char, unsigned char, EGG::Effect::ERecursive); + virtual void setDefaultParticleSize(nw4r::math::VEC2&, EGG::Effect::ERecursive); + virtual void setParticleScale(nw4r::math::VEC2&, EGG::Effect::ERecursive); + virtual void setDefaultParticleRotate(const nw4r::math::VEC3&, EGG::Effect::ERecursive); + virtual void setParticleRotate(const nw4r::math::VEC3&, EGG::Effect::ERecursive); + virtual void setEmitterSize(const nw4r::math::VEC3&, bool, EGG::Effect::ERecursive); + virtual void setLocalScale(const nw4r::math::VEC3&, EGG::Effect::ERecursive); + virtual void setDynamicsScale(const nw4r::math::VEC3&, const nw4r::math::VEC2*); + virtual void setScale(float); + virtual void setScale(const nw4r::math::VEC3&); + virtual void setPos(const nw4r::math::VEC3&); + virtual void setMtx(const nw4r::math::MTX34&); + virtual void setPtclAnim(int, bool); + virtual void update(); + virtual void getEffect() const; + virtual void getRootEmitter() const; + virtual void reset(); + + u8 mPad[0x7c]; +}; + +} // namespace EGG +namespace mEf { + +class effect_c : public EGG::Effect { +public: + effect_c() {} + + virtual void createEffect(const char *, int); + virtual void createEffect(const char *, ulong, const mVec3_c *, const mAng3_c *, const mVec3_c *); + virtual void createEffect(const char *, ulong, const mMtx_c *); + // virtual void vfa8(); + // virtual void vfac(); + virtual void follow(const mVec3_c *, const mAng3_c *, const mVec3_c *); + virtual void follow(const mMtx_c *); + + u8 mPad[0x92]; + mAng mAng; +}; + +class levelEffect_c : public effect_c { +public: + levelEffect_c() : m_114(0), m_118(0), m_11c(0), m_11d(0), m_120(0), m_124(0) {} + virtual ~levelEffect_c() { cleanup(); } + + // [tmp, so that vtable doesn't generate in this TU] + virtual void createEffect(const char *, int); + + void cleanup(); + + u32 m_114, m_118; + u8 m_11c, m_11d; + u32 m_120, m_124; +}; + +void createEffect(const char *, unsigned long, const mVec3_c *, const mAng3_c *, const mVec3_c *); + +}; // namespace mEf +class PauseManager_c { +public: + u8 m_00[0x1D]; // TODO + u8 mDisablePause; + static bool m_OtasukeAfter; + static PauseManager_c *m_instance; +}; +class dActorCreateMng_c { +public: + u8 m_00[0xBCB]; // TODO + u8 m_bcb; + static dActorCreateMng_c *m_instance; +}; +class dStageTimer_c { +public: + char mPad1[4]; + u32 mPreciseTime; + void setTimer(short time); + static dStageTimer_c *m_instance; +}; + +struct mRect_c { + float left, top, right, bottom; +}; + +class dGameDisplay_c : public dBase_c { + + /// @brief The picture panes used in the layout. + /// @unofficial + enum P_PANE_e { + P_collectOff_00, + P_collection_00, + P_collectOff_01, + P_collection_01, + P_collectOff_02, + P_collection_02, + P_marioIcon_00, + P_luijiIcon_00, + P_kinoB_00, + P_kinoY_00, + P_COUNT + }; + + /// @brief The text boxes used in the layout. + /// @unofficial + enum T_PANE_e { + T_left_00, + T_x_01, + T_left_01, + T_x_02, + T_left_02, + T_x_03, + T_left_03, + T_x_04, + T_coin_00, + T_time_00, + T_score_00, + T_COUNT + }; + + /// @brief The null panes used in the layout. + /// @unofficial + enum N_PANE_e { + N_otasukeInfo_00, + N_otasukeChu_00, + N_left_00, + N_coin_00, + N_collection_00, + N_score_00, + N_areaZanki_00, + N_areaCoin_00, + N_areaScore_00, + N_marioIcon_00, + N_luigiIcon_00, + N_kinoB_00, + N_kinoY_00, + N_coin_01, + N_time_00, + N_proportionL_00, + N_proportionR_00, + N_coin1st_00, + N_coin2nd_00, + N_coin3rd_00, + N_COUNT + }; + +public: + dGameDisplay_c(); + + virtual int create(); + virtual int execute(); + virtual int doDelete(); + virtual int draw(); + virtual ~dGameDisplay_c(); + +private: + void AlphaEnterAndExit(); + void AreaCheck(); + void AreaSetup(int, int); + bool createLayout(); + void Effect1UP(int); + void EffectCollectionCoinClear(); + void EffectCollectionCoinGet(int); + void GrayColorSet(int); + bool NormalSettle(); + bool OtasukeSettle(); + void OtehonPosChange(); + void RestCoinAnimeCheck(); + void RestCoinAnimeSetup(); + void RestDispSetup(); + void ReturnGrayColorSet(int); + void setCoinNum(int); + void setCollect(); + void setPlayNum(int *); + void setScore(int); + void setTime(int); + void fn_801585c0(); + + LytBase_c mLayout; + mEf::levelEffect_c mEffect; + GXColorS10 mColorBackup[3][PLAYER_COUNT]; + + sFStateMgr_c mStateMgr; + + STATE_FUNC_DECLARE(dGameDisplay_c, ProcGoalEnd); + STATE_FUNC_DECLARE(dGameDisplay_c, ProcGoalSettleUp); + STATE_FUNC_DECLARE(dGameDisplay_c, ProcMainGame); + STATE_FUNC_DECLARE(dGameDisplay_c, ProcMainPause); + + int mPlayNum[PLAYER_COUNT]; + int mCoins; + int mTimer; + u32 m_3E4; + int mScore; + int m_3EC[3]; // one for each star coin + u32 m_3F8; + u32 m_3FC; + int m_400; + int m_404; + int m_408; + u32 m_40C; + u32 m_410; + int m_414; + int mAreaAlpha[3]; + + u32 m_424[PLAYER_COUNT]; + + int m_434; + int m_438; + u32 m_43C; + int m_440; + u32 m_444; + + u8 m_448; + u8 m_449; + u8 m_44A; + bool mHasLoadedLayout; + u8 m_44C; + u8 m_44D[3]; + u8 m_450; + u8 m_451; + u8 m_452; + u8 m_453; + u8 m_454[PLAYER_COUNT]; + mRect_c m_458[3]; + u32 m_488; + u32 m_48C; + + nw4r::lyt::Pane *mpRootPane; ///< The root pane of the view. + + nw4r::lyt::Picture *mpPicturePanes[P_COUNT]; ///< The picture panes of the view. + LytTextBox_c *mpTextBoxes[T_COUNT]; ///< The textboxes of the view. + nw4r::lyt::Pane *mpNullPanes[N_COUNT]; ///< The null panes of the view. + + float m_538; + float m_53C; + float m_540; + + mVec3_c m_544; + mVec3_c m_550; + mVec3_c m_55C; + mVec3_c m_568; + mVec3_c m_574; + mVec3_c m_580; + mVec3_c m_58C; + mVec3_c m_598; + +public: + static dGameDisplay_c *m_instance; + static const int c_COINNUM_DIGIT; + static const int c_PLAYNUM_DIGIT; + static const int c_TIME_DIGIT; + static const int c_SCORE_DIGIT; +}; diff --git a/include/game/bases/d_info.hpp b/include/game/bases/d_info.hpp index c1f9b316..a539512e 100644 --- a/include/game/bases/d_info.hpp +++ b/include/game/bases/d_info.hpp @@ -69,8 +69,8 @@ class dInfo_c { int mDisplayCourseWorld; int mDisplayCourseNum; u8 pad6[0x14]; - int mTextBoxMessageID; int mTextBoxMessageGroup; + int mTextBoxMessageID; u8 pad7[0x1]; bool mExtensionAttached; u8 m_3da; diff --git a/include/game/bases/d_lytbase.hpp b/include/game/bases/d_lytbase.hpp index 46e33ab6..8fc9769b 100644 --- a/include/game/bases/d_lytbase.hpp +++ b/include/game/bases/d_lytbase.hpp @@ -9,40 +9,43 @@ class LytBase_c : public d2d::Multi_c { public: LytBase_c(); ~LytBase_c(); - virtual bool build(const char *, d2d::ResAccMult_c *); - - LytTextBox_c *findTextBox(const char *); - void allocStringBuffer(nw4r::lyt::Pane *); - - bool ReadResourceEx(const char *, int, bool); - bool ReadResource(const char *, bool); - bool ReadResource2(const char *, int); - bool ReadResource3(const char *, int); ///< @unofficial [Not in Shield version.] - - void NPaneRegister(const char **, nw4r::lyt::Pane **, int); - void WPaneRegister(const char **, nw4r::lyt::Window **, int); - void PPaneRegister(const char **, nw4r::lyt::Picture **, int); - void TPaneRegister(const char **, LytTextBox_c **, int); - void TPaneNameRegister(const char **, const int *, int, int); - void AnimeResRegister(const char **, int); - void GroupRegister(const char **, const int *, int); - - void AnimeStartBaseSetup(int); - void AnimeStartSetup(int, bool); - void LoopAnimeStartSetup(int); - void ReverseAnimeStartSetup(int, bool); - void AnimeEndSetup(int); + virtual bool build(const char *name, d2d::ResAccMult_c *resAcc); + + LytTextBox_c *findTextBox(const char *name); + void allocStringBuffer(nw4r::lyt::Pane *pane); + + bool ReadResourceEx(const char *name, int i, bool isLocalized); + bool ReadResource(const char *name, bool isLocalized); + bool ReadResource2(const char *name, int i); + bool ReadResource3(const char *name, int i); ///< @unofficial [Not in Shield version]. + + void NPaneRegister(const char **paneNames, nw4r::lyt::Pane **panes, int count); + void WPaneRegister(const char **windowPaneNames, nw4r::lyt::Window **panes, int count); + void PPaneRegister(const char **picPaneNames, nw4r::lyt::Picture **panes, int count); + void TPaneRegister(const char **textboxNames, LytTextBox_c **panes, int count); + void TPaneNameRegister(const char **textboxNames, const int *messageIDs, int messageGroup, int count); + void AnimeResRegister(const char **animeNames, int count); + void GroupRegister(const char **groupNames, const int *animeIdxs, int count); + + void AnimeStartBaseSetup(int animeIdx); + void AnimeStartSetup(int animeIdx, bool startAtEnd); + void LoopAnimeStartSetup(int animeIdx); + void ReverseAnimeStartSetup(int animeIdx, bool startAtEnd); + void AnimeEndSetup(int animeIdx); void AllAnimeEndSetup(); void AnimePlay(); bool isAnime(int); bool isAllAnime(); - void FUN_800c9770(void *, float *); ///< @unofficial + void SetScissorMask(const nw4r::lyt::Pane *pane, d2d::ScissorMask &scissorMask); ///< @unofficial bool doDelete(); public: + m2d::AnmGroup_c &getAnmGroup(int index) const { return mpAnimGroup[index]; } + +private: d2d::ResAccMultLoader_c mResAccessorLoader; m2d::AnmResV2_c *mpAnimRes; @@ -50,7 +53,6 @@ class LytBase_c : public d2d::Multi_c { bool *mpEnabledAnims; int mAnimCount; - int mGroupCount; int mLastStartedAnimNum; diff --git a/include/game/bases/d_message.hpp b/include/game/bases/d_message.hpp index 2dba8711..f042f349 100644 --- a/include/game/bases/d_message.hpp +++ b/include/game/bases/d_message.hpp @@ -6,8 +6,8 @@ class MsgRes_c : public EGG::MsgRes { public: - u8 getFont(ulong messageID, ulong messageGroup); - u16 getScale(ulong messageID, ulong messageGroup); + u8 getFont(ulong messageGroup, ulong messageID); + u16 getScale(ulong messageGroup, ulong messageID); }; class dMessage_c { diff --git a/include/game/bases/d_s_stage.hpp b/include/game/bases/d_s_stage.hpp index 573dcbb7..7eac3c7f 100644 --- a/include/game/bases/d_s_stage.hpp +++ b/include/game/bases/d_s_stage.hpp @@ -21,8 +21,16 @@ class dScStage_c : public dScene_c { LOOP_COUNT, }; + u8 getCurrWorld() const { return mCurrWorld; } + u8 getCurrArea() const { return mCurrArea; } + u8 getCurrCourse() const { return mCurrCourse; } + u8 getCurrFile() const { return mCurrFile; } + + static void play(); + static float getLoopPosX(float x); + typedef void (*changePosFunc)(mVec3_c *); static void setChangePosFunc(int); @@ -30,17 +38,15 @@ class dScStage_c : public dScene_c { static void createReplayDataHeap(EGG::Heap *heap, ulong size, int options); + static dScStage_c *getInstance() { return m_instance; } + + char pad[0x1198]; u8 mCurrWorld; u8 mCurrCourse; u8 mCurrFile; u8 mCurrArea; - u8 getCurrWorld() const { return mCurrWorld; } - u8 getCurrArea() const { return mCurrArea; } - - static dScStage_c *getInstance() { return m_instance; } - static float getLoopPosX(float x); static u32 m_exeFrame; static int m_loopType; static PLAYER_TYPE_e mCollectionCoin[STAR_COIN_COUNT]; @@ -51,6 +57,8 @@ class dScStage_c : public dScene_c { static bool m_KoopaJrEscape; static dInfo_c::GameMode_e m_gameMode; static Exit_e m_exitMode; + static u32 m_miniGame; + static bool m_isStaffCredit; static changePosFunc changePos; static dScStage_c *m_instance; diff --git a/include/game/bases/d_tag_processor.hpp b/include/game/bases/d_tag_processor.hpp index 0691e1d4..7eb8a678 100644 --- a/include/game/bases/d_tag_processor.hpp +++ b/include/game/bases/d_tag_processor.hpp @@ -6,6 +6,9 @@ class TagProcessor_c : public nw4r::ut::WideTagProcessor { public: + TagProcessor_c(); + ~TagProcessor_c(); + u8 mPad[0xc0]; u8 mFontIndex; diff --git a/include/game/framework/f_profile_name.hpp b/include/game/framework/f_profile_name.hpp index 38cfcbed..a74aa7dc 100644 --- a/include/game/framework/f_profile_name.hpp +++ b/include/game/framework/f_profile_name.hpp @@ -716,7 +716,7 @@ namespace fProfile { COURSE_SELECT_MANAGER, FUKIDASHI_MANAGER, SMALL_SCORE_MANAGER, - GAMEDISPLAY, + GAMEDISPLAY, ///< The profile for dGameDisplay_c. OTASUKE_INFO, PAUSEWINDOW, RESULT, diff --git a/include/game/mLib/m_2d/animation.hpp b/include/game/mLib/m_2d/animation.hpp index 15751c0c..0b3a1bf5 100644 --- a/include/game/mLib/m_2d/animation.hpp +++ b/include/game/mLib/m_2d/animation.hpp @@ -16,7 +16,7 @@ struct GroupAnimTransform_s { class AnmResV2_c { public: - AnmResV2_c() {} + AnmResV2_c() : mGroupAnim(nullptr), mGroupNum(0) {} virtual ~AnmResV2_c() {} bool create(const char *name, m2d::ResAccIf_c *resAcc, m2d::Layout_c *layout, bool useOverride); @@ -39,6 +39,7 @@ class AnmGroupBase_c { }; AnmGroupBase_c() {} + AnmGroupBase_c(FrameCtrl_c *fc) : mpFrameCtrl(fc), mpAnmRes(nullptr), mpGroupAnim(nullptr), mFlags(0) {} bool create(AnmResV2_c *anmRes, const char *name); void setAnmEnable(bool enable); @@ -52,7 +53,20 @@ class AnmGroupBase_c { class AnmGroup_c : public AnmGroupBase_c { public: + AnmGroup_c() : AnmGroupBase_c(&mFrameCtrl) { + mFrameCtrl.mEndFrame = 0.0f; + mFrameCtrl.mCurrFrame = 0.0f; + mFrameCtrl.mPrevFrame = 0.0f; + mFrameCtrl.mRate = 1.0f; + } + + void play() { mpFrameCtrl->play(); updateFrame(); } + void setStart() { mpFrameCtrl->setFrame(1.0f); updateFrame(); } + void setLast() { mpFrameCtrl->setFrame(mpFrameCtrl->getLastActiveFrame()); updateFrame(); } + void setEnd() { mpFrameCtrl->setFrame(mpFrameCtrl->getLastFrame()); updateFrame(); } void setAndUpdate(float frame) { mpFrameCtrl->setFrame(frame); updateFrame(); } + + FrameCtrl_c mFrameCtrl; }; } // namespace m2d diff --git a/include/game/mLib/m_2d/frame_ctrl.hpp b/include/game/mLib/m_2d/frame_ctrl.hpp index 0c0f7cb6..a24321b3 100644 --- a/include/game/mLib/m_2d/frame_ctrl.hpp +++ b/include/game/mLib/m_2d/frame_ctrl.hpp @@ -19,8 +19,12 @@ class FrameCtrl_c { void setRate(float rate); bool isStop() const; + void setFlags(bool loop, bool reverse) { + mFlags = (!loop ? FrameCtrl_c::NO_LOOP : 0) | (reverse ? FrameCtrl_c::REVERSE : 0); + } float getFrame() const { return mCurrFrame; } - float getLastActiveFrame() const { return mEndFrame - 1.0f; } + float getLastFrame() const { return mEndFrame - 1.0f; } + float getLastActiveFrame() const { return mEndFrame - 2.0f; } float mEndFrame; float mCurrFrame; diff --git a/include/game/mLib/m_fader_base.hpp b/include/game/mLib/m_fader_base.hpp index 14a180e2..e63cde94 100644 --- a/include/game/mLib/m_fader_base.hpp +++ b/include/game/mLib/m_fader_base.hpp @@ -51,6 +51,10 @@ class mFaderBase_c { void setFrame(u16 duration); ///< Sets the duration of the fade. Duration must not be zero. void setColor(const mColor &color); ///< Sets the fader's color. Alpha is not modified. + bool isHidden() const { + return getStatus() == HIDDEN; + } + protected: EStatus mStatus; ///< The fader's status. u8 mFlag; ///< The fader's flags. diff --git a/include/game/mLib/m_mtx.hpp b/include/game/mLib/m_mtx.hpp index cb701ca8..46a88a86 100644 --- a/include/game/mLib/m_mtx.hpp +++ b/include/game/mLib/m_mtx.hpp @@ -11,6 +11,9 @@ class mMtx_c : public nw4r::math::MTX34 { /// @brief Constructs an empty matrix. mMtx_c() {} + /// @brief Constructs a matrix from an MTX34. + mMtx_c(const nw4r::math::MTX34 &mtx) : MTX34(mtx) {} + /// @brief Constructs a matrix with the given components. mMtx_c(float _00, float _01, float _02, float _03, float _10, float _11, float _12, float _13, float _20, float _21, float _22, float _23); diff --git a/include/game/mLib/m_vec.hpp b/include/game/mLib/m_vec.hpp index b62a374e..7b29ed01 100644 --- a/include/game/mLib/m_vec.hpp +++ b/include/game/mLib/m_vec.hpp @@ -29,6 +29,7 @@ class mVec2_c : public EGG::Vector2f { /// @brief Copy constructor. mVec2_c(const mVec2_c &v) { set(v.x, v.y); } + mVec2_c(const nw4r::math::VEC2 &v) { set(v.x, v.y); } void set(float x, float y) { this->x = x; @@ -101,6 +102,10 @@ class mVec2_c : public EGG::Vector2f { bool operator!=(const mVec2_c &v) const { return x != v.x || y != v.y; } }; +inline mVec2_c operator*(float f, const mVec2_c &v) { + return mVec2_c(f * v.x, f * v.y); +} + /// @brief A three-dimensional floating point vector. /// @ingroup mlib /// @todo Add EGG::vector3f operators. @@ -189,6 +194,13 @@ class mVec3_c : public EGG::Vector3f { /// @brief Inequality operator. bool operator!=(const mVec3_c &v) const { return x != v.x || y != v.y || z != v.z; } + mVec3_c &setToShifted(const mVec3_c &v, float sx, float sy, float sz) { + x = sx + v.x; + y = sy + v.y; + z = sz + v.z; + return *this; + } + float xzLen() const { return EGG::Mathf::sqrt(x * x + z * z); } diff --git a/include/game/mLib/m_video.hpp b/include/game/mLib/m_video.hpp index 36b518c0..9fbd8319 100644 --- a/include/game/mLib/m_video.hpp +++ b/include/game/mLib/m_video.hpp @@ -5,6 +5,9 @@ class mVideo { public: static void create(); + float getWidth() const { return mRenderModeObj.fbWidth; } + float getHeight() const { return mRenderModeObj.efbHeight; } + static float getSmth(float offs) { return (m_video->mRenderModeObj.efbHeight - offs) * 0.5f; } GXRenderModeObj &mRenderModeObj; diff --git a/include/game/snd/snd_audio_mgr.hpp b/include/game/snd/snd_audio_mgr.hpp index bbb7b9a8..faeabb40 100644 --- a/include/game/snd/snd_audio_mgr.hpp +++ b/include/game/snd/snd_audio_mgr.hpp @@ -3,6 +3,7 @@ class SndAudioMgr { public: void startSystemSe(unsigned int soundID, unsigned long); + void holdSystemSe(unsigned int soundID, unsigned long); public: static SndAudioMgr *sInstance; diff --git a/include/lib/egg/core/eggMsgRes.h b/include/lib/egg/core/eggMsgRes.h index b7b93d94..5714b3e1 100644 --- a/include/lib/egg/core/eggMsgRes.h +++ b/include/lib/egg/core/eggMsgRes.h @@ -6,7 +6,7 @@ namespace EGG { class MsgRes { public: - wchar_t *getMsg(ulong messageID, ulong messageGroup); + wchar_t *getMsg(ulong messageGroup, ulong messageID); }; } // namespace EGG diff --git a/slices/wiimj2d.json b/slices/wiimj2d.json index e4f02a11..50a695e5 100644 --- a/slices/wiimj2d.json +++ b/slices/wiimj2d.json @@ -287,6 +287,18 @@ ".sdata2": "0x1380-0x1388" } }, + { + "source": "dol/bases/d_lytbase.cpp", + "memoryRanges": { + ".text": "0xc2220-0xc33d0", + ".ctors": "0x11c-0x120", + ".rodata": "0x3338-0x33a0", + ".data": "0x19098-0x190e0", + ".sdata": "0x588-0x598", + ".bss": "0x7de0-0x7eb8", + ".sdata2": "0x1878-0x1898" + } + }, { "source": "dol/bases/d_lyttextbox.cpp", "memoryRanges": { @@ -516,6 +528,21 @@ ".sdata": "0x1cd8-0x1ce0" } }, + { + "source": "dol/bases/d_gamedisplay.cpp", + "nonMatching": true, + "memoryRanges": { + ".text": "0x1510a0-0x153d00", + ".ctors": "0x1f4-0x1f8", + ".data": "0x28fc8-0x29660", + ".sbss2": "0x28-0x30", + ".rodata": "0x7c48-0x7d00", + ".sdata": "0x1d28-0x1d50", + ".sbss": "0x768-0x778", + ".sdata2": "0x2b30-0x2b48", + ".bss": "0x259e8-0x25ae8" + } + }, { "source": "dol/bases/d_pausewindow.cpp", "memoryRanges": { diff --git a/source/dol/bases/d_gamedisplay.cpp b/source/dol/bases/d_gamedisplay.cpp new file mode 100644 index 00000000..beeaae21 --- /dev/null +++ b/source/dol/bases/d_gamedisplay.cpp @@ -0,0 +1,941 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ACTOR_PROFILE(GAMEDISPLAY, dGameDisplay_c, 0); + +STATE_DEFINE(dGameDisplay_c, ProcMainGame); +STATE_DEFINE(dGameDisplay_c, ProcMainPause); +STATE_DEFINE(dGameDisplay_c, ProcGoalSettleUp); +STATE_DEFINE(dGameDisplay_c, ProcGoalEnd); + +dGameDisplay_c *dGameDisplay_c::m_instance; +const int dGameDisplay_c::c_COINNUM_DIGIT = 2; +const int dGameDisplay_c::c_PLAYNUM_DIGIT = 2; +const int dGameDisplay_c::c_TIME_DIGIT = 3; +const int dGameDisplay_c::c_SCORE_DIGIT = 8; + + +dGameDisplay_c::~dGameDisplay_c() { + m_instance = nullptr; +} + +dGameDisplay_c::dGameDisplay_c() : + mStateMgr(*this, StateID_ProcMainGame), + m_452(1), + mHasLoadedLayout(false) +{ + m_instance = this; +} + +int dGameDisplay_c::create() { + if (mHasLoadedLayout) { + return 1; + } + + if (!createLayout()) { + return 0; + } + + mLayout.mDrawOrder = 0x11; + + for (int i = 0; i < PLAYER_COUNT; i++) { + mPlayNum[i] = -1; + m_424[i] = 0; + m_454[i] = 0; + } + + m_454[3] = 0; + mScore = 1; + m_3E4 = 1; + mCoins = 1; + mTimer = -1; + m_434 = 2; + + setPlayNum(mPlayNum); + setCoinNum(0); + setTime(0); + setScore(0); + + m_438 = 0; + m_440 = 0; + m_3FC = -1; + m_3F8 = -1; + m_444 = 0; + m_453 = 0; + m_400 = 0; + m_404 = 0x1e; + m_408 = 0x1e; + m_40C = 0; + m_43C = 0; + m_540 = 0; + m_53C = 0; + m_538 = 0; + + RestDispSetup(); + fn_801585c0(); + mLayout.AllAnimeEndSetup(); + + if ((dScStage_c::m_gameMode == 2) || (dScStage_c::m_gameMode == 3) || dScStage_c::m_miniGame || (dInfo_c::m_startGameInfo.mLevel1 == STAGE_PEACH_CASTLE) || dScStage_c::m_isStaffCredit) { + mpRootPane->SetVisible(false); + } else { + mpRootPane->SetVisible(true); + } + + if (dScStage_c::m_gameMode == 1) { + mpNullPanes[N_otasukeInfo_00]->SetVisible(true); + } else { + mpNullPanes[N_otasukeInfo_00]->SetVisible(false); + } + + if (PauseManager_c::m_OtasukeAfter) { + m_448 = 1; + mpNullPanes[N_otasukeChu_00]->SetVisible(true); + mpNullPanes[N_left_00]->SetVisible(false); + mLayout.ReverseAnimeStartSetup(0, false); + } else { + m_448 = 0; + mpNullPanes[N_otasukeChu_00]->SetVisible(false); + mpNullPanes[N_left_00]->SetVisible(true); + } + + if (dInfo_c::m_startGameInfo.mLevel1 == STAGE_CANNON) { + mpNullPanes[N_collection_00]->SetVisible(false); + mpNullPanes[N_score_00]->SetVisible(false); + mpNullPanes[N_time_00]->SetVisible(false); + } else { + mpNullPanes[N_collection_00]->SetVisible(true); + mpNullPanes[N_score_00]->SetVisible(true); + mpNullPanes[N_time_00]->SetVisible(true); + } + + if (dInfo_c::mGameFlag & 0x40) { + mpNullPanes[N_score_00]->SetVisible(false); + } + + + dMj2dGame_c *save = dSaveMng_c::m_instance->getSaveGame(-1); + u32 w = dInfo_c::m_startGameInfo.mWorld1; + u32 l = dInfo_c::m_startGameInfo.mLevel1; + if (w > WORLD_USED_COUNT) { + w = 0; + } + if (l > STAGE_STAFFROLL) { + l = STAGE_1; + } + + if (!(dInfo_c::mGameFlag & 0x10) && !(dInfo_c::mGameFlag & 0x80000000) && !dScWMap_c::IsCourseType(w, l, dScWMap_c::COURSE_TYPE_NO_STAR_COINS)) { + mpNullPanes[N_collection_00]->SetVisible(false); + } + + for (u32 i = 0; i < 3; i++) { + m_3EC[i] = 3; + if ((dScStage_c::mCollectionCoin[i] != 4) || save->isCollectCoin(w, l, i)) { + mpPicturePanes[P_collectOff_00 + 2 * i]->SetVisible(false); + mpPicturePanes[P_collection_00 + 2 * i]->SetVisible(true); + m_3EC[i] = 2; + } + } + + mVec2_c disp_scale; + dGameCom::DispSizeScale(disp_scale); + mpNullPanes[N_proportionL_00]->SetScale(disp_scale); + mpNullPanes[N_proportionR_00]->SetScale(disp_scale); + + m_544 = mpNullPanes[N_proportionL_00]->GetTranslate(); + m_550 = mpNullPanes[N_proportionR_00]->GetTranslate(); + m_55C = mpNullPanes[N_otasukeChu_00]->GetTranslate(); + m_568 = mpNullPanes[N_areaZanki_00]->GetTranslate(); + m_574 = mpNullPanes[N_otasukeInfo_00]->GetTranslate(); + m_580 = mpNullPanes[N_areaCoin_00]->GetTranslate(); + m_58C = mpNullPanes[N_areaScore_00]->GetTranslate(); + m_598 = mpNullPanes[N_time_00]->GetTranslate(); + + OtehonPosChange(); + + m_449 = 0; + m_44A = 0; + mHasLoadedLayout = true; + m_44C = 0; + for (int i = 0; i < 3; i++) { + mAreaAlpha[i] = 0xFF; + m_44D[i] = 0; + } + m_450 = 0; + m_451 = 0; + + mLayout.calc(); + + return SUCCEEDED; +} + +int dGameDisplay_c::execute() { + if (mHasLoadedLayout) { + + RestCoinAnimeCheck(); + mStateMgr.executeState(); + + if (mLayout.isAllAnime() || m_450 || m_451) { + mLayout.AnimePlay(); + mLayout.calc(); + } + + AreaCheck(); + AlphaEnterAndExit(); + + for (int i = 0; i < PLAYER_COUNT; i++) { + if (m_424[i]) { + m_424[i]--; + } + } + } + + return SUCCEEDED; +} + +int dGameDisplay_c::draw() { + if (!m_452) { + return 1; + } + + if (mHasLoadedLayout) { + mLayout.entry(); + } + + return SUCCEEDED; +} + +int dGameDisplay_c::doDelete() { + return mLayout.doDelete(); +} + +// Doesn't match - weird float trickery +void dGameDisplay_c::OtehonPosChange() { + if (dScStage_c::m_gameMode != 4) { + return; + } + + float a = 0.0f; + float offs1 = 16.0f; + float offs2 = 23.0f; + + float x = a + offs1; // 16.0f + float e = a - offs1; // -16.0f + + float d = a - offs2; // -23.0f + float f = a + offs2; // 23.0f + + mVec3_c v; + + v.setToShifted(m_544, x, 0.0f, 0.0f); + mpNullPanes[N_proportionL_00]->SetTranslate(v); + + v.setToShifted(m_550, e, 0.0f, 0.0f); + mpNullPanes[N_proportionR_00]->SetTranslate(v); + + v.setToShifted(m_55C, 0.0f, d, 0.0f); + mpNullPanes[N_otasukeChu_00]->SetTranslate(v); + + v.setToShifted(m_568, 0.0f, d, 0.0f); + mpNullPanes[N_areaZanki_00]->SetTranslate(v); + + v.setToShifted(m_574, 0.0f, f, 0.0f); + mpNullPanes[N_otasukeInfo_00]->SetTranslate(v); + + v.setToShifted(m_580, 0.0f, d, 0.0f); + mpNullPanes[N_areaCoin_00]->SetTranslate(v); + + v.setToShifted(m_58C, 0.0f, d, 0.0f); + mpNullPanes[N_areaScore_00]->SetTranslate(v); + + v.setToShifted(m_598, 0.0f, d, 0.0f); + mpNullPanes[N_time_00]->SetTranslate(v); + + mLayout.calc(); +} + +void dGameDisplay_c::AreaSetup(int a, int areaPane) { + nw4r::math::MTX34 mtx = mpNullPanes[areaPane]->GetGlobalMtx(); + m_458[a].right = mtx._03; + m_458[a].bottom = mtx._03; + m_458[a].left = mtx._13; + m_458[a].top = mtx._13; + nw4r::lyt::Size size = mpNullPanes[areaPane]->GetSize(); + + float w = size.width; + switch (mpNullPanes[areaPane]->GetBasePositionH()) { + case 0: + m_458[a].bottom += w; + break; + case 1: + w /= 2; + m_458[a].right -= w; + m_458[a].bottom += w; + break; + case 2: + m_458[a].right -= w; + break; + } + + float h = size.height; + switch (mpNullPanes[areaPane]->GetBasePositionV()) { + case 0: + m_458[a].top -= h; + break; + case 1: + h /= 2; + m_458[a].left += h; + m_458[a].top -= h; + break; + case 2: + m_458[a].left += h; + break; + } +} + + + +void dGameDisplay_c::fn_801585c0() { + for (int i = 0; i < 3; i++) { + AreaSetup(i, N_areaZanki_00 + i); + } + + if (m_414 != P_marioIcon_00) { + nw4r::lyt::Pane *pane = mpPicturePanes[m_414]; + nw4r::math::MTX34 mtx = pane->GetGlobalMtx(); + nw4r::lyt::Size size = pane->GetSize(); + + float f = mtx._03 + size.width * 0.5f; + f += 60.0f; + m_458[0].bottom = f; + } +} + + +void dGameDisplay_c::RestDispSetup() { + mVec3_c iconPos[4]; + + static const u32 lbl_802F5C38[PLAYER_COUNT] = { + P_marioIcon_00, P_luijiIcon_00, P_kinoY_00, P_kinoB_00, + }; + + iconPos[PLAYER_MARIO] = mpPicturePanes[P_marioIcon_00]->GetTranslate(); + mpPicturePanes[P_marioIcon_00]->SetVisible(false); + iconPos[PLAYER_LUIGI] = mpPicturePanes[P_luijiIcon_00]->GetTranslate(); + mpPicturePanes[P_luijiIcon_00]->SetVisible(false); + iconPos[PLAYER_YELLOW_TOAD] = mpPicturePanes[P_kinoB_00]->GetTranslate(); + mpPicturePanes[P_kinoB_00]->SetVisible(false); + iconPos[PLAYER_BLUE_TOAD] = mpPicturePanes[P_kinoY_00]->GetTranslate(); + mpPicturePanes[P_kinoY_00]->SetVisible(false); + + int iconPosIdx = 0; + for (int i = 0; i < PLAYER_COUNT; i++) { + int idx = daPyMng_c::getPlayerIndex(daPyCom_c::sc_PLAYER_ORDER[i]); + if (!daPyMng_c::mPlayerEntry[idx]) { + continue; + } + + mpPicturePanes[lbl_802F5C38[i]]->SetVisible(true); + mpPicturePanes[lbl_802F5C38[i]]->SetTranslate(iconPos[iconPosIdx]); + iconPosIdx++; + m_414 = P_marioIcon_00 + i; + } +} + +bool dGameDisplay_c::createLayout() { + static const char *AnmNameTbl[] = { + "gameScene_37_inMarioCoin.brlan" + }; + + static const char *GROUP_NAME_DT[] = { + "C00_inMarioCoin" + }; + static const int ANIME_INDEX_TBL[] = { + 0 + }; + + static const int MESSAGE_DATA_TBL[] = { + 0x14, 0x14, 0x13, 0x13 + }; + + static const char *NPANE_NAME_DT[] = { + "N_otasukeInfo_00", "N_otasukeChu_00", + "N_left_00", + "N_coin_00", + "N_collection_00", + "N_score_00", + "N_areaZanki_00", "N_areaCoin_00", "N_areaScore_00", + "N_marioIcon_00", "N_luigiIcon_00", "N_kinoB_00", "N_kinoY_00", + "N_coin_01", + "N_time_00", + "N_proportionL_00", "N_proportionR_00", + "N_coin1st_00", "N_coin2nd_00", "N_coin3rd_00" + }; + + static const char *PPANE_NAME_DT[] = { + "P_collectOff_00", "P_collection_00", + "P_collectOff_01", "P_collection_01", + "P_collectOff_02", "P_collection_02", + "P_marioIcon_00", "P_luijiIcon_00", + "P_kinoB_00", "P_kinoY_00" + }; + + static const char *T_PANE_NAME_DT[] = { + "T_left_00", "T_x_01", + "T_left_01", "T_x_02", + "T_left_02", "T_x_03", + "T_left_03", "T_x_04", + "T_coin_00", + "T_time_00", + "T_score_00" + }; + + static const char *T_PANE_NAME_TBL[] = { + "T_otaChuS_00", "T_otaChu_01", + "T_InfoS_00", "T_Info_00" + }; + + if (!mLayout.ReadResource("gameScene/gameScene.arc", false)) { + return false; + } + + mLayout.build("gameScene_37.brlyt", nullptr); + mLayout.AnimeResRegister(AnmNameTbl, 1); + mLayout.GroupRegister(GROUP_NAME_DT, ANIME_INDEX_TBL, 1); + + mpRootPane = mLayout.getRootPane(); + mLayout.NPaneRegister(NPANE_NAME_DT, mpNullPanes, N_COUNT); + mLayout.PPaneRegister(PPANE_NAME_DT, mpPicturePanes, P_COUNT); + + mpPicturePanes[P_collectOff_00]->SetVisible(true); + mpPicturePanes[P_collection_00]->SetVisible(false); + mpPicturePanes[P_collectOff_01]->SetVisible(false); // [???] + mpPicturePanes[P_collectOff_01]->SetVisible(true); + mpPicturePanes[P_collection_01]->SetVisible(false); + mpPicturePanes[P_collectOff_02]->SetVisible(false); // [???] + mpPicturePanes[P_collectOff_02]->SetVisible(true); + mpPicturePanes[P_collection_02]->SetVisible(false); + + mpPicturePanes[P_marioIcon_00]->SetVisible(false); + + mLayout.TPaneRegister(T_PANE_NAME_DT, mpTextBoxes, T_COUNT); + mLayout.TPaneNameRegister(T_PANE_NAME_TBL, MESSAGE_DATA_TBL, 1, 4); + + return true; +} + + +void dGameDisplay_c::RestCoinAnimeCheck() { + if (m_44A) { + m_449 = 0; + } + if (!m_449) { + return; + } + + m_449 = 0; + m_44A = 1; + mLayout.AnimeStartSetup(0, false); + + if (dActorCreateMng_c::m_instance->m_bcb) { + PauseManager_c::m_instance->mDisablePause = true; + } +} + + +void dGameDisplay_c::AreaCheck() { + if (!mpRootPane->IsVisible()) { + return; + } + + for (int i = 0; i < PLAYER_COUNT; i++) { + if (!daPyMng_c::checkPlayer(i)) { + continue; + } + + dAcPy_c *player = daPyMng_c::getPlayer(i); + if (player == nullptr) { + continue; + } + + mVec3_c pos = player->getCenterPos(); + dGameCom::getGlbPosToLyt(pos); + + for (int i = 0; i < 3; i++) { + if (!m_44D[i] && m_458[i].right < pos.x && m_458[i].bottom > pos.x && m_458[i].left > pos.y && m_458[i].top < pos.y) { + m_44D[i] = 1; + m_450 = 1; + } + } + } +} + + +void dGameDisplay_c::AlphaEnterAndExit() { + if (!mpRootPane->IsVisible()) { + return; + } + + int x = 0; + for (int i = 0; i < 3; i++) { + int a = mpNullPanes[N_areaZanki_00 + i]->GetAlpha(); + if (m_44D[i]) { + if (a <= 70) { + x++; + } + } else if (a >= 0xFF) { + x++; + } + } + + if (x >= 3) { + m_450 = 0; + } else { + m_450 = 1; + } + + int max_alpha = 0xFF; + int min_alpha = 70; + int step = 12; + + for (int i = 0; i < 3; i++) { + int d = step; + if (m_44D[i]) { + d *= -1; + } + mAreaAlpha[i] += d; + if (mAreaAlpha[i] <= min_alpha) { + mAreaAlpha[i] = min_alpha; + } + if (mAreaAlpha[i] >= max_alpha) { + mAreaAlpha[i] = max_alpha; + } + + mpNullPanes[N_areaZanki_00 + i]->SetAlpha(mAreaAlpha[i]); + m_44D[i] = 0; + } +} + +bool dGameDisplay_c::NormalSettle() { + short t = ((int)(dStageTimer_c::m_instance->mPreciseTime + 0xFFF) >> 12); + bool ret; + if (t > 0) { + int x = m_40C; + int score = 0; + while (x > 0) { + t--; + score += m_410; + if (t <= 0) { + break; + } + x--; + } + + dStageTimer_c::m_instance->setTimer((short) t); + + if (!(dInfo_c::mGameFlag & 0x40)) { + SndAudioMgr::sInstance->holdSystemSe(SE_SYS_SCORE_COUNT, 1); + } + + daPyMng_c::addScore(score, -1); + ret = false; + } else { + ret = true; + } + + return ret; +} + +bool dGameDisplay_c::OtasukeSettle() { + dStageTimer_c *timer = dStageTimer_c::m_instance; + short t = ((int)(timer->mPreciseTime + 0xFFF) >> 12); + int score = daPyMng_c::mScore; + + if (!t && !score && !mCoins) { + return true; + } + + if (mCoins) { + mCoins += -3; + if (mCoins < 0) { + mCoins = 0; + } + } + + dGameCom::LayoutDispNumber(mCoins, c_COINNUM_DIGIT, mpTextBoxes[N_areaScore_00], false); + + if (t) { + t -= m_40C; + if (t < 0) { + t = 0; + } + } + timer->setTimer(t); + + if (score) { + score -= m_410 * m_40C; + if (score < 0) { + score = 0; + } + } + daPyMng_c::mScore = score; + + SndAudioMgr::sInstance->holdSystemSe(SE_SYS_SCORE_COUNT, 1); + + return false; +} + +// ---------------- +// StateID_ProcMainGame +// ---------------- + +void dGameDisplay_c::initializeState_ProcMainGame() { + m_43C = 0; + m_451 = 0; + m_453 = 0; +} + +void dGameDisplay_c::executeState_ProcMainGame() { + if (m_438 != 1) { + if (m_44C) { + mStateMgr.changeState(StateID_ProcGoalSettleUp); + } + return; + } else { + m_440 = 0; + mStateMgr.changeState(StateID_ProcMainPause); + } +} + +void dGameDisplay_c::finalizeState_ProcMainGame() { + m_451 = 1; +} + +// ---------------- +// StateID_ProcMainPause +// ---------------- + +void dGameDisplay_c::initializeState_ProcMainPause() { + m_43C = 1; + m_438 = 0; +} + +void dGameDisplay_c::executeState_ProcMainPause() { + if (m_440 == 1) { + mStateMgr.changeState(StateID_ProcMainGame); + } +} +void dGameDisplay_c::finalizeState_ProcMainPause() { + m_440 = 0; +} + +// ---------------- +// StateID_ProcGoalSettleUp +// ---------------- + +void dGameDisplay_c::initializeState_ProcGoalSettleUp() { + m_40C = 10; + m_410 = 0x32; + m_444 = 1; + m_453 = 1; + m_400 = 0; + + dMultiMng_c::mspInstance->m_04 = (short)((int)(dStageTimer_c::m_instance->mPreciseTime + 0xFFF) >> 12); + + if (PauseManager_c::m_OtasukeAfter) { + EffectCollectionCoinClear(); + } +} + +void dGameDisplay_c::executeState_ProcGoalSettleUp() { + if (m_400 < m_404) { + m_400++; + } else if (PauseManager_c::m_OtasukeAfter) { + if (OtasukeSettle()) { + m_400 = 0; + SndAudioMgr::sInstance->startSystemSe(SE_SYS_SCORE_COUNT_FINISH, 1); + mStateMgr.changeState(StateID_ProcGoalEnd); + } + } else { + if (NormalSettle()) { + m_400 = 0; + if (!(dInfo_c::mGameFlag & 0x40)) { + SndAudioMgr::sInstance->startSystemSe(SE_SYS_SCORE_COUNT_FINISH, 1); + } + mStateMgr.changeState(StateID_ProcGoalEnd); + } + } +} + +void dGameDisplay_c::finalizeState_ProcGoalSettleUp() {} + +// ---------------- +// StateID_ProcGoalEnd +// ---------------- + +void dGameDisplay_c::initializeState_ProcGoalEnd() {} + +void dGameDisplay_c::executeState_ProcGoalEnd() { + if (m_400 < m_408) { + m_400++; + } else { + m_444 = 0; + } +} + +void dGameDisplay_c::finalizeState_ProcGoalEnd() {} + + +void dGameDisplay_c::Effect1UP(int a) { + if ( + !mFader_c::mFader->isHidden() || + PauseManager_c::m_OtasukeAfter || + dScStage_c::m_miniGame || + dInfo_c::m_startGameInfo.mGameMode == dInfo_c::GAME_MODE_TITLE_REPLAY + ) { + return; + } + if (m_424[a] == 0) { + m_424[a] = 0xF; + + nw4r::lyt::Pane *icon = mpNullPanes[N_marioIcon_00 + a]; + + nw4r::math::MTX34 mtx = icon->GetGlobalMtx(); + + mVec3_c tmp; + tmp.x = mtx._03; + tmp.y = mtx._13; + tmp.z = 0.0f; + dGameCom::fn_800B37E0(tmp, false); + mEf::createEffect("Wm_2d_1up01", 0, &tmp, nullptr, nullptr); + + tmp.x = mtx._03; + tmp.y = mtx._13; + tmp.z = 0.0f; + dGameCom::fn_800B37E0(tmp, true); + mEf::createEffect("Wm_2d_1up02", 0, &tmp, nullptr, nullptr); + } +} + +void dGameDisplay_c::GrayColorSet(int player) { + if (m_454[player] == 0) { + static nw4r::ut::Color GrayColor(160, 160, 160, 255); + static const int TPANE_IDX_TBL[] = { + T_left_00, T_x_01, + T_left_01, T_x_02, + T_left_02, T_x_03, + T_left_03, T_x_04 + }; + static const int PPANE_IDX_TBL[] = { P_marioIcon_00, P_luijiIcon_00, P_kinoB_00, P_kinoY_00 }; + + m_454[player] = true; + nw4r::lyt::Pane *icon1 = mpPicturePanes[PPANE_IDX_TBL[player]]; + nw4r::lyt::Material *mat1 = icon1->GetMaterial(); + mColorBackup[0][player] = mat1->GetTevColor(1); + mat1->SetTevColor(1, nw4r::g3d::detail::GetRGBAS10(GrayColor)); + nw4r::lyt::Pane *icon2 = mpTextBoxes[TPANE_IDX_TBL[player * 2]]; + nw4r::lyt::Material *mat2 = icon2->GetMaterial(); + mColorBackup[1][player] = mat2->GetTevColor(1); + mat2->SetTevColor(1, nw4r::g3d::detail::GetRGBAS10(GrayColor)); + nw4r::lyt::Pane *icon3 = mpTextBoxes[TPANE_IDX_TBL[player * 2 + 1]]; + nw4r::lyt::Material *mat3 = icon3->GetMaterial(); + mColorBackup[2][player] = mat3->GetTevColor(1); + mat3->SetTevColor(1, nw4r::g3d::detail::GetRGBAS10(GrayColor)); + } +} + +void dGameDisplay_c::ReturnGrayColorSet(int player) { + if (m_454[player] != 0) { + static const int TPANE_IDX_TBL[] = { + T_left_00, T_x_01, + T_left_01, T_x_02, + T_left_02, T_x_03, + T_left_03, T_x_04 + }; + static const int PPANE_IDX_TBL[] = { P_marioIcon_00, P_luijiIcon_00, P_kinoB_00, P_kinoY_00 }; + + m_454[player] = 0; + nw4r::lyt::Pane *icon1 = mpPicturePanes[PPANE_IDX_TBL[player]]; + icon1->GetMaterial()->SetTevColor(1, mColorBackup[0][player]); + nw4r::lyt::Pane *icon2 = mpTextBoxes[TPANE_IDX_TBL[player * 2]]; + icon2->GetMaterial()->SetTevColor(1, mColorBackup[1][player]); + nw4r::lyt::Pane *icon3 = mpTextBoxes[TPANE_IDX_TBL[player * 2 + 1]]; + icon3->GetMaterial()->SetTevColor(1, mColorBackup[2][player]); + } +} + +void dGameDisplay_c::EffectCollectionCoinClear() { + static const int lbl_802f5cb8[] = { 0, 2, 4 }; + static const int lbl_802f5cc4[] = { 1, 3, 5 }; + + for (int i = 0; i < 3; i++) { + mpPicturePanes[lbl_802f5cb8[i]]->SetVisible(true); + if (mpPicturePanes[lbl_802f5cc4[i]]->IsVisible()) { + nw4r::lyt::Pane *icon = mpNullPanes[N_coin1st_00 + i]; + + nw4r::math::MTX34 mtx = icon->GetGlobalMtx(); + + mVec3_c tmp; + tmp.x = mtx._03; + tmp.y = mtx._13; + tmp.z = 0.0f; + dGameCom::fn_800B37E0(tmp, false); + mEf::createEffect("Wm_2d_starcoinvanish", 0, &tmp, nullptr, nullptr); + } + mpPicturePanes[lbl_802f5cc4[i]]->SetVisible(false); + } +} + +void dGameDisplay_c::EffectCollectionCoinGet(int i) { + nw4r::lyt::Pane *icon = mpNullPanes[N_coin1st_00 + i]; + + nw4r::math::MTX34 mtx = icon->GetGlobalMtx(); + + mVec3_c tmp; + tmp.x = mtx._03; + tmp.y = mtx._13; + tmp.z = 0.0f; + dGameCom::fn_800B37E0(tmp, false); + mEf::createEffect("Wm_2d_starcoinget", 0, &tmp, nullptr, nullptr); +} + +void dGameDisplay_c::setPlayNum(int *life_nums) { + static const int PANE_INDEX_TBL[PLAYER_COUNT] = { + T_left_00, T_left_01, T_left_02, T_left_03 + }; + + for (int i = 0; i < PLAYER_COUNT; i++) { + if (mPlayNum[i] == life_nums[i]) { + continue; + } + + if (mPlayNum[i] < life_nums[i]) { + Effect1UP(i); + } + if (life_nums[i] == 0) { + GrayColorSet(i); + } else if (mPlayNum[i] == 0) { + ReturnGrayColorSet(i); + } + + mPlayNum[i] = life_nums[i]; + dGameCom::LayoutDispNumber(mPlayNum[i], c_PLAYNUM_DIGIT, mpTextBoxes[PANE_INDEX_TBL[i]], false); + } +} + +void dGameDisplay_c::setCoinNum(int num_coins) { + if (!m_453 && (mCoins != num_coins)) { + mCoins = num_coins; + dGameCom::LayoutDispNumber(mCoins, c_COINNUM_DIGIT, mpTextBoxes[T_coin_00], false); + + if (num_coins || m_444 || !mFader_c::mFader->isHidden()) { + return; + } + if ( + dInfo_c::m_startGameInfo.mGameMode == dInfo_c::GAME_MODE_TITLE || + dInfo_c::m_startGameInfo.mGameMode == dInfo_c::GAME_MODE_TITLE_REPLAY + ) { + return; + } + + nw4r::lyt::Pane *pane = mpNullPanes[N_coin_01]; + + nw4r::math::MTX34 mtx = pane->GetGlobalMtx(); + + mVec3_c tmp; + tmp.x = mtx._03; + tmp.y = mtx._13; + tmp.z = 0.0f; + + dGameCom::fn_800B37E0(tmp, false); + mEf::createEffect("Wm_2d_coin100", 0, &tmp, nullptr, nullptr); + } +} + +void dGameDisplay_c::setTime(int time) { + if (mTimer == time) { + return; + } + + mTimer = time; + dGameCom::LayoutDispNumber(mTimer, c_TIME_DIGIT, mpTextBoxes[9], true); +} + +void dGameDisplay_c::setCollect() { + if (m_453) { + return; + } + + dMj2dGame_c *save = dSaveMng_c::m_instance->getSaveGame(-1); + u8 w = dScStage_c::m_instance->getCurrWorld(); + u8 l = dScStage_c::m_instance->getCurrCourse(); + if (w >= WORLD_COUNT || l >= STAGE_COUNT) { + return; + } + + if ( + dInfo_c::m_startGameInfo.mGameMode == dInfo_c::GAME_MODE_TITLE || + dInfo_c::m_startGameInfo.mGameMode == dInfo_c::GAME_MODE_TITLE_REPLAY + ) { + return; + } + + for (u32 coinIdx = 0; coinIdx < 3; coinIdx++) { + if (save->isCollectCoin(w, l, coinIdx) && (dInfo_c::m_startGameInfo.mGameMode == dInfo_c::GAME_MODE_NORMAL)) { + mpPicturePanes[P_collectOff_00 + 2 * coinIdx]->SetVisible(false); + mpPicturePanes[P_collection_00 + 2 * coinIdx]->SetVisible(true); + if (m_3EC[coinIdx] != 2) { + m_3EC[coinIdx] = 2; + } + } else if (dScStage_c::mCollectionCoin[coinIdx] != 4) { + mpPicturePanes[P_collectOff_00 + 2 * coinIdx]->SetVisible(false); + mpPicturePanes[P_collection_00 + 2 * coinIdx]->SetVisible(true); + if (m_3EC[coinIdx] != 2) { + m_3EC[coinIdx] = 2; + EffectCollectionCoinGet(coinIdx); + } + } else { + mpPicturePanes[P_collectOff_00 + 2 * coinIdx]->SetVisible(true); + mpPicturePanes[P_collection_00 + 2 * coinIdx]->SetVisible(false); + if (m_3EC[coinIdx] != 0) { + m_3EC[coinIdx] = 0; + } + } + } + mLayout.calc(); +} + +void dGameDisplay_c::setScore(int score) { + if ((mScore == score) || (mScore >= MAX_SCORE)) { + return; + } + + // Only let 1 in 3 calls to 'setScore' actually update the scrore. + if (++m_434 < 2) { + return; + } + + m_434 = 0; + mScore = score; + if (score >= MAX_SCORE) { + mScore = MAX_SCORE; + } + + dGameCom::LayoutDispNumber(mScore, c_SCORE_DIGIT, mpTextBoxes[T_score_00], true); +} + +void dGameDisplay_c::RestCoinAnimeSetup() { + if (PauseManager_c::m_OtasukeAfter) { + m_449 = 1; + } +} diff --git a/source/dol/bases/d_lytbase.cpp b/source/dol/bases/d_lytbase.cpp new file mode 100644 index 00000000..5e79e351 --- /dev/null +++ b/source/dol/bases/d_lytbase.cpp @@ -0,0 +1,297 @@ +#include +#include +#include +#include +#include + +TagProcessor_c LytBase_c::s_TagPrc; + +LytBase_c::LytBase_c() { + mAnimCount = 0; + mGroupCount = 0; +} + +LytBase_c::~LytBase_c() {} + +bool LytBase_c::build(const char *name, d2d::ResAccMult_c *resAcc) { + bool res = d2d::Multi_c::build(name, resAcc); + if (res) { + allocStringBuffer(getRootPane()); + mLayout.SetTagProcessor(&s_TagPrc); + } + return res; +} + +LytTextBox_c *LytBase_c::findTextBox(const char *name) { + return (LytTextBox_c *) d2d::Multi_c::findTextBoxByName(name); +} + +void LytBase_c::allocStringBuffer(nw4r::lyt::Pane *pane) { + nw4r::lyt::TextBox *box = nw4r::ut::DynamicCast(pane); + if (box != nullptr) { + const wchar_t *buf = box->GetStringBuffer(); + box->AllocStringBuffer(0x1ff); + if (buf != nullptr) { + box->SetString(buf, 0); + } + } + for ( + nw4r::lyt::PaneList::Iterator it = pane->GetChildList().GetBeginIter(); + it != pane->GetChildList().GetEndIter(); + it++ + ) { + allocStringBuffer(&*it); + } +} + +bool LytBase_c::ReadResourceEx(const char *name, int i, bool isLocalized) { + char resourcePath[100]; + if (isLocalized) { + char nonLocalizedPath[100] = "Layout/"; + strncat(nonLocalizedPath, name, ARRAY_MAX_STRLEN(nonLocalizedPath)); + dGameCom::AreaLanguageFolder(nonLocalizedPath, resourcePath); + } else { + memset(resourcePath, 0, sizeof(resourcePath)); + strncat(resourcePath, "Layout/", ARRAY_MAX_STRLEN(resourcePath)); + strncat(resourcePath, name, ARRAY_MAX_STRLEN(resourcePath)); + } + if (!mResAccessorLoader.requestEx(resourcePath, i)) { + return false; + } + + mpResAccessor = &mResAccessorLoader; + return true; +} + +bool LytBase_c::ReadResource(const char *name, bool isLocalized) { + return ReadResourceEx(name, 0, isLocalized); +} + +bool LytBase_c::ReadResource2(const char *name, int i) { + char resourcePath[100]; + memset(resourcePath, 0, sizeof(resourcePath)); + strncat(resourcePath, "EU/", ARRAY_MAX_STRLEN(resourcePath)); + strncat(resourcePath, "Layout/", ARRAY_MAX_STRLEN(resourcePath)); + strncat(resourcePath, name, ARRAY_MAX_STRLEN(resourcePath)); + if (!mResAccessorLoader.requestEx(resourcePath, 0)) { + return false; + } + mpResAccessor = &mResAccessorLoader; + return true; +} + +bool LytBase_c::ReadResource3(const char *name, int i) { + char resourcePath[100]; + memset(resourcePath, 0, sizeof(resourcePath)); + strncat(resourcePath, "EU/NedEU/Layout/", ARRAY_MAX_STRLEN(resourcePath)); + strncat(resourcePath, name, ARRAY_MAX_STRLEN(resourcePath)); + if (!mResAccessorLoader.requestEx(resourcePath, i)) { + return false; + } + mpResAccessor = &mResAccessorLoader; + return true; +} + +void LytBase_c::NPaneRegister(const char **paneNames, nw4r::lyt::Pane **panes, int count) { + for (int i = 0; i < count; i++) { + panes[i] = findPaneByName(paneNames[i]); + } +} + +void LytBase_c::WPaneRegister(const char **windowPaneNames, nw4r::lyt::Window **panes, int count) { + for (int i = 0; i < count; i++) { + panes[i] = findWindowByName(windowPaneNames[i]); + } +} + +void LytBase_c::PPaneRegister(const char **picPaneNames, nw4r::lyt::Picture **panes, int count) { + for (int i = 0; i < count; i++) { + panes[i] = findPictureByName(picPaneNames[i]); + } +} + +void LytBase_c::TPaneRegister(const char **textboxNames, LytTextBox_c **panes, int count) { + for (int i = 0; i < count; i++) { + panes[i] = findTextBox(textboxNames[i]); + } +} + +void LytBase_c::TPaneNameRegister(const char **textboxNames, const int *messageIDs, int messageGroup, int count) { + MsgRes_c *bmg = dMessage_c::getMesRes(); + for (int i = 0; i < count; i++) { + LytTextBox_c *box = findTextBox(textboxNames[i]); + box->setMessage(bmg, messageGroup, messageIDs[i], 0); + } +} + +void LytBase_c::AnimeResRegister(const char **animeNames, int count) { + d2d::ResAccMult_c *resAcc = mpResAccessor; + mpAnimRes = new m2d::AnmResV2_c[count]; + mAnimCount = count; + for (int i = 0; i < count; i++) { + mpAnimRes[i].create(animeNames[i], resAcc, &mLayout, true); + } +} + +void LytBase_c::GroupRegister(const char **groupNames, const int *animeIdxs, int count) { + mpAnimGroup = new m2d::AnmGroup_c[count]; + mpEnabledAnims = new bool[count]; + mGroupCount = count; + for (int i = 0; i < count; i++) { + mpAnimGroup[i].create(&mpAnimRes[animeIdxs[i]], groupNames[i]); + } +} + +void LytBase_c::AnimeStartBaseSetup(int animeIdx) { + float dummy_float = 0.5f; // [For .sdata2 ordering] + mpAnimGroup[animeIdx].setAnmEnable(true); + m2d::AnmGroup_c &animeGroup = mpAnimGroup[animeIdx]; + animeGroup.mpFrameCtrl->setFrame(0.0f); + animeGroup.updateFrame(); + mpEnabledAnims[animeIdx] = true; + mLastStartedAnimNum = animeIdx; +} + +void LytBase_c::AnimeStartSetup(int animeIdx, bool startAtEnd) { + AnimeStartBaseSetup(animeIdx); + if (startAtEnd) { + mpAnimGroup[animeIdx].setLast(); + } + mpAnimGroup[animeIdx].mpFrameCtrl->setFlags(false, false); +} + +void LytBase_c::LoopAnimeStartSetup(int animeIdx) { + AnimeStartBaseSetup(animeIdx); + mpAnimGroup[animeIdx].mpFrameCtrl->setFlags(true, false); +} + +void LytBase_c::ReverseAnimeStartSetup(int animeIdx, bool startAtEnd) { + AnimeStartBaseSetup(animeIdx); + if (startAtEnd) { + mpAnimGroup[animeIdx].mpFrameCtrl->setFlags(false, false); + mpAnimGroup[animeIdx].setEnd(); + } else { + mpAnimGroup[animeIdx].setStart(); + } + mpAnimGroup[animeIdx].mpFrameCtrl->setFlags(false, true); +} + +void LytBase_c::AnimeEndSetup(int animeIdx) { + if (mpEnabledAnims[animeIdx]) { + mpAnimGroup[animeIdx].setAnmEnable(false); + mpEnabledAnims[animeIdx] = false; + } +} + +void LytBase_c::AllAnimeEndSetup() { + for (int i = 0; i < mGroupCount; i++) { + AnimeEndSetup(i); + } + mLastStartedAnimNum = mGroupCount; +} + +void LytBase_c::AnimePlay() { + for (int i = 0; i < mGroupCount; i++) { + if (mpEnabledAnims[i]) { + if (mpAnimGroup[i].mpFrameCtrl->isStop()) { + AnimeEndSetup(i); + } else { + mpAnimGroup[i].play(); + } + } + } +} + +bool LytBase_c::isAnime(int animeIdx) { + if (animeIdx < 0) { + return mpEnabledAnims[mLastStartedAnimNum]; + } + return mpEnabledAnims[animeIdx]; +} + +bool LytBase_c::isAllAnime() { + for (int i = 0; i < mGroupCount; i++) { + if (mpEnabledAnims[i]) { + return true; + } + } + return false; +} + +void LytBase_c::SetScissorMask(const nw4r::lyt::Pane *pane, d2d::ScissorMask &scissorMask) { + nw4r::ut::Rect view = mDrawInfo.GetViewRect(); + mVec2_c paneSize; + mVec2_c pos; + mVec2_c scissorSize; + mVec2_c scale = mDrawInfo.GetLocationAdjustScale(); + + float actualScaleY = scale.y; + if (actualScaleY <= 1e-6f) { + actualScaleY = 1e-6f; + } + float height = view.GetHeight() / actualScaleY; + + float actualScaleX = scale.x; + if (actualScaleX <= 1e-6f) { + actualScaleX = 1e-6f; + } + float width = view.GetWidth() / actualScaleX; + + if (width < 0.0f) { + width *= -1.0f; + } + if (height < 0.0f) { + height *= -1.0f; + } + + mMtx_c mtx = pane->GetGlobalMtx(); + + paneSize.x = pane->GetSize().width; + paneSize.y = pane->GetSize().height; + + float ratioX = mVideo::m_video->getWidth() / width; + float ratioY = mVideo::m_video->getHeight() / height; + + float trueSizeX = mtx.m[1][1] * (paneSize.x * ratioX); + float trueSizeY = mtx.m[1][1] * (paneSize.y * ratioY); + + float translateX = mtx.m[0][3] / actualScaleX; + float translateY = mtx.m[1][3] * -1.0f; + + translateX *= ratioX; + translateY *= ratioY; + + u32 scX, scY, scW, scH; + GXGetScissor(&scX, &scY, &scW, &scH); + pos.x = scX + scW * 0.5f + (translateX - trueSizeX * 0.5f); + pos.y = scY + scH * 0.5f + (translateY - trueSizeY * 0.5f); + scissorSize.x = trueSizeX + 0.5f; + scissorSize.y = trueSizeY + 0.5f; + scissorMask.setSize(scissorSize); + scissorMask.setPos(pos); + scissorMask.mEnabled = true; +} + +bool LytBase_c::doDelete() { + if (mAnimCount != 0) { + for (int i = 0; i < mAnimCount; i++) { + if (!mpAnimRes[i].remove()) { + return false; + } + } + delete[] mpAnimRes; + mAnimCount = 0; + } + + if (mGroupCount != 0) { + delete[] mpAnimGroup; + delete[] mpEnabledAnims; + mGroupCount = 0; + } + + if (!mResAccessorLoader.remove()) { + return false; + } + + return true; +} diff --git a/source/dol/bases/d_lyttextbox.cpp b/source/dol/bases/d_lyttextbox.cpp index 45723eb2..71020691 100644 --- a/source/dol/bases/d_lyttextbox.cpp +++ b/source/dol/bases/d_lyttextbox.cpp @@ -4,14 +4,14 @@ #include #include -void LytTextBox_c::setMessage(MsgRes_c *bmg, ulong messageID, ulong messageGroup, long placeholderCount, ...) { +void LytTextBox_c::setMessage(MsgRes_c *bmg, ulong messageGroup, ulong messageID, long param, ...) { dInfo_c *info = dInfo_c::getInstance(); - info->mTextBoxMessageID = messageID; info->mTextBoxMessageGroup = messageGroup; + info->mTextBoxMessageID = messageID; va_list args; - va_start(args, placeholderCount); - setMessage(bmg, messageID, messageGroup, placeholderCount, &args); + va_start(args, param); + setMessage(bmg, messageGroup, messageID, param, &args); va_end(args); } @@ -23,10 +23,10 @@ void LytTextBox_c::ExtensionUserDataSetup() { } } -void LytTextBox_c::setMessage(MsgRes_c *bmg, ulong messageID, ulong messageGroup, long placeholderCount, va_list *vargs) { +void LytTextBox_c::setMessage(MsgRes_c *bmg, ulong messageGroup, ulong messageID, long param, va_list *vargs) { nw4r::lyt::Size fontSize = GetFontSize(); - u8 fontIndex = bmg->getFont(messageID, messageGroup); + u8 fontIndex = bmg->getFont(messageGroup, messageID); SetFont(dFontMng_c::getFont(fontIndex)); LytBase_c::s_TagPrc.mFontIndex = fontIndex; @@ -37,11 +37,11 @@ void LytTextBox_c::setMessage(MsgRes_c *bmg, ulong messageID, ulong messageGroup if (extUserDataNum != 0) { ExtensionUserDataSetup(); } - info->mTextBoxMessageID = messageID; info->mTextBoxMessageGroup = messageGroup; - setText(bmg->getMsg(messageID, messageGroup), placeholderCount, vargs, bmg); + info->mTextBoxMessageID = messageID; + setText(bmg->getMsg(messageGroup, messageID), param, vargs, bmg); - float charWScale = bmg->getScale(messageID, messageGroup) * 0.01f; + float charWScale = bmg->getScale(messageGroup, messageID) * 0.01f; fontSize.width = GetFont()->GetWidth() * charWScale; SetFontSize(fontSize); diff --git a/source/dol/bases/d_s_boot.cpp b/source/dol/bases/d_s_boot.cpp index b3df995e..fed425bc 100644 --- a/source/dol/bases/d_s_boot.cpp +++ b/source/dol/bases/d_s_boot.cpp @@ -449,7 +449,7 @@ int dScBoot_c::draw() { void dScBoot_c::initializeState_ResetWait() { mIsResetting = false; - mpWiiStrap->mLayout.mpAnimGroup->setAndUpdate(0.0f); + mpWiiStrap->mLayout.getAnmGroup(0).setAndUpdate(0.0f); } void dScBoot_c::executeState_ResetWait() { @@ -522,7 +522,7 @@ void dScBoot_c::initializeState_ResetFadeIn() { dReset::Manage_c::GetInstance()->ActiveSaveWindow(true); dFader_c::setFader(dFader_c::FADE); dFader_c::startFadeIn(30); - mpWiiStrap->mLayout.mpAnimGroup->setAndUpdate(0.0f); + mpWiiStrap->mLayout.getAnmGroup(0).setAndUpdate(0.0f); } void dScBoot_c::executeState_ResetFadeIn() { @@ -564,7 +564,7 @@ void dScBoot_c::finalizeState_FadeOutWait() {} void dScBoot_c::initializeState_WiiStrapKeyWait() { mAutoAdvanceTimer = 1200; mMinWaitTimer = 60; - mpWiiStrap->mLayout.mpAnimGroup->setAndUpdate(0.0f); + mpWiiStrap->mLayout.getAnmGroup(0).setAndUpdate(0.0f); } void dScBoot_c::executeState_WiiStrapKeyWait() { diff --git a/source/dol/mLib/m_2d.cpp b/source/dol/mLib/m_2d.cpp index e1fb226e..9c2e86a4 100644 --- a/source/dol/mLib/m_2d.cpp +++ b/source/dol/mLib/m_2d.cpp @@ -158,8 +158,8 @@ void m2d::FrameCtrl_c::play() { } else { frame += mRate; if (mFlags & NO_LOOP) { - if (frame > getLastActiveFrame()) { - frame = getLastActiveFrame(); + if (frame > getLastFrame()) { + frame = getLastFrame(); } } else if (frame >= mEndFrame) { frame -= mEndFrame; @@ -191,7 +191,7 @@ void m2d::FrameCtrl_c::setRate(float rate) { bool m2d::FrameCtrl_c::isStop() const { switch (mFlags) { case NO_LOOP: - return mCurrFrame >= getLastActiveFrame(); + return mCurrFrame >= getLastFrame(); case NO_LOOP | REVERSE: return mCurrFrame <= 0.0f; default: diff --git a/syms.txt b/syms.txt index 2a5428f6..e78a7340 100644 --- a/syms.txt +++ b/syms.txt @@ -143,6 +143,7 @@ showFukidashi__8dGameComFii=0x800B3600 hideFukidashiForLevel__8dGameComFiii=0x800B3720 hideFukidashiTemporarily__8dGameComFiii=0x800B3750 hideFukidashiForSession__8dGameComFii=0x800B3780 +fn_800B37E0__8dGameComFR7mVec3_cb=0x800B37E0 clearGameStop__8dGameComFv=0x800B3A20 setGameStop__8dGameComFv=0x800B3A30 isGameStop__8dGameComFUl=0x800B3B50 @@ -155,6 +156,7 @@ SetSoftLight_Enemy__8dGameComFRQ23m3d6bmdl_ci=0x800B4170 SetSoftLight_MapObj__8dGameComFRQ23m3d6bmdl_ci=0x800B42B0 SelectCursorSetup__8dGameComFPQ34nw4r3lyt4Paneib=0x800B44D0 GetLanguageHBM__8dGameComFv=0x800B4630 +AreaLanguageFolder__8dGameComFPCcPc=0x800B4670 PlayerEnterCheck__8dGameComFi=0x800B4760 Player1upColor__8dGameComFP12LytTextBox_ci=0x800B4780 isNowCourseClear__8dGameComFv=0x800B4E30 @@ -232,6 +234,7 @@ ScoreSet__11dScoreMng_cFR7mVec3_cUlii=0x800E2070 ScoreSet__11dScoreMng_cFP8dActor_cUliff=0x800E2190 ScoreSet2__11dScoreMng_cFR7mVec3_cUli=0x800E2310 UnKnownScoreSet__11dScoreMng_cFP8dActor_cUlff=0x800E24B0 +setTimer__13dStageTimer_cFs=0x800E3A00 setBlack__6dSys_cFb=0x800E4890 setFrameRate__6dSys_cFUc=0x800E4920 setClearColor__6dSys_cFQ34nw4r2ut5Color=0x800E4940 @@ -242,6 +245,8 @@ createEffectManagerPhase2__7dSystemFPv=0x800E5170 createFontManagerPhase__7dSystemFPv=0x800E51E0 createMessageManagerPhase__7dSystemFPv=0x800E5220 fixArena__7dSystemFv=0x800E52B0 +__ct__14TagProcessor_cFv=0x800E5510 +__dt__14TagProcessor_cFv=0x800E5590 preProcess__14TagProcessor_cFPCwPwUlPilP16__va_list_structP8MsgRes_c=0x800E72D0 create__6mVideoFv=0x800E8BC0 GetPointFromIndex__12dWmConnect_cFi=0x800F3400 @@ -338,12 +343,20 @@ create__22mDvd_mountMemArchive_cFPCcUcPQ23EGG4Heap=0x8016BE00 getArcBinary__22mDvd_mountMemArchive_cCFv=0x8016BFA0 create__16mDvd_toMainRam_cFPCcUcPQ23EGG4Heap=0x8016C0B0 createEffect__3mEfFPCcUlPC7mVec3_cPC7mAng3_cPC7mVec3_c=0x8016C9D0 +createEffect__Q23mEf8effect_cFPCci=0x8016CAA0 +createEffect__Q23mEf8effect_cFPCcUlPC7mVec3_cPC7mAng3_cPC7mVec3_c=0x8016CBF0 +createEffect__Q23mEf8effect_cFPCcUlPC6mMtx_c=0x8016CCA0 +follow__Q23mEf8effect_cFPC7mVec3_cPC7mAng3_cPC7mVec3_c=0x8016CFE0 +follow__Q23mEf8effect_cFPC6mMtx_c=0x8016D090 +cleanup__Q23mEf13levelEffect_cFv=0x8016D5F0 +createExpHeap__5mHeapFUlPQ23EGG4HeapPCcUlQ25mHeap13AllocOptBit_t=0x8016E640 create__4mPadFv=0x8016F330 beginPad__4mPadFv=0x8016F360 endPad__4mPadFv=0x8016F550 __dt__Q36nw4hbm3lyt8DrawInfoFv=0x8017F550 GetLayoutRect__Q36nw4hbm3lyt6LayoutCFv=0x80180160 startSystemSe__11SndAudioMgrFUiUl=0x801954C0 +holdSystemSe__11SndAudioMgrFUiUl=0x801954E0 startSound__14SndObjctCmnEmyFUlRCQ34nw4r4math4VEC2Ul=0x80198040 startSound__14SndObjctCmnMapFUlRCQ34nw4r4math4VEC2Ul=0x80198D70 FUN_8019d5b0__11SndSceneMgrFUc=0x8019D5B0 @@ -517,6 +530,7 @@ __dt__Q34nw4r3lyt8DrawInfoFv=0x802B4EF0 GetFrameSize__Q34nw4r3lyt13AnimTransformCFv=0x802B51E0 IsLoopData__Q34nw4r3lyt13AnimTransformCFv=0x802B51F0 __ct__Q34nw4r3lyt18AnimTransformBasicFv=0x802B5210 +__ct__Q34nw4r3lyt12AnimResourceFv=0x802B5C30 Set__Q34nw4r3lyt12AnimResourceFPCv=0x802B5C50 GetGroupNum__Q34nw4r3lyt12AnimResourceCFv=0x802B5D60 GetGroupArray__Q34nw4r3lyt12AnimResourceCFv=0x802B5D80 @@ -605,6 +619,44 @@ initialize__Q23EGG13TextureBufferFUlPQ23EGG4Heap=0x802D3780 create__Q23EGG9ExceptionFUsUsUsPQ23EGG4Heapi=0x802D7700 setPadInfo__Q23EGG9ExceptionFPCUs=0x802D77A0 getMsg__Q23EGG6MsgResFUlUl=0x802D7B50 +__ct__Q23EGG6EffectFv=0x802D7D90 +__dt__Q23EGG6EffectFv=0x802D7E10 +create__Q23EGG6EffectFv=0x802D7E70 +fade__Q23EGG6EffectFv=0x802D7F40 +followFade__Q23EGG6EffectFv=0x802D7FD0 +kill__Q23EGG6EffectFv=0x802D8040 +setDisableCalc__Q23EGG6EffectFb=0x802D80E0 +setDisableDraw__Q23EGG6EffectFb=0x802D8180 +setDisableCalcDraw__Q23EGG6EffectFb=0x802D8220 +setLife__Q23EGG6EffectFUsQ33EGG6Effect10ERecursive=0x802D82F0 +setEmitRatio__Q23EGG6EffectFfQ33EGG6Effect10ERecursive=0x802D8300 +setEmitInterval__Q23EGG6EffectFUsQ33EGG6Effect10ERecursive=0x802D8310 +setEmitEmitDiv__Q23EGG6EffectFUsQ33EGG6Effect10ERecursive=0x802D8320 +setInitVelocityRandom__Q23EGG6EffectFScQ33EGG6Effect10ERecursive=0x802D8330 +setPowerYAxis__Q23EGG6EffectFfQ33EGG6Effect10ERecursive=0x802D8340 +setPowerRadiationDir__Q23EGG6EffectFfQ33EGG6Effect10ERecursive=0x802D8350 +setPowerSpecDir__Q23EGG6EffectFfQ33EGG6Effect10ERecursive=0x802D8360 +setPowerSpecDirAdd__Q23EGG6EffectFfQ33EGG6Effect10ERecursive=0x802D8370 +setSpecDir__Q23EGG6EffectFRCQ34nw4r4math4VEC3Q33EGG6Effect10ERecursive=0x802D8380 +setSpecDirAdd__Q23EGG6EffectFRCQ34nw4r4math4VEC3Q33EGG6Effect10ERecursive=0x802D8390 +setVelocity__Q23EGG6EffectFRCQ34nw4r4math4VEC3=0x802D83A0 +setColor__Q23EGG6EffectFUcUcUcUcQ33EGG6Effect10ERecursive=0x802D8430 +setDefaultParticleSize__Q23EGG6EffectFRQ34nw4r4math4VEC2Q33EGG6Effect10ERecursive=0x802D84C0 +setParticleScale__Q23EGG6EffectFRQ34nw4r4math4VEC2Q33EGG6Effect10ERecursive=0x802D84D0 +setDefaultParticleRotate__Q23EGG6EffectFRCQ34nw4r4math4VEC3Q33EGG6Effect10ERecursive=0x802D84E0 +setParticleRotate__Q23EGG6EffectFRCQ34nw4r4math4VEC3Q33EGG6Effect10ERecursive=0x802D84F0 +setEmitterSize__Q23EGG6EffectFRCQ34nw4r4math4VEC3bQ33EGG6Effect10ERecursive=0x802D8500 +setLocalScale__Q23EGG6EffectFRCQ34nw4r4math4VEC3Q33EGG6Effect10ERecursive=0x802D8510 +setDynamicsScale__Q23EGG6EffectFRCQ34nw4r4math4VEC3PCQ34nw4r4math4VEC2=0x802D8520 +setScale__Q23EGG6EffectFf=0x802D8620 +setScale__Q23EGG6EffectFRCQ34nw4r4math4VEC3=0x802D8640 +setPos__Q23EGG6EffectFRCQ34nw4r4math4VEC3=0x802D8670 +setMtx__Q23EGG6EffectFRCQ34nw4r4math5MTX34=0x802D86A0 +setPtclAnim__Q23EGG6EffectFib=0x802D86C0 +update__Q23EGG6EffectFv=0x802D88B0 +getEffect__Q23EGG6EffectCFv=0x802D8A30 +getRootEmitter__Q23EGG6EffectCFv=0x802D8AB0 +reset__Q23EGG6EffectFv=0x802D8B30 strlen=0x802DC98C __ptmf_test=0x802DCE80 __ptmf_cmpr=0x802DCEB0 @@ -696,7 +748,9 @@ g_profile_PLAYER_ICE=0x80326960 g_profile_YOSHI=0x80326A50 g_profile_FUKIDASHI_MANAGER=0x803275E0 g_profile_GAMEDISPLAY=0x80327668 +__vt__Q23mEf13levelEffect_c=0x80329CA0 sTVModeInfo__Q23EGG6Screen=0x80350820 +mPlayerEntry__9daPyMng_c=0x80355150 mPlayerType__9daPyMng_c=0x80355160 mPlayerMode__9daPyMng_c=0x80355170 mRest__9daPyMng_c=0x80355190 @@ -716,8 +770,10 @@ mspInstance__13daPyDemoMng_c=0x80429F74 mNum__9daPyMng_c=0x80429F80 mCtrlPlrNo__9daPyMng_c=0x80429F84 mActPlayerInfo__9daPyMng_c=0x80429F88 +mScore__9daPyMng_c=0x80429FA0 m_instance__18dActorGroupIdMng_c=0x8042A010 m_instance__11dActorMng_c=0x8042A020 +m_instance__17dActorCreateMng_c=0x8042A028 mspInstance__12dAttention_c=0x8042A030 g_pSndObjEmy__6dAudio=0x8042A03C g_pSndObjMap__6dAudio=0x8042A040 @@ -732,9 +788,12 @@ ms_Instance__8dGraph_c=0x8042A238 m_instance__7dInfo_c=0x8042A25C mGameFlag__7dInfo_c=0x8042A260 m_instance__13dNandThread_c=0x8042A298 +m_instance__14PauseManager_c=0x8042A2B8 +m_OtasukeAfter__14PauseManager_c=0x8042A2C2 m_instance__8dQuake_c=0x8042A2E8 m_instance__10dSaveMng_c=0x8042A320 m_instance__11dScoreMng_c=0x8042A330 +m_instance__13dStageTimer_c=0x8042A350 isZeroWidthSpace__14TagProcessor_c=0x8042A3A8 m_instance__9daWmMap_c=0x8042A46C ms_instance__12daWmPlayer_c=0x8042A480 @@ -745,6 +804,8 @@ m_exeFrame__10dScStage_c=0x8042A4E0 m_gameMode__10dScStage_c=0x8042A4E4 m_loopType__10dScStage_c=0x8042A4E8 m_isCourseOut__10dScStage_c=0x8042A4FD +m_isStaffCredit__10dScStage_c=0x8042A4FF +m_miniGame__10dScStage_c=0x8042A500 m_KoopaJrEscape__10dScStage_c=0x8042A507 changePos__10dScStage_c=0x8042A508 m_WorldNo__9dScWMap_c=0x8042A52D