#include "d/lyt/d_lyt_draw_mark.h" #include "common.h" #include "d/d_gfx.h" #include "d/d_pad.h" #include "d/d_rumble.h" #include "d/d_sc_game.h" #include "d/flag/storyflag_manager.h" #include "d/lyt/d_lyt_control_game.h" #include "d/lyt/d_lyt_do_button.h" #include "d/snd/d_snd_bgm_mgr.h" #include "d/snd/d_snd_small_effect_mgr.h" #include "d/snd/d_snd_wzsound.h" #include "m/m_angle.h" #include "m/m_pad.h" #include "m/m_vec.h" #include "nw4r/math/math_types.h" #include "toBeSorted/arc_managers/layout_arc_manager.h" class dLytDrawMark_HIO_c { public: dLytDrawMark_HIO_c(); virtual ~dLytDrawMark_HIO_c(); /* 0x04 */ f32 field_0x04; /* 0x08 */ f32 field_0x08; /* 0x0C */ f32 field_0x0C; /* 0x10 */ f32 field_0x10; /* 0x14 */ s16 field_0x14; /* 0x16 */ u16 field_0x16; /* 0x18 */ u16 field_0x18; /* 0x1A */ s16 field_0x1A; /* 0x1C */ s16 field_0x1C; /* 0x1E */ u8 field_0x1E; }; static dLytDrawMark_HIO_c sHio; dLytDrawMark_HIO_c::dLytDrawMark_HIO_c() { field_0x14 = 10; field_0x04 = 620.0f; field_0x08 = 800.0f; field_0x0C = 35.0f; field_0x10 = 30.0f; field_0x16 = 5; field_0x1A = 10923; field_0x18 = 9000; field_0x1C = 10; field_0x1E = 0; } dLytDrawMark_HIO_c::~dLytDrawMark_HIO_c() {} STATE_DEFINE(dLytDrawMark_c, Wait); STATE_DEFINE(dLytDrawMark_c, In); STATE_DEFINE(dLytDrawMark_c, RingIn); STATE_DEFINE(dLytDrawMark_c, MoveWait); STATE_DEFINE(dLytDrawMark_c, MoveDraw); STATE_DEFINE(dLytDrawMark_c, MoveFix); STATE_DEFINE(dLytDrawMark_c, MoveEnd); STATE_DEFINE(dLytDrawMark_c, Complete); #define DRAW_MARK_ANIM_IN 0 #define DRAW_MARK_ANIM_RING_IN 1 #define DRAW_MARK_ANIM_DRAW_LINE_LOOP_OFFSET 2 #define DRAW_MARK_ANIM_BASE_LOOP 8 #define DRAW_MARK_ANIM_LINE_FIX_OFFSET 9 #define DRAW_MARK_ANIM_COMPLETE 15 #define DRAW_MARK_NUM_ANIMS 16 #define DRAW_MARK_PANE_START_OFFSET 0 #define DRAW_MARK_PANE_END_OFFSET 6 #define DRAW_MARK_PANE_RING_ALL 12 #define DRAW_MARK_NUM_PANES 13 bool dLytDrawMark_c::build(UNKWORD) { // enums cause deoptimization here... mVariant = dScGame_c::currentSpawnInfo.layer == 3 ? /* VAR_IMP_2*/ 1 : dScGame_c::currentSpawnInfo.layer == 4 ? /* VAR_IMP_3 */ 2 : /* VAR_IMP_1 */ 0; if (mVariant == VAR_IMP_2) { buildVariant02(); } else if (mVariant == VAR_IMP_3) { buildVariant03(); } else { buildVariant01(); } field_0x500 = mpPanes[0]; mLastLine = false; mNeedEnableLineLoop = false; field_0x940 = false; mForceComplete = false; mSavedLineLoopIndex = -1; field_0x8F8 = -1; mLineFixIndex = 0; field_0x944 = 0; field_0x900 = 0; mDpdPosInitTimer = 1; mSampleTimer = 0; mLineLoopIndex = 0; field_0x874.x = field_0x874.y = 0.0f; mDpdPosLastFrame.x = mDpdPosLastFrame.y = 0.0f; field_0x910 = 0.0f; field_0x914 = 0.0f; for (int i = 0; i < 10; i++) { field_0x918[i] = 0.0f; } field_0x955 = 0; field_0x956 = 0; field_0x957 = 0; for (int i = 0; i < 6; i++) { mStartPositions[i].x = mStartPositions[i].y = 0.0f; mEndPositions[i].x = mEndPositions[i].y = 0.0f; } mAnm[DRAW_MARK_ANIM_IN].setFrame(0.0f); mAnm[DRAW_MARK_ANIM_IN].setAnimEnable(true); mAnm[DRAW_MARK_ANIM_RING_IN].setFrame(0.0f); mAnm[DRAW_MARK_ANIM_RING_IN].setAnimEnable(true); mLyt.calc(); mAnm[DRAW_MARK_ANIM_IN].setAnimEnable(false); mAnm[DRAW_MARK_ANIM_RING_IN].setAnimEnable(false); mStateMgr.changeState(StateID_In); return true; } bool dLytDrawMark_c::remove() { dPad::ex_c::getInstance()->setField_0x70(); mResAcc.detach(); return true; } bool dLytDrawMark_c::execute() { dPad::ex_c::fn_80059220(); mStateMgr.executeState(); for (int i = 0; i < DRAW_MARK_NUM_ANIMS; i++) { if (mAnmCtrlInUse[i]) { if (mAnm[i].isEnabled()) { mAnm[i].play(); } } } mLyt.calc(); return true; } bool dLytDrawMark_c::draw() { mLyt.addToDrawList(); return true; } void dLytDrawMark_c::initializeState_Wait() {} void dLytDrawMark_c::executeState_Wait() {} void dLytDrawMark_c::finalizeState_Wait() {} void dLytDrawMark_c::initializeState_In() { mAnm[DRAW_MARK_ANIM_IN].setForwardOnce(); mAnm[DRAW_MARK_ANIM_IN].setToStart(); mAnm[DRAW_MARK_ANIM_IN].setAnimEnable(true); dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SEAL_APPEAR); if (mVariant == VAR_IMP_2) { dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SEAL_LINE_APPEAR_2); } else if (mVariant == VAR_IMP_3) { dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SEAL_LINE_APPEAR_3); } else { dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SEAL_LINE_APPEAR_1); } } void dLytDrawMark_c::executeState_In() { if (mAnm[DRAW_MARK_ANIM_IN].isStop2()) { mAnm[DRAW_MARK_ANIM_IN].setAnimEnable(false); mStateMgr.changeState(StateID_RingIn); } } void dLytDrawMark_c::finalizeState_In() {} void dLytDrawMark_c::initializeState_RingIn() { mAnm[DRAW_MARK_ANIM_RING_IN].setForwardOnce(); mAnm[DRAW_MARK_ANIM_RING_IN].setToStart(); mAnm[DRAW_MARK_ANIM_RING_IN].setAnimEnable(true); mAnm[DRAW_MARK_ANIM_BASE_LOOP].setAnimEnable(true); mAnm[DRAW_MARK_ANIM_BASE_LOOP].setFrame(0.0f); } void dLytDrawMark_c::executeState_RingIn() { if (mAnm[DRAW_MARK_ANIM_RING_IN].isStop2()) { mAnm[DRAW_MARK_ANIM_RING_IN].setAnimEnable(false); mNeedEnableLineLoop = true; mStateMgr.changeState(StateID_MoveWait); } } void dLytDrawMark_c::finalizeState_RingIn() {} void dLytDrawMark_c::initializeState_MoveWait() { loadPanePos(); if (mNeedEnableLineLoop) { mAnm[mLineLoopIndex + DRAW_MARK_ANIM_DRAW_LINE_LOOP_OFFSET].setAnimEnable(true); mNeedEnableLineLoop = false; } field_0x874 = mStartPositions[mLineLoopIndex]; // unused mVec2_c _ = mEndPositions[mLineLoopIndex] - mStartPositions[mLineLoopIndex]; if (mSavedLineLoopIndex == -1) { mSavedLineLoopIndex = mLineLoopIndex; } } void dLytDrawMark_c::executeState_MoveWait() { if (mAnm[mLineLoopIndex + DRAW_MARK_ANIM_DRAW_LINE_LOOP_OFFSET].getFrame() == 1.0f) { dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SEAL_LINE_BLINK); } dPad::ex_c::getInstance()->setField_0x70(sHio.field_0x18); fn_800ADC10(mVec2_c(0.0f, 0.0f)); mDpdPosScreen.x = mDpdPosScreen.y = 0.0f; mDpdPosLastFrame.set(0.0f, 0.0f); mStateMgr.changeState(StateID_MoveDraw); } void dLytDrawMark_c::finalizeState_MoveWait() {} void dLytDrawMark_c::initializeState_MoveDraw() { mDpdPosInitTimer = 1; field_0x900 = 0; field_0x914 = 0.0f; for (int i = 0; i < 10; i++) { field_0x918[i] = 0.0f; } field_0x955 = 0; field_0x956 = 0; field_0x957 = 0; } void dLytDrawMark_c::executeState_MoveDraw() { if (mAnm[mLineLoopIndex + DRAW_MARK_ANIM_DRAW_LINE_LOOP_OFFSET].getFrame() == 1.0f) { dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SEAL_LINE_BLINK); } if (mForceComplete) { mStateMgr.changeState(StateID_Complete); } else { detectSwordSwing(); } } void dLytDrawMark_c::finalizeState_MoveDraw() {} void dLytDrawMark_c::initializeState_MoveFix() { mAnm[mLineLoopIndex + DRAW_MARK_ANIM_DRAW_LINE_LOOP_OFFSET].setFrame(0.0f); mLyt.calc(); mAnm[mLineLoopIndex + DRAW_MARK_ANIM_DRAW_LINE_LOOP_OFFSET].setAnimEnable(false); dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SEAL_LINE); dRumble_c::start(dRumble_c::sRumblePreset4, dRumble_c::FLAG_SLOT0); mAnm[mLineFixIndex + DRAW_MARK_ANIM_LINE_FIX_OFFSET].setAnimEnable(true); mAnm[mLineFixIndex + DRAW_MARK_ANIM_LINE_FIX_OFFSET].setFrame(0.0f); } void dLytDrawMark_c::executeState_MoveFix() { if (mAnm[mLineFixIndex + DRAW_MARK_ANIM_LINE_FIX_OFFSET].isEndReached()) { mAnm[mLineFixIndex + DRAW_MARK_ANIM_LINE_FIX_OFFSET].setAnimEnable(false); mLineFixIndex++; if (mLineLoopIndex >= getNumLines() - 1) { mLineLoopIndex = 0; mLastLine = true; } else { mLineLoopIndex++; } mNeedEnableLineLoop = true; if (mSavedLineLoopIndex < getNumLines()) { if (mLastLine) { dLytControlGame_c::getInstance()->setDrawMarkRelated(0, 0); mStateMgr.changeState(StateID_Complete); } else { mSavedLineLoopIndex = -1; mStateMgr.changeState(StateID_MoveWait); } } } } void dLytDrawMark_c::finalizeState_MoveFix() {} void dLytDrawMark_c::initializeState_MoveEnd() { if (mLineLoopIndex >= getNumLines() - 1) { mLineLoopIndex = 0; mLastLine = true; } else { mLineLoopIndex++; } mNeedEnableLineLoop = true; } void dLytDrawMark_c::executeState_MoveEnd() { if (mSavedLineLoopIndex < getNumLines()) { if (mLastLine) { dLytControlGame_c::getInstance()->setDrawMarkRelated(0, 0); mStateMgr.changeState(StateID_Complete); } else { mSavedLineLoopIndex = -1; mStateMgr.changeState(StateID_MoveWait); } } } void dLytDrawMark_c::finalizeState_MoveEnd() {} void dLytDrawMark_c::initializeState_Complete() { static const s32 sFlags[] = { STORYFLAG_IMPRISONED_1_DEFEATED, STORYFLAG_IMPRISONED_2_DEFEATED, STORYFLAG_IMPRISONED_3_DEFEATED, }; mAnm[DRAW_MARK_ANIM_COMPLETE].setForwardOnce(); mAnm[DRAW_MARK_ANIM_COMPLETE].setToStart(); mAnm[DRAW_MARK_ANIM_COMPLETE].setAnimEnable(true); StoryflagManager::sInstance->setFlag(sFlags[mVariant]); dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_SEAL_COMPLETE); dSndBgmMgr_c::GetInstance()->stopAllBgm(30); } void dLytDrawMark_c::executeState_Complete() { if (mAnm[DRAW_MARK_ANIM_COMPLETE].isEndReached()) { mAnm[DRAW_MARK_ANIM_COMPLETE].setAnimEnable(false); field_0x940 = true; mStateMgr.changeState(StateID_Wait); } } void dLytDrawMark_c::finalizeState_Complete() {} void dLytDrawMark_c::detectSwordSwing() { dPad::ex_c::getInstance()->setField_0x70(sHio.field_0x18); mDpdPosScreen = dPad::getDpdPosScreen(); if (mDpdPosInitTimer > 0) { mDpdPosLastFrame = mDpdPosScreen; mDpdPosInitTimer--; } if (mSampleTimer > 0) { mSampleTimer--; mDpdPosLastFrame = mDpdPosScreen; } else { mVec2_c swingDir(mDpdPosScreen.x - mDpdPosLastFrame.x, mDpdPosScreen.y - mDpdPosLastFrame.y); mAng swingAngle = swingDir.ang2(); mVec2_c lineDir = mEndPositions[mLineLoopIndex] - mStartPositions[mLineLoopIndex]; mAng lineAngle = lineDir.ang2(); mVec2_c v(swingDir); v.y *= dGfx_c::getScreenAspectF(); f32 swingMag = v.length(); mAng ang2 = mAng::abs(lineAngle - swingAngle); if (field_0x910 >= sHio.field_0x08) { if (swingMag < sHio.field_0x10) { field_0x914 = 0.0f; } else { field_0x914 += swingMag; bool isSwingInRightDirection = false; if (ang2 <= sHio.field_0x1A) { isSwingInRightDirection = true; } field_0x955 = field_0x956; field_0x956 = field_0x957; field_0x957 = isSwingInRightDirection; if (field_0x914 >= sHio.field_0x04) { if (field_0x955 && field_0x956 && field_0x957) { field_0x910 = sHio.field_0x08 / 2.0f; } mStateMgr.changeState(StateID_MoveFix); return; } } } else { if (ang2 <= sHio.field_0x1A) { field_0x900++; field_0x914 += swingMag; if (field_0x900 > sHio.field_0x14) { field_0x900 = sHio.field_0x14; field_0x914 -= field_0x918[0]; for (int i = 0; i < 9; i++) { field_0x918[i] = field_0x918[i + 1]; } field_0x918[9] = swingMag; } else { s32 idx = field_0x900 - 1; field_0x918[idx] = swingMag; } if (field_0x914 >= sHio.field_0x04) { field_0x910 = 0.0f; mStateMgr.changeState(StateID_MoveFix); return; } } else { if (swingMag >= sHio.field_0x0C) { field_0x910 += swingMag - sHio.field_0x0C; if (field_0x910 >= sHio.field_0x08) { mSampleTimer = sHio.field_0x1C; } } field_0x900 = 0; field_0x914 = 0.0f; for (int i = 0; i < 10; i++) { field_0x918[i] = 0.0f; } } } fn_800ADC10(mVec2_c(0.0f, 0.0f)); mDpdPosScreen.x = mDpdPosScreen.y = 0.0f; mDpdPosLastFrame.set(0.0f, 0.0f); dLytDobutton_c::setActionTextStuff(dLytDobutton_c::ICON_2, dLytDobutton_c::ACT_DO_70, true); } } // Copied from SelectBtnHelper void dLytDrawMark_c::convertScreenPosToDpdPos(mVec2_c *pOutDpd, mVec2_c *screenPos) const { pOutDpd->x = (screenPos->x - dGfx_c::getWidth4x3LeftF()) / (dGfx_c::getWidth4x3F() * 0.5f) - 1.0f; pOutDpd->y = (screenPos->y - dGfx_c::getCurrentScreenTopF()) / (dGfx_c::getCurrentScreenHeightF() * -0.5f) - 1.0f; } // Copied from SelectBtnHelper void dLytDrawMark_c::fn_800ADC10(mVec2_c screenPos) const { mVec2_c dpdPos; convertScreenPosToDpdPos(&dpdPos, &screenPos); dPad::ex_c::getInstance()->fn_80056580(mPad::getCurrentCoreID(), dpdPos); } void dLytDrawMark_c::loadPanePos() { for (int i = 0; i < getNumLines(); i++) { nw4r::math::MTX34 mtx1 = mpPanes[i + DRAW_MARK_PANE_START_OFFSET]->GetGlobalMtx(); mStartPositions[i].set(mtx1._03, mtx1._13); nw4r::math::MTX34 mtx2 = mpPanes[i + DRAW_MARK_PANE_END_OFFSET]->GetGlobalMtx(); mEndPositions[i].set(mtx2._03, mtx2._13); } } static const d2d::LytBrlanMapping brlanMapVariant01[] = { { "drawMark_01_in.brlan", "G_inOut_00"}, { "drawMark_01_ringIn.brlan", "G_inOut_01"}, {"drawMark_01_drawLineLoop.brlan", "G_triangle_00"}, {"drawMark_01_drawLineLoop.brlan", "G_triangle_01"}, {"drawMark_01_drawLineLoop.brlan", "G_triangle_02"}, { "", ""}, { "", ""}, { "", ""}, { "drawMark_01_baseLoop.brlan", "G_baseAll_00"}, { "drawMark_01_LineFix.brlan", "G_lineFix_00"}, { "drawMark_01_LineFix.brlan", "G_lineFix_01"}, { "drawMark_01_LineFix.brlan", "G_lineFix_02"}, { "", ""}, { "", ""}, { "", ""}, { "drawMark_01_complete.brlan", "G_complete_00"}, }; static const char *sPaneNamesVariant01[] = { "N_start_03", "N_start_04", "N_start_05", nullptr, nullptr, nullptr, "N_end_01", "N_end_02", "N_end_03", nullptr, nullptr, nullptr, "N_ringAll_00", }; void dLytDrawMark_c::buildVariant01() { void *data = LayoutArcManager::GetInstance()->getLoadedData("DrawMark_01"); mResAcc.attach(data, ""); mLyt.setResAcc(&mResAcc); mLyt.build("drawMark_01.brlyt", nullptr); for (int i = 0; i < DRAW_MARK_NUM_ANIMS; i++) { if (brlanMapVariant01[i].mFile[0] == '\0') { mAnmCtrlInUse[i] = false; } else { mAnmCtrlInUse[i] = true; mAnm[i].init(brlanMapVariant01[i].mFile, &mResAcc, mLyt.getLayout(), brlanMapVariant01[i].mName); mAnm[i].bind(false); mAnm[i].setAnimEnable(false); } } for (int i = 0; i < DRAW_MARK_NUM_PANES; i++) { if (sPaneNamesVariant01[i] != nullptr) { mpPanes[i] = mLyt.findPane(sPaneNamesVariant01[i]); } else { mpPanes[i] = nullptr; } } } static const d2d::LytBrlanMapping brlanMapVariant02[] = { { "drawMark_02_in.brlan", "G_inOut_00"}, { "drawMark_02_ringIn.brlan", "G_inOut_01"}, {"drawMark_02_drawLineLoop.brlan", "G_triangle_00"}, {"drawMark_02_drawLineLoop.brlan", "G_triangle_01"}, {"drawMark_02_drawLineLoop.brlan", "G_triangle_02"}, {"drawMark_02_drawLineLoop.brlan", "G_triangle_03"}, { "", ""}, { "", ""}, { "drawMark_02_baseLoop.brlan", "G_baseAll_00"}, { "drawMark_02_LineFix.brlan", "G_lineFix_00"}, { "drawMark_02_LineFix.brlan", "G_lineFix_01"}, { "drawMark_02_LineFix.brlan", "G_lineFix_02"}, { "drawMark_02_LineFix.brlan", "G_lineFix_03"}, { "", ""}, { "", ""}, { "drawMark_02_complete.brlan", "G_complete_00"}, }; static const char *sPaneNamesVariant02[] = { "N_start_00", "N_start_01", "N_start_02", "N_start_03", nullptr, nullptr, "N_end_01", "N_end_02", "N_end_03", "N_end_04", nullptr, nullptr, "N_ringAll_00", }; void dLytDrawMark_c::buildVariant02() { void *data = LayoutArcManager::GetInstance()->getLoadedData("DrawMark_02"); mResAcc.attach(data, ""); mLyt.setResAcc(&mResAcc); mLyt.build("drawMark_02.brlyt", nullptr); for (int i = 0; i < DRAW_MARK_NUM_ANIMS; i++) { if (brlanMapVariant02[i].mFile[0] == '\0') { mAnmCtrlInUse[i] = false; } else { mAnmCtrlInUse[i] = true; mAnm[i].init(brlanMapVariant02[i].mFile, &mResAcc, mLyt.getLayout(), brlanMapVariant02[i].mName); mAnm[i].bind(false); mAnm[i].setAnimEnable(false); } } for (int i = 0; i < DRAW_MARK_NUM_PANES; i++) { if (sPaneNamesVariant02[i] != nullptr) { mpPanes[i] = mLyt.findPane(sPaneNamesVariant02[i]); } else { mpPanes[i] = nullptr; } } } static const d2d::LytBrlanMapping brlanMapVariant03[] = { { "drawMark_03_in.brlan", "G_inOut_00"}, { "drawMark_03_ringIn.brlan", "G_inOut_01"}, {"drawMark_03_drawLineLoop.brlan", "G_triangle_00"}, {"drawMark_03_drawLineLoop.brlan", "G_triangle_01"}, {"drawMark_03_drawLineLoop.brlan", "G_triangle_02"}, {"drawMark_03_drawLineLoop.brlan", "G_triangle_03"}, {"drawMark_03_drawLineLoop.brlan", "G_triangle_04"}, {"drawMark_03_drawLineLoop.brlan", "G_triangle_05"}, { "drawMark_03_baseLoop.brlan", "G_baseAll_00"}, { "drawMark_03_LineFix.brlan", "G_lineFix_00"}, { "drawMark_03_LineFix.brlan", "G_lineFix_01"}, { "drawMark_03_LineFix.brlan", "G_lineFix_02"}, { "drawMark_03_LineFix.brlan", "G_lineFix_03"}, { "drawMark_03_LineFix.brlan", "G_lineFix_04"}, { "drawMark_03_LineFix.brlan", "G_lineFix_05"}, { "drawMark_03_complete.brlan", "G_complete_00"}, }; static const char *sPaneNamesVariant03[] = { "N_start_00", "N_start_01", "N_start_02", "N_start_03", "N_start_04", "N_start_05", "N_end_01", "N_end_02", "N_end_03", "N_end_04", "N_end_05", "N_end_06", "N_ringAll_00", }; void dLytDrawMark_c::buildVariant03() { void *data = LayoutArcManager::GetInstance()->getLoadedData("DrawMark_03"); mResAcc.attach(data, ""); mLyt.setResAcc(&mResAcc); mLyt.build("drawMark_03.brlyt", nullptr); for (int i = 0; i < DRAW_MARK_NUM_ANIMS; i++) { if (brlanMapVariant03[i].mFile[0] == '\0') { mAnmCtrlInUse[i] = false; } else { mAnmCtrlInUse[i] = true; mAnm[i].init(brlanMapVariant03[i].mFile, &mResAcc, mLyt.getLayout(), brlanMapVariant03[i].mName); mAnm[i].bind(false); mAnm[i].setAnimEnable(false); } } for (int i = 0; i < DRAW_MARK_NUM_PANES; i++) { if (sPaneNamesVariant03[i] != nullptr) { mpPanes[i] = mLyt.findPane(sPaneNamesVariant03[i]); } else { mpPanes[i] = nullptr; } } } s32 dLytDrawMark_c::getNumLines() const { if (mVariant == VAR_IMP_2) { return 4; } else if (mVariant == VAR_IMP_3) { return 6; } else { return 3; } }