diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 2c008acb..be3722f1 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -7987,7 +7987,7 @@ initializeState_EventSaveObjDecide__13dLytMapMain_cFv = .text:0x80142730; // typ executeState_EventSaveObjDecide__13dLytMapMain_cFv = .text:0x80142740; // type:function size:0x4 finalizeState_EventSaveObjDecide__13dLytMapMain_cFv = .text:0x80142750; // type:function size:0x4 checkCursorPointedAtMap__13dLytMapMain_cFv = .text:0x80142760; // type:function size:0x190 -fn_801428F0 = .text:0x801428F0; // type:function size:0xB4 +dLytMapMain_vt0x10__13dLytMapMain_cFv = .text:0x801428F0; // type:function size:0xB4 fn_801429B0 = .text:0x801429B0; // type:function size:0x1D8 fn_80142B90 = .text:0x80142B90; // type:function size:0xEC fn_80142C80__13dLytMapMain_cFl = .text:0x80142C80; // type:function size:0x8C @@ -8001,10 +8001,10 @@ fn_80143300__13dLytMapMain_cFv = .text:0x80143300; // type:function size:0x54 fn_80143360__13dLytMapMain_cFv = .text:0x80143360; // type:function size:0x1D4 checkScroll__13dLytMapMain_cFv = .text:0x80143540; // type:function size:0x374 build__9dLytMap_cFv = .text:0x801438C0; // type:function size:0x6C -fn_80143930 = .text:0x80143930; // type:function size:0x60 -fn_80143990 = .text:0x80143990; // type:function size:0x4C -fn_801439E0 = .text:0x801439E0; // type:function size:0x4C -fn_80143A30__9dLytMap_cFv = .text:0x80143A30; // type:function size:0x70 +remove__9dLytMap_cFv = .text:0x80143930; // type:function size:0x60 +execute__9dLytMap_cFv = .text:0x80143990; // type:function size:0x4C +draw__9dLytMap_cFv = .text:0x801439E0; // type:function size:0x4C +fadeOut__9dLytMap_cFv = .text:0x80143A30; // type:function size:0x70 getName__20dLytMapFloorBtnMgr_cCFv = .text:0x80143AA0; // type:function size:0x8 getLyt__20dLytMapFloorBtnMgr_cFv = .text:0x80143AB0; // type:function size:0x8 getPane__20dLytMapFloorBtnMgr_cFv = .text:0x80143AC0; // type:function size:0x8 @@ -33852,7 +33852,7 @@ __vt__57sFStateMgr_c<18dLytMapPopupInfo_c,20sStateMethodUsr_FI_c> = .data:0x8052 __vt__87sStateMgr_c<18dLytMapPopupInfo_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x80520848; // type:object size:0x30 __vt__34sFStateFct_c<18dLytMapPopupInfo_c> = .data:0x80520878; // type:object size:0x14 __vt__31sFState_c<18dLytMapPopupInfo_c> = .data:0x80520890; // type:object size:0x18 -lbl_805208A8 = .data:0x805208A8; // type:object size:0x10 +__vt__14dLytMapFader_c = .data:0x805208A8; // type:object size:0x10 __vt__20dLytMapFloorBtnMgr_c = .data:0x805208B8; // type:object size:0x38 __vt__59sFStateMgr_c<20dLytMapFloorBtnMgr_c,20sStateMethodUsr_FI_c> = .data:0x805208F0; // type:object size:0x30 __vt__89sStateMgr_c<20dLytMapFloorBtnMgr_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x80520920; // type:object size:0x30 @@ -33872,9 +33872,9 @@ __vt__55sFStateMgr_c<16dLytMapPinIcon_c,20sStateMethodUsr_FI_c> = .data:0x80520A __vt__85sStateMgr_c<16dLytMapPinIcon_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x80520AF0; // type:object size:0x30 __vt__32sFStateFct_c<16dLytMapPinIcon_c> = .data:0x80520B20; // type:object size:0x14 __vt__29sFState_c<16dLytMapPinIcon_c> = .data:0x80520B38; // type:object size:0x18 -lbl_80520B50 = .data:0x80520B50; // type:object size:0xC -lbl_80520B5C = .data:0x80520B5C; // type:object size:0xC -lbl_80520B68 = .data:0x80520B68; // type:object size:0xC +__vt__16dLytMapPutIcon_c = .data:0x80520B50; // type:object size:0xC +__vt__16LytMap0x80520B5C = .data:0x80520B5C; // type:object size:0xC +__vt__19dLytMapFootPrints_c = .data:0x80520B68; // type:object size:0xC __vt__14dLytMapPlace_c = .data:0x80520B74; // type:object size:0xC __vt__14dLytMapPopup_c = .data:0x80520B80; // type:object size:0xC __vt__16dLytMapCapture_c = .data:0x80520B8C; // type:object size:0xC @@ -35094,7 +35094,9 @@ lbl_80529098 = .data:0x80529098; // type:object size:0xC lbl_805290A4 = .data:0x805290A4; // type:object size:0x18 lbl_805290BC = .data:0x805290BC; // type:object size:0xC lbl_805290C8 = .data:0x805290C8; // type:object size:0xC -lbl_805290D4 = .data:0x805290D4; // type:object size:0x2C +lbl_805290D4 = .data:0x805290D4; // type:object size:0xB data:string +lbl_805290E0 = .data:0x805290E0; // type:object size:0xC +lbl_805290EC = .data:0x805290EC; // type:object size:0x12 data:string lbl_80529100 = .data:0x80529100; // type:object size:0xC lbl_8052910C = .data:0x8052910C; // type:object size:0x14 lbl_80529120 = .data:0x80529120; // type:object size:0x20 data:string @@ -40133,7 +40135,7 @@ lbl_80572828 = .sdata:0x80572828; // type:object size:0x8 lbl_80572830 = .sdata:0x80572830; // type:object size:0x8 lbl_80572838 = .sdata:0x80572838; // type:object size:0x8 lbl_80572840 = .sdata:0x80572840; // type:object size:0x8 -lbl_80572848 = .sdata:0x80572848; // type:object size:0x8 +lbl_80572848 = .sdata:0x80572848; // type:object size:0x6 data:string lbl_80572850 = .sdata:0x80572850; // type:object size:0x4 lbl_80572854 = .sdata:0x80572854; // type:object size:0x7 data:string lbl_8057285C = .sdata:0x8057285C; // type:object size:0x7 data:string diff --git a/include/d/d_stage_mgr.h b/include/d/d_stage_mgr.h index 65534302..68d47f3f 100644 --- a/include/d/d_stage_mgr.h +++ b/include/d/d_stage_mgr.h @@ -71,8 +71,8 @@ public: STIF_AREA_VOLCANO_NORTH = 6, STIF_AREA_LANAYRU_MINE = 7, STIF_AREA_LANAYRU_DESERT = 8, - STIF_AREA_LANAYRU_SAND_SEA = 9, - STIF_AREA_LANAYRU_CAVES = 10, + STIF_AREA_LANAYRU_CAVES = 9, + STIF_AREA_LANAYRU_SAND_SEA = 10, STIF_AREA_LANAYRU_GORGE = 11, }; diff --git a/include/d/flag/storyflag_map.h b/include/d/flag/storyflag_map.h index b7d58a31..5ebbc965 100644 --- a/include/d/flag/storyflag_map.h +++ b/include/d/flag/storyflag_map.h @@ -1155,7 +1155,7 @@ enum StoryFlags_e { /** [First Goddess Cube (Unlocks ability to skyward strike Goddess Cubes)] * Story Flag #227 (0x00E3) - JP 805ACD72 0x20 / US 805A9AF2 0x20 */ - STORYFLAG_227, + STORYFLAG_FIRST_GODDESS_CUBE, /** [Goddess Cube near Skyview Entrance] * Story Flag #228 (0x00E4) - JP 805ACD72 0x40 / US 805A9AF2 0x40 diff --git a/include/d/lyt/d_lyt_map.h b/include/d/lyt/d_lyt_map.h index f3c938ff..fedd5d13 100644 --- a/include/d/lyt/d_lyt_map.h +++ b/include/d/lyt/d_lyt_map.h @@ -11,6 +11,7 @@ #include "d/lyt/d_textbox.h" #include "d/lyt/d_window.h" #include "egg/core/eggColorFader.h" +#include "egg/core/eggFader.h" #include "m/m2d.h" #include "m/m_angle.h" #include "m/m_vec.h" @@ -140,6 +141,31 @@ struct LytMap0x80520B5C { bool field_0x05; }; + +/** 2D UI - Map - beacon preview icon following the cursor */ +class dLytMapPutIcon_c { +public: + dLytMapPutIcon_c() : mVisible(false), field_0x98(0.0f, 0.0f) {} + virtual ~dLytMapPutIcon_c() {} + + void build(d2d::ResAccIf_c *resAcc); + void remove(); + void execute(); + void draw(); + + void setPosition(const mVec2_c &pos); + void setScale(f32 scale); + + void setVisible(bool visible) { + mVisible = visible; + } + +private: + /* 0x04 */ d2d::LytBase_c mLyt; + /* 0x94 */ bool mVisible; + /* 0x98 */ mVec2_c field_0x98; +}; + struct dLytMapFloorBtnAnmGroups { /* 0x00 */ d2d::AnmGroup_c mLoop; /* 0x40 */ d2d::AnmGroup_c mOnOff; @@ -367,6 +393,35 @@ private: /* 0x712 */ bool mForceNoNav; }; +// Made up name +class dLytMapFader_c : public m2d::Base_c { +public: + dLytMapFader_c(); + virtual ~dLytMapFader_c(); + /* vt 0x0C */ virtual void draw() override; + + void calc(); + + bool isVisible() const { + return mIsVisible; + } + + void setVisible(bool v) { + mIsVisible = v; + } + + void fadeOut() { + mFader.setStatus(EGG::Fader::STATUS_PREPARE_OUT); + mFader.setFrame(15); + mFader.fadeOut(); + } + +public: + /* 0x10 */ EGG::ColorFader mFader; + /* 0x34 */ u8 _0x34[0x38 - 0x34]; + /* 0x38 */ bool mIsVisible; +}; + // Size 0x4C class dLytMapPopupInfo_c { friend class dLytMapMain_c; @@ -475,6 +530,7 @@ class dLytMapSaveObj_c { public: dLytMapSaveObj_c() : mStateMgr(*this, sStateID::null), mSelectRequest(false), mDecideRequest(false), mDecideFinished(false) {} + ~dLytMapSaveObj_c() {} STATE_FUNC_DECLARE(dLytMapSaveObj_c, Wait); STATE_FUNC_DECLARE(dLytMapSaveObj_c, ToSelect); @@ -500,30 +556,6 @@ private: /* 0x18E */ bool mDecideFinished; }; -/** 2D UI - Map - beacon preview icon following the cursor */ -class dLytMapPutIcon_c { -public: - dLytMapPutIcon_c() : mVisible(false), field_0x98(0.0f, 0.0f) {} - virtual ~dLytMapPutIcon_c() {} - - void build(d2d::ResAccIf_c *resAcc); - void remove(); - void execute(); - void draw(); - - void setPosition(const mVec2_c &pos); - void setScale(f32 scale); - - void setVisible(bool visible) { - mVisible = visible; - } - -private: - /* 0x04 */ d2d::LytBase_c mLyt; - /* 0x94 */ bool mVisible; - /* 0x98 */ mVec2_c field_0x98; -}; - class dLytMapMain_c : public m2d::Base_c { friend class dLytMap_c; @@ -819,7 +851,7 @@ private: /* 0x8D00 */ mVec3_c mMapScroll; /* 0x8D0C */ mVec3_c mPlayerPos; /* 0x8D18 */ mVec3_c field_0x8D18; - /* 0x8D24 */ mVec3_c field_0x8D24; + /* 0x8D24 */ mVec3_c mGoddessChestWorldPosition; /* 0x8D30 */ mVec2_c field_0x8D30; /* 0x8D38 */ mVec2_c field_0x8D38; /* 0x8D40 */ f32 field_0x8D40; @@ -860,19 +892,6 @@ private: /* 0x8DC8 */ dLytMapGlobal_c mGlobal; }; -// Made up name -class dLytMapFader_c : public m2d::Base_c { -public: - dLytMapFader_c(); - virtual ~dLytMapFader_c(); - /* vt 0x0C */ virtual void draw() override; - - void calc(); - -private: - /* 0x10 */ EGG::ColorFader mFader; -}; - // Size 0x91FC, inline ctor at 802ccd88 class dLytMap_c { public: @@ -903,7 +922,10 @@ public: return mMapMain.isVisibleNoIntro(); } - void build(); + bool build(); + bool remove(); + bool execute(); + bool draw(); bool isMapEventEq2Or4Or5Or6() const { return mMapMain.mMapEvent == dLytMapMain_c::MAP_EVENT_SW_BANK_SMALL || @@ -924,11 +946,13 @@ public: return mMapMain.getSaveObjDefinition(mMapMain.mMapEventArg1, statueIdx); } - void fn_80143A30(); + void fadeOut(); private: /* 0x0004 */ d2d::ResAccIf_c mResAcc; /* 0x0374 */ dLytMapMain_c mMapMain; + /* 0x91A4 */ u8 _0x91A4[0x91C0 - 0x91A4]; + /* 0x91C0 */ dLytMapFader_c mMapFader; static dLytMap_c *sInstance; }; diff --git a/src/d/lyt/d_lyt_map.cpp b/src/d/lyt/d_lyt_map.cpp index 91e459d5..ba3a0aff 100644 --- a/src/d/lyt/d_lyt_map.cpp +++ b/src/d/lyt/d_lyt_map.cpp @@ -1,8 +1,11 @@ +// clang-format off +// vtable order +#define NEED_DIRECT_FRAMECTRL_ACCESS + #include "c/c_math.h" #include "d/d_player_act.h" #include "d/snd/d_snd_player_mgr.h" #include "toBeSorted/minigame_mgr.h" -#define NEED_DIRECT_FRAMECTRL_ACCESS #include "c/c_lib.h" #include "common.h" #include "d/a/d_a_player.h" @@ -50,6 +53,8 @@ #include "toBeSorted/d_beacon.h" #include "toBeSorted/event_manager.h" +// clang-format on + struct dLytMap_HIO_c { dLytMap_HIO_c(); virtual ~dLytMap_HIO_c(); @@ -1944,7 +1949,7 @@ dLytMapMain_c::dLytMapMain_c() mShowIslandNames(false), field_0x8DBD(0), mMapChangeAlpha(0), - mIsVisible(true), + mIsVisible(false), field_0x8DC0(-1), field_0x8DC4(0) { field_0x8D78 = 0.0f; @@ -3719,6 +3724,9 @@ static const s32 sFlagsRenameMe[] = { STORYFLAG_THUNDERHEAD_ENTERED }; +extern const s32 unkPadding[]; +const s32 unkPadding[14] = {0}; + // Not sure what the second number means static const s32 sFlags2RenameMe[][2] = { { STORYFLAG_FARON_DISCOVERED, 5}, @@ -5278,8 +5286,148 @@ void dLytMapMain_c::finalizeState_EventGoddessCube_Step1() { mEventTimer = 50; } -void dLytMapMain_c::initializeState_EventGoddessCube_Step2() {} -void dLytMapMain_c::executeState_EventGoddessCube_Step2() {} +void dLytMapMain_c::initializeState_EventGoddessCube_Step2() { + dAcTbox_c *box = findGoddessChestForStoryflag(STORYFLAG_FIRST_GODDESS_CUBE); + mGoddessChestWorldPosition = box->getPosition(); + mNextMapMode = dLytMapGlobal_c::MAPMODE_ZOOM; + dLytMapGlobal_c *global = getGlobal(); + mMapScroll = global->getMapScroll(); + field_0x8D50 = global->getField_0x44(); + field_0x8D44 = global->getMapRotation(); + field_0x8D4C = fn_80142D90(mNextMapMode); + fn_80142D10(mNextMapMode, mNextMapUpDirection, field_0x8D46); + mVec3_c center = mGoddessChestWorldPosition; + mVec2_c result(0.0f, 0.0f); + global->unprojectFromMap(mMapScroll, result, field_0x8D44); + global->setMapRotationCenter(center); + + mVec3_c offset(field_0x8CD0.x * 0.5f, 0.0f, field_0x8CD0.z * 0.5f); + offset.rotY(-global->getField_0x56()); + if (offset.x < 0.0f) { + offset.x = -offset.x; + } + if (offset.z < 0.0f) { + offset.z = -offset.z; + } + + mVec3_c diff1(field_0x8CC4.x - offset.x, 0.0f, field_0x8CC4.z - offset.z); + mVec3_c diff2(field_0x8CC4.x + offset.x, 0.0f, field_0x8CC4.z + offset.z); + + if (mPlayerPos.x < diff1.x) { + mPlayerPos.x = diff1.x; + } + if (mPlayerPos.z < diff1.z) { + mPlayerPos.z = diff1.z; + } + if (mPlayerPos.x > diff2.x) { + mPlayerPos.x = diff2.x; + } + if (mPlayerPos.z > diff2.z) { + mPlayerPos.z = diff2.z; + } + const mVec3_c &c = global->getMapRotationCenter(); + fn_80143060(mPlayerPos, center, c, field_0x8D46); + mVec3_c tmp = mMapScroll; + fn_80143060(mMapScroll, tmp, c, field_0x8D44); + fn_80143060(field_0x8D18, center, global->getPlayerPos(), field_0x8D46); + + global->setMapScroll(mMapScroll); + const mVec2_c &csPos = dCsGame_c::GetInstance()->getCursorIf()->getCursorPos(); + global->unprojectFromMap(field_0x8CF4, csPos); + fn_8013FB70(field_0x8CF4, field_0x8D50 / field_0x8D4C); + mpScaleFramePane->SetVisible(true); + field_0x8C70 = 0; + if (mNextMapMode == dLytMapGlobal_c::MAPMODE_STAGE) { + global->setZoomFrame(1.0f); + global->setField_0x58(field_0x8D50 / field_0x8D4C); + } else { + global->setZoomFrame(0.0f); + global->setField_0x58(1.0f); + } + mAnmGroups[MAP_MAIN_ANIM_ROTATE].bind(false); + if (mCurrentMapMode == dLytMapGlobal_c::MAPMODE_ZOOM) { + mAnmGroups[MAP_MAIN_ANIM_ROTATE].setFrame(0.0f); + } else { + mAnmGroups[MAP_MAIN_ANIM_ROTATE].setToEnd(); + } + + if (mNextMapMode == dLytMapGlobal_c::MAPMODE_ZOOM) { + mMarkers.setIslandNamesOn(false); + } + + if (mNextMapMode == dLytMapGlobal_c::MAPMODE_STAGE) { + mMarkers.setIslandNamesOn(mShowIslandNames); + } + dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_MAP_ZOOMIN_TO_DETAIL); +} +void dLytMapMain_c::executeState_EventGoddessCube_Step2() { + dLytMapGlobal_c *global = getGlobal(); + f32 f1 = (f32)field_0x8C70 / sHio.field_0x1C; + f32 factor = cLib::easeInOut(f1, 2.0f); + + f32 f2, f3; + if (mNextMapMode == dLytMapGlobal_c::MAPMODE_STAGE) { + f32 ratio = field_0x8D50 / field_0x8D4C; + f1 = 1.0f - f1; + f2 = ratio + (1.0f - ratio) * factor; + f3 = 1.0f - factor; + } else { + f32 ratio = field_0x8D4C / field_0x8D50; + f2 = ratio + (1.0f - ratio) * (1.0f - factor); + f3 = factor; + } + global->setZoomFrame(f1); + global->setField_0x58(f2); + + // unused + mVec3_c tmp = mMapScroll; + // unused + mVec3_c tmp2 = mPlayerPos; + + // Lerps + f32 f4 = field_0x8D50 + factor * (field_0x8D4C - field_0x8D50); + global->setField_0x44(f4); + + + // TODO stack and reg swaps + global->setMapRotation(factor * mAng(field_0x8D46 - field_0x8D44) + field_0x8D44); + + f32 length = mAnmGroups[MAP_MAIN_ANIM_ROTATE].getLastFrame(); + + // unused - the f1 store is here so that the fcmpu isn't optimized away + if (field_0x8C7C - field_0x8C80) { + f1 = 0.0f; + } + + mAnmGroups[MAP_MAIN_ANIM_ROTATE].setFrame(length - f3 * length); + + global->setMapScroll(mPlayerPos + (mMapScroll - mPlayerPos) * (1.0f / (f4 / field_0x8D50)) * (1.0f - factor)); + + fn_8013FB70(field_0x8CF4, f4 / field_0x8D4C); + + mpScaleFramePane->SetVisible(true); + if (field_0x8C70 >= sHio.field_0x1C) { + mpScaleFramePane->SetVisible(false); + if (mCurrentMapMode == dLytMapGlobal_c::MAPMODE_ZOOM) { + mAnmGroups[MAP_MAIN_ANIM_ROTATE].setToEnd(); + } else { + mAnmGroups[MAP_MAIN_ANIM_ROTATE].setFrame(0.0f); + } + mLyt.calc(); + mAnmGroups[MAP_MAIN_ANIM_ROTATE].unbind(); + mMapUpDirection = mNextMapUpDirection; + global->setMapRotation(field_0x8D46); + global->setField_0x44(field_0x8D4C); + global->setMapScroll(field_0x8D18); + if (dAcPy_c::LINK != nullptr) { + global->setMapRotationCenter(global->getPlayerPos()); + } + mCurrentMapMode = mNextMapMode; + mStateMgr.changeState(StateID_EventGoddessCube_Step3); + } else { + field_0x8C70++; + } +} void dLytMapMain_c::finalizeState_EventGoddessCube_Step2() {} void dLytMapMain_c::initializeState_EventGoddessCube_Step3() {} @@ -5579,7 +5727,7 @@ void dLytMapMain_c::executeState_EventSaveObjConfirmMsgWindow() { dFader_c::FADER_GREY ); dScGame_c::GetInstance()->setTargetingScreenPrio(0x8B); - dLytMap_c::GetInstance()->fn_80143A30(); + dLytMap_c::GetInstance()->fadeOut(); mStateMgr.changeState(StateID_EventSaveObjDecide); mSaveCaption.mStateMgr.changeState(dLytMapSaveCaption_c::StateID_Out); } else { @@ -5636,12 +5784,45 @@ void dLytMapMain_c::checkCursorPointedAtMap() { mPointerCanPlaceBeacon = canPlaceBeacon; } -void dLytMap_c::build() { +dLytMap_c *dLytMap_c::sInstance; + +bool dLytMap_c::build() { d2d::setLytAllocator(); void *data = LayoutArcManager::GetInstance()->getLoadedData("Map2D"); mResAcc.attach(data, ""); mMapMain.build(); m2d::setLytAllocator(); mMapMain.setPriority(0x86); - // TODO there's another thing here at 0x91C0 + mMapFader.setPriority(0x8A); + return true; +} + +bool dLytMap_c::remove() { + d2d::setLytAllocator(); + mMapMain.remove(); + mResAcc.detach(); + dCsGame_c::GetInstance()->setPriorityDraw(0x88); + dScGame_c::GetInstance()->setTargetingScreenPrio(0x85); + return true; +} + +bool dLytMap_c::execute() { + mMapMain.execute(); + if (mMapFader.isVisible()) { + mMapFader.calc(); + } + return true; +} + +bool dLytMap_c::draw() { + mMapMain.addToDrawList(); + if (mMapFader.isVisible()) { + mMapFader.addToDrawList(); + } + return true; +} + +void dLytMap_c::fadeOut() { + mMapFader.setVisible(true); + mMapFader.fadeOut(); }