diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 3a8bba0e..25a2a6ad 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -334,7 +334,9 @@ d/lyt/meter/d_lyt_meter_z_btn.cpp: d/lyt/meter/d_lyt_meter_key.cpp: .text start:0x800E2240 end:0x800E4928 .ctors start:0x804DB6EC end:0x804DB6F0 + .rodata start:0x804E5510 end:0x804E55A0 .data start:0x80514188 end:0x805148B0 + .sdata2 start:0x80579B80 end:0x80579BA0 .bss start:0x805AA450 end:0x805AA790 d/lyt/meter/d_lyt_meter_drink.cpp: diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 86464a98..31176913 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -5513,9 +5513,9 @@ executeState_Off__20dLytMeterKakeraKey_cFv = .text:0x800E2690; // type:function finalizeState_Off__20dLytMeterKakeraKey_cFv = .text:0x800E2710; // type:function size:0x4 build__20dLytMeterKakeraKey_cFPQ23d2d10ResAccIf_c = .text:0x800E2720; // type:function size:0x1D0 remove__20dLytMeterKakeraKey_cFv = .text:0x800E28F0; // type:function size:0x58 -LytMeterKakera__update = .text:0x800E2950; // type:function size:0x218 +execute__20dLytMeterKakeraKey_cFv = .text:0x800E2950; // type:function size:0x218 draw__20dLytMeterKakeraKey_cFv = .text:0x800E2B70; // type:function size:0x28 -fn_800E2BA0 = .text:0x800E2BA0; // type:function size:0x20 +setPosition__20dLytMeterKakeraKey_cFl = .text:0x800E2BA0; // type:function size:0x20 initializeState_Wait__18dLytMeterBossKey_cFv = .text:0x800E2BC0; // type:function size:0x4 executeState_Wait__18dLytMeterBossKey_cFv = .text:0x800E2BD0; // type:function size:0x28 finalizeState_Wait__18dLytMeterBossKey_cFv = .text:0x800E2C00; // type:function size:0x4 @@ -13579,7 +13579,7 @@ AcItem__changeSlingshotSeedCount = .text:0x802521F0; // type:function size:0xC addDekuSeeds = .text:0x80252200; // type:function size:0x9C AcItem__getMaxNumberOfSlingshotSeeds = .text:0x802522A0; // type:function size:0x8 getTotalSeedCapacity__9dAcItem_cFv = .text:0x802522B0; // type:function size:0x38 -getKeyPieceCount = .text:0x802522F0; // type:function size:0x8 +getKeyPieceCount__9dAcItem_cFv = .text:0x802522F0; // type:function size:0x8 increaseKeyPieceCounter = .text:0x80252300; // type:function size:0xC getSmallKeyCounter = .text:0x80252310; // type:function size:0x8 increaseSmallKeyCounter = .text:0x80252320; // type:function size:0xC @@ -17278,7 +17278,7 @@ targetAngleY__4cLibFRC7mVec3_cRC7mVec3_c = .text:0x802E0680; // type:function si targetAngleX__4cLibFRC7mVec3_cRC7mVec3_c = .text:0x802E06A0; // type:function size:0x68 cLib__offsetPos = .text:0x802E0710; // type:function size:0xD8 fn_802E07F0 = .text:0x802E07F0; // type:function size:0x24 -fn_802E0820 = .text:0x802E0820; // type:function size:0x34 +easeOut__4cLibFff = .text:0x802E0820; // type:function size:0x34 fn_802E0860 = .text:0x802E0860; // type:function size:0x60 insertAfter__9cListMg_cFP9cListNd_cP9cListNd_c = .text:0x802E08C0; // type:function size:0x40 remove__9cListMg_cFP9cListNd_c = .text:0x802E0900; // type:function size:0xAC diff --git a/include/c/c_lib.h b/include/c/c_lib.h index ab903f08..1862235e 100644 --- a/include/c/c_lib.h +++ b/include/c/c_lib.h @@ -10,6 +10,9 @@ s32 targetAngleY(const mVec3_c &target, const mVec3_c &source); s32 targetAngleX(const mVec3_c &target, const mVec3_c &source); f32 addCalcPosXZ(mVec3_c *src, const mVec3_c &target, f32 scale, f32 maxStep, f32 minStep); +// made up name +f32 easeOut(f32 value, f32 exponent); + } // namespace cLib #endif diff --git a/include/d/a/d_a_item.h b/include/d/a/d_a_item.h index bfce4cac..45a546b9 100644 --- a/include/d/a/d_a_item.h +++ b/include/d/a/d_a_item.h @@ -59,6 +59,8 @@ public: static s32 getTotalSeedCapacity(); static s32 getTotalArrowCapacity(); + static bool getKeyPieceCount(); + static bool isRupee(ITEM_ID item); static bool isKeyPiece(ITEM_ID item); static bool isTreasure(ITEM_ID item); @@ -67,7 +69,7 @@ public: static void itemGetEventStart(dAcBase_c *); static void itemGetEventEnd(dAcBase_c *); - static void healLink(u32 amount, bool); + static void healLink(u32 amount, bool); // move to dAcPy_c private: /* 0x334 */ UNKTYPE *mpMdl; // Model has its own handling system diff --git a/include/d/lyt/meter/d_lyt_meter_key.h b/include/d/lyt/meter/d_lyt_meter_key.h index a46a48b9..a717ddd3 100644 --- a/include/d/lyt/meter/d_lyt_meter_key.h +++ b/include/d/lyt/meter/d_lyt_meter_key.h @@ -2,8 +2,9 @@ #define D_LYT_METER_KEY_H #include "d/lyt/d2d.h" +#include "m/m_vec.h" +#include "nw4r/lyt/lyt_pane.h" #include "s/s_State.hpp" -#include "s/s_StateMgr.hpp" class dLytMeterKakeraKey_c { public: @@ -12,8 +13,11 @@ public: bool build(d2d::ResAccIf_c *); bool remove(); + bool execute(); bool draw(); + void setPosition(s32 position); + private: STATE_FUNC_DECLARE(dLytMeterKakeraKey_c, Wait); STATE_FUNC_DECLARE(dLytMeterKakeraKey_c, On); @@ -23,9 +27,16 @@ private: /* 0x000 */ UI_STATE_MGR_DECLARE(dLytMeterKakeraKey_c); /* 0x03C */ d2d::dLytSub mLyt; - /* 0x0D0 */ d2d::AnmGroup_c mAnmGroups[8]; - /* 0x2D0 */ u32 field_0x2D0; - /* 0x2D4 */ mVec3_c mVecs[2]; + /* 0x0D0 */ d2d::AnmGroup_c mAnm[8]; + /* 0x2D0 */ nw4r::lyt::Pane *mpPane; + /* 0x2D4 */ mVec3_c mPanePositions[2]; + /* 0x2EC */ mVec3_c mPosition; + /* 0x2F8 */ u32 mSavedKeyPieceCount; + /* 0x2FC */ s32 mNextKeyPieceCount; + /* 0x300 */ s32 mPosititionIndex; + /* 0x304 */ s32 mOldPosititionIndex; + /* 0x308 */ s32 mMovementFrame; + /* 0x30C */ u8 mShouldBeVisible; }; class dLytMeterBossKey_c { @@ -48,7 +59,7 @@ private: /* 0x004 */ UI_STATE_MGR_DECLARE(dLytMeterBossKey_c); /* 0x040 */ d2d::dLytSub mLyt; - /* 0x0D4 */ d2d::AnmGroup_c mAnmGroups[5]; + /* 0x0D4 */ d2d::AnmGroup_c mAnm[5]; /* 0x214 */ u32 field_0x2D0; /* 0x218 */ mVec3_c mVecs[4]; }; @@ -73,7 +84,7 @@ private: /* 0x004 */ UI_STATE_MGR_DECLARE(dLytMeterSmallKey_c); /* 0x040 */ d2d::dLytSub mLyt; - /* 0x0D4 */ d2d::AnmGroup_c mAnmGroups[5]; + /* 0x0D4 */ d2d::AnmGroup_c mAnm[5]; /* 0x214 */ u32 field_0x2D0; /* 0x218 */ mVec3_c mVecs[4]; }; diff --git a/src/d/lyt/meter/d_lyt_meter_key.cpp b/src/d/lyt/meter/d_lyt_meter_key.cpp index d9bd35fc..a34f8304 100644 --- a/src/d/lyt/meter/d_lyt_meter_key.cpp +++ b/src/d/lyt/meter/d_lyt_meter_key.cpp @@ -1,5 +1,13 @@ #include "d/lyt/meter/d_lyt_meter_key.h" +#include "c/c_lib.h" +#include "common.h" +#include "d/a/d_a_item.h" +#include "d/lyt/d2d.h" +#include "m/m_vec.h" +#include "nw4r/lyt/lyt_pane.h" +#include "toBeSorted/small_sound_mgr.h" + STATE_DEFINE(dLytMeterKakeraKey_c, Wait); STATE_DEFINE(dLytMeterKakeraKey_c, On); STATE_DEFINE(dLytMeterKakeraKey_c, Increase); @@ -16,26 +24,189 @@ STATE_DEFINE(dLytMeterSmallKey_c, On); STATE_DEFINE(dLytMeterSmallKey_c, Active); STATE_DEFINE(dLytMeterSmallKey_c, Off); +static const d2d::LytBrlanMapping brlanMapKakera[] = { + { "keyKakera_00_in.brlan", "G_inOut_00"}, + {"keyKakera_00_number1.brlan", "G_number1_00"}, + {"keyKakera_00_number2.brlan", "G_number2_00"}, + {"keyKakera_00_number3.brlan", "G_number3_00"}, + {"keyKakera_00_number4.brlan", "G_number4_00"}, + {"keyKakera_00_number5.brlan", "G_number5_00"}, + { "keyKakera_00_loop.brlan", "G_loop_00"}, + { "keyKakera_00_out.brlan", "G_inOut_00"}, +}; + +#define KEY_KAKERA_ANIM_IN 0 +#define KEY_KAKERA_ANIM_NUMBER_OFFSET 1 +#define KEY_KAKERA_ANIM_LOOP 6 +#define KEY_KAKERA_ANIM_OUT 7 + +#define KEY_KAKERA_NUM_ANIMS 8 + +#define KEY_KAKERA_NUM_PIECES 5 + void dLytMeterKakeraKey_c::initializeState_Wait() {} -void dLytMeterKakeraKey_c::executeState_Wait() {} +void dLytMeterKakeraKey_c::executeState_Wait() { + if (mShouldBeVisible) { + mStateMgr.changeState(StateID_On); + } +} void dLytMeterKakeraKey_c::finalizeState_Wait() {} -void dLytMeterKakeraKey_c::initializeState_On() {} -void dLytMeterKakeraKey_c::executeState_On() {} +void dLytMeterKakeraKey_c::initializeState_On() { + mAnm[KEY_KAKERA_ANIM_IN].setAnimEnable(true); + mAnm[KEY_KAKERA_ANIM_IN].setToEnd(); + for (int i = 0; i < KEY_KAKERA_NUM_PIECES; i++) { + if (i < mSavedKeyPieceCount) { + mAnm[i + KEY_KAKERA_ANIM_NUMBER_OFFSET].setAnimEnable(true); + mAnm[i + KEY_KAKERA_ANIM_NUMBER_OFFSET].setToEnd(); + } + } + + mLyt.calc(); + + for (int i = 0; i < KEY_KAKERA_NUM_PIECES; i++) { + if (mAnm[i + KEY_KAKERA_ANIM_NUMBER_OFFSET].isEnabled()) { + mAnm[i + KEY_KAKERA_ANIM_NUMBER_OFFSET].setAnimEnable(false); + } + } + + mAnm[KEY_KAKERA_ANIM_IN].setFrame(0.0f); +} +void dLytMeterKakeraKey_c::executeState_On() { + if (mAnm[KEY_KAKERA_ANIM_IN].isEndReached()) { + mAnm[KEY_KAKERA_ANIM_IN].setAnimEnable(false); + mStateMgr.changeState(StateID_Active); + } +} void dLytMeterKakeraKey_c::finalizeState_On() {} -void dLytMeterKakeraKey_c::initializeState_Increase() {} -void dLytMeterKakeraKey_c::executeState_Increase() {} +void dLytMeterKakeraKey_c::initializeState_Increase() { + mNextKeyPieceCount = mSavedKeyPieceCount + 1; + mAnm[mNextKeyPieceCount - 1 + KEY_KAKERA_ANIM_NUMBER_OFFSET].setAnimEnable(true); + mAnm[mNextKeyPieceCount - 1 + KEY_KAKERA_ANIM_NUMBER_OFFSET].setFrame(0.0f); + mSavedKeyPieceCount = dAcItem_c::getKeyPieceCount(); + if (mSavedKeyPieceCount == KEY_KAKERA_NUM_PIECES) { + SmallSoundManager::GetInstance()->playSound(SE_S_KEY_COMPLETE); + } else { + SmallSoundManager::GetInstance()->playSound(SE_S_KEY_PARTS); + } +} +void dLytMeterKakeraKey_c::executeState_Increase() { + if (mAnm[mNextKeyPieceCount + KEY_KAKERA_ANIM_IN].isEndReached()) { + mAnm[mNextKeyPieceCount + KEY_KAKERA_ANIM_IN].setAnimEnable(false); + mNextKeyPieceCount = -1; + mStateMgr.changeState(StateID_Active); + } +} void dLytMeterKakeraKey_c::finalizeState_Increase() {} void dLytMeterKakeraKey_c::initializeState_Active() {} -void dLytMeterKakeraKey_c::executeState_Active() {} +void dLytMeterKakeraKey_c::executeState_Active() { + if (mSavedKeyPieceCount != dAcItem_c::getKeyPieceCount()) { + mStateMgr.changeState(StateID_Increase); + } else if (!mShouldBeVisible) { + mStateMgr.changeState(StateID_Off); + } +} void dLytMeterKakeraKey_c::finalizeState_Active() {} -void dLytMeterKakeraKey_c::initializeState_Off() {} -void dLytMeterKakeraKey_c::executeState_Off() {} +void dLytMeterKakeraKey_c::initializeState_Off() { + mAnm[KEY_KAKERA_ANIM_OUT].setAnimEnable(true); + mAnm[KEY_KAKERA_ANIM_OUT].setFrame(0.0f); +} +void dLytMeterKakeraKey_c::executeState_Off() { + if (mAnm[KEY_KAKERA_ANIM_OUT].isEndReached()) { + mAnm[KEY_KAKERA_ANIM_OUT].setAnimEnable(false); + mStateMgr.changeState(StateID_Wait); + } +} void dLytMeterKakeraKey_c::finalizeState_Off() {} +bool dLytMeterKakeraKey_c::build(d2d::ResAccIf_c *resAcc) { + mLyt.setResAcc(resAcc); + mLyt.build("keyKakera_00.brlyt", nullptr); + mLyt.setPriority(0x8A); + + for (int i = 0; i < KEY_KAKERA_NUM_ANIMS; i++) { + mAnm[i].init(brlanMapKakera[i].mFile, resAcc, mLyt.getLayout(), brlanMapKakera[i].mName); + mAnm[i].bind(false); + mAnm[i].setAnimEnable(false); + } + + mAnm[KEY_KAKERA_ANIM_LOOP].setAnimEnable(true); + mSavedKeyPieceCount = dAcItem_c::getKeyPieceCount(); + mNextKeyPieceCount = -1; + mpPane = mLyt.findPane("N_inOut_00"); + nw4r::lyt::Pane *positionPane = mLyt.findPane("N_keyPosition_00"); + + mPanePositions[0].copyFrom(positionPane->GetTranslate()); + mPanePositions[1].copyFrom(mpPane->GetTranslate()); + + mPosititionIndex = 1; + mOldPosititionIndex = 1; + mMovementFrame = 0; + + mPosition.copyFrom(mPanePositions[mPosititionIndex]); + mShouldBeVisible = 0; + mpPane->SetTranslate(mPosition); + + mAnm[KEY_KAKERA_ANIM_IN].setFrame(0.0f); + mAnm[KEY_KAKERA_ANIM_IN].setAnimEnable(true); + mLyt.calc(); + mAnm[KEY_KAKERA_ANIM_IN].setAnimEnable(false); + + mStateMgr.changeState(StateID_Wait); + + return true; +} + +bool dLytMeterKakeraKey_c::remove() { + for (int i = 0; i < KEY_KAKERA_NUM_ANIMS; i++) { + mAnm[i].unbind(); + mAnm[i].remove(); + } + return true; +} + +bool dLytMeterKakeraKey_c::execute() { + mStateMgr.executeState(); + if (mPosition != mPanePositions[mPosititionIndex]) { + if (mMovementFrame < 5) { + mPosition = (mPanePositions[mPosititionIndex] - mPanePositions[mOldPosititionIndex]) * + cLib::easeOut(++mMovementFrame / 5.0f, 3.0f) + + mPanePositions[mOldPosititionIndex]; + } else { + mMovementFrame = 0; + mPosition = mPanePositions[mPosititionIndex]; + } + mpPane->SetTranslate(mPosition); + } + + for (int i = 0; i < KEY_KAKERA_NUM_ANIMS; i++) { + if (mAnm[i].isEnabled()) { + mAnm[i].play(); + } + } + mLyt.calc(); + + return true; +} + +bool dLytMeterKakeraKey_c::draw() { + mLyt.addToDrawList(); + return true; +} + +void dLytMeterKakeraKey_c::setPosition(s32 position) { + if (mPosititionIndex == position) { + return; + } + + mOldPosititionIndex = mPosititionIndex; + mPosititionIndex = position; + mMovementFrame = 0; +} + void dLytMeterBossKey_c::initializeState_Wait() {} void dLytMeterBossKey_c::executeState_Wait() {} void dLytMeterBossKey_c::finalizeState_Wait() {}