#ifndef D_A_MIDNA_H #define D_A_MIDNA_H #include "JSystem/J3DGraphBase/J3DMatBlock.h" #include "JSystem/J3DGraphAnimator/J3DMaterialAnm.h" #include "Z2AudioLib/Z2Creature.h" #include "f_op/f_op_actor.h" #include "d/d_bg_s_lin_chk.h" #include "d/d_com_inf_game.h" #include "d/d_msg_flow.h" #include "d/actor/d_a_player.h" class daKago_c; class daMidna_hio_c1 { public: /* 0x00 */ u8 forced_display; /* 0x01 */ u8 hio_priority; /* 0x02 */ s16 hair_color_1r; /* 0x04 */ s16 hair_color_1g; /* 0x06 */ s16 hair_color_1b; /* 0x08 */ s16 hair_k_color_1r; /* 0x0A */ s16 hair_k_color_1g; /* 0x0C */ s16 hair_k_color_1b; /* 0x0E */ s16 hair_k_color_2r; /* 0x10 */ s16 hair_k_color_2g; /* 0x12 */ s16 hair_k_color_2b; /* 0x14 */ f32 scale; /* 0x18 */ f32 y_pos; /* 0x1C */ f32 z_pos; }; class daMidna_hio_c0 { public: static daMidna_hio_c1 const m; }; STATIC_ASSERT(sizeof(daMidna_hio_c0::m) == 0x20); #if DEBUG class daMidna_hio_c : public JORReflexible { public: daMidna_hio_c(); void genMessage(JORMContext*); virtual ~daMidna_hio_c() {} /* 0x4 */ s8 id; /* 0x8 */ daMidna_hio_c1 m; }; #define NPC_MIDNA_HIO_CLASS daMidna_hio_c #else #define NPC_MIDNA_HIO_CLASS daMidna_hio_c0 #endif class daMidna_McaMorfCB1_c : public mDoExt_McaMorfCallBack1_c { public: int execute(u16, J3DTransformInfo*); virtual ~daMidna_McaMorfCB1_c() {} void setScale(cXyz* i_scale) { mpScale = i_scale; } /* 0x4 */ cXyz* mpScale; }; class daMidna_matAnm_c : public J3DMaterialAnm { public: void init(); void calc(J3DMaterial*) const; inline ~daMidna_matAnm_c() {} daMidna_matAnm_c() { init(); } f32* getNowOffsetXP() { return &mNowOffsetX; } f32* getNowOffsetYP() { return &mNowOffsetY; } void setNowOffsetX(f32 offsetX) { mNowOffsetX = offsetX; } void setNowOffsetY(f32 offsetY) { mNowOffsetY = offsetY; } static bool getEyeMoveFlg() { return sEyeMoveFlg; } static void offEyeMoveFlg() { sEyeMoveFlg = false; } static void onEyeMoveFlg() { sEyeMoveFlg = true; } static void setMorfFrame(u8 frame) { sMorfFrame = frame; } static void decMorfFrame() { cLib_calcTimer(&sMorfFrame); } static u8 getMorfFrame() { return sMorfFrame; } /* 0x0F4 */ f32 mOldTransX; /* 0x0F8 */ f32 mOldTransY; /* 0x0FC */ f32 mNowOffsetX; /* 0x100 */ f32 mNowOffsetY; static bool sEyeMoveFlg; static u8 sMorfFrame; }; STATIC_ASSERT(sizeof(daMidna_matAnm_c) == 0x104); struct daMidna_anmData_s { /* 0x0 */ u16 mResID; /* 0x2 */ u16 mTexID; /* 0x4 */ f32 mSoundFrame; /* 0x8 */ u32 mSoundID; }; struct daMidna_texData_s { /* 0x0 */ u16 mBtpID; /* 0x2 */ u16 mBtkID; }; class daMidna_c; typedef int (daMidna_c::*daMidna_func)(); /** * @ingroup actors-unsorted * @class daMidna_c * @brief Midna * * @details * */ class daMidna_c : public fopAc_ac_c { public: enum daMidna_ERFLG0 { ERFLG0_UNK_100 = 0x100, ERFLG0_NO_SERVICE_WAIT = 0x80, ERFLG0_UNK_40 = 0x40, ERFLG0_UNK_20 = 0x20, ERFLG0_FORCE_MORF_CANCEL = 0x10, ERFLG0_FORCE_PANIC = 8, ERFLG0_UNK_2 = 2, ERFLG0_UNK_1 = 1, }; enum daMidna_FLG0 { FLG0_NO_HAIR_LEAD = 0x80000000, FLG0_UNK_40000000 = 0x40000000, FLG0_NO_HAIR_SCALE = 0x20000000, FLG0_UNK_10000000 = 0x10000000, FLG0_PORTAL_OBJ_CALL = 0x8000000, FLG0_UNK_4000000 = 0x4000000, FLG0_UNK_2000000 = 0x2000000, FLG0_UNK_1000000 = 0x1000000, FLG0_UNK_800000 = 0x800000, FLG0_UNK_400000 = 0x400000, FLG0_UNK_200000 = 0x200000, FLG0_NPC_NEAR = 0x100000, FLG0_UNK_80000 = 0x80000, FLG0_NPC_FAR = 0x40000, FLG0_FORCE_NECK_AIM = 0x20000, FLG0_UNK_10000 = 0x10000, FLG0_UNK_8000 = 0x8000, FLG0_NO_INPUT = 0x4000, FLG0_NO_DRAW = 0x2000, FLG0_UNK_1000 = 0x1000, FLG0_WOLF_NO_POS = 0x800, FLG0_TAG_WAIT = 0x400, FLG0_UNK_200 = 0x200, FLG0_UNK_100 = 0x100, FLG0_UNK_80 = 0x80, FLG0_UNK_40 = 0x40, FLG0_UNK_20 = 0x20, FLG0_UNK_10 = 0x10, FLG0_UNK_8 = 8, FLG0_UNK_4 = 4, FLG0_UNK_2 = 2, FLG0_UNK_1 = 1, FLG0_TAG_PORTAL = FLG0_TAG_WAIT | FLG0_PORTAL_OBJ_CALL, }; enum daMidna_FLG1 { FLG1_SHADOW_NO_DRAW = 0x1000, FLG1_UNK_800 = 0x800, FLG1_UNK_400 = 0x400, FLG1_UNK_200 = 0x200, FLG1_SIDE_WARP = 0x100, FLG1_NO_MASK_DRAW = 0x80, FLG1_UNK_40 = 0x40, FLG1_UNK_20 = 0x20, FLG1_UNK_10 = 0x10, FLG1_FORCE_NORMAL_COL = 8, FLG1_FORCE_TIRED_COL = 4, FLG1_SHADOW_MODEL_DRAW_DEMO_FORCE = 2, FLG1_UNK_1 = 1, }; enum daMidna_ANM { /* 0x00 */ ANM_WAITA, /* 0x01 */ ANM_CLING, /* 0x02 */ ANM_CLINGB, /* 0x03 */ ANM_WAITB, /* 0x04 */ ANM_PANIC, /* 0x05 */ ANM_TALKA, /* 0x06 */ ANM_LEADST, /* 0x07 */ ANM_LEADED, /* 0x08 */ ANM_LEADWAIT, /* 0x09 */ ANM_LEADTOWAITA, /* 0x0A */ ANM_LEADSWAIT, /* 0x0B */ ANM_CLINGST, /* 0x0C */ ANM_SWAITB, /* 0x0D */ ANM_SWAITC, /* 0x0E */ ANM_WLDIEA, /* 0x0F */ ANM_WLSWIMDIE, /* 0x10 */ ANM_S_APPEAR, /* 0x11 */ ANM_S_APPEARBL, /* 0x12 */ ANM_S_RETURN, /* 0x13 */ ANM_S_HOLE, /* 0x14 */ ANM_WARPIN, /* 0x15 */ ANM_WAITTP, /* 0x16 */ ANM_ENTRANCE, /* 0x17 */ ANM_SWAITD, /* 0x18 */ ANM_HIT, /* 0x19 */ ANM_LOOKABOUT, /* 0x1A */ ANM_SWAITA, /* 0x1B */ ANM_S_MOVE, /* 0x1C */ ANM_RETURN, /* 0x1D */ ANM_WAITD, /* 0x1E */ ANM_CLINGD, /* 0x1F */ ANM_ROPEWAIT, /* 0x20 */ ANM_ROPEFALTER, /* 0x21 */ ANM_DIGIN, /* 0x22 */ ANM_DOOROPC, /* 0x23 */ ANM_DOOROPD, /* 0x24 */ ANM_GRAB, /* 0x25 */ ANM_GRABED, /* 0x26 */ ANM_MGNCATCHST, /* 0x27 */ ANM_MGNCATCHED, /* 0x28 */ ANM_MGNTHROWLST, /* 0x29 */ ANM_MGNTHROWLED, /* 0x2A */ ANM_MGNTHROWRST, /* 0x2B */ ANM_MGNTHROWRED, /* 0x2C */ ANM_FTALKA, /* 0x2D */ ANM_FTALKB, /* 0x2E */ ANM_FTALKC, /* 0x2F */ ANM_FTALKC2, /* 0x30 */ ANM_HAIR, /* 0x31 */ ANM_S_TAKES, /* 0x32 */ ANM_S_WAITS, /* 0x33 */ ANM_S_PACKAWAY, /* 0x34 */ ANM_GRABST, /* 0x35 */ ANM_MAX, /* 0x00 */ ANM_NONE = 0, }; void onForcePanic() { onEndResetStateFlg0(ERFLG0_FORCE_PANIC); } void onRatBody(int) { onForcePanic(); } u32 checkForceNormalColor() const { return checkStateFlg1(FLG1_FORCE_NORMAL_COL); } u32 checkForceTiredColor() const { return checkStateFlg1(FLG1_FORCE_TIRED_COL); } void onNoServiceWait() { onEndResetStateFlg0(ERFLG0_NO_SERVICE_WAIT); } int modelCallBack(int); int changeUpperBck(); int changeFaceBck(); int baseModelCallBack(int); int initInvModel(u16, J3DModel**, mDoExt_invisibleModel*, u32); int initDemoModel(J3DModel**, char const*, u32); int createHeap(); cPhs__Step create(); void allAnimePlay(); void setMatrix(); void setBodyPartMatrix(); void setRoomInfo(); void setBodyPartPos(); BOOL checkAppear(); void checkMidnaPosState(); BOOL setUpperAnime(u16, u16); BOOL setUpperAnimeAndSe(daMidna_ANM); BOOL setFaceAnime(u16, u16); void endHighModel(); BOOL setDemoAnm(); void setFaceBtp(u16, int); void setFaceBtk(u16, int); void setLeftHandShape(u16); void setRightHandShape(u16); BOOL checkHairOnlyAnime(int) const; void setBckAnime(J3DAnmTransform*, int, f32); void setAnm(); s16 getNeckAimAngle(cXyz const*, s16*, s16*, s16*, s16*); void clearEyeMove(); void setEyeMove(cXyz const*, s16, s16); void setNeckAngle(); void initHairAngle(); void setHairAngle(); void setDemoData(); J3DAnmTevRegKey* setSimpleBrk(J3DModelData*, u16); J3DAnmTextureSRTKey* setSimpleBtk(J3DModelData*, u16); void initMidnaModel(); void setMidnaNoDrawFlg(); int checkMetamorphoseEnableBase(); BOOL checkNoDrawState(); void setSound(); int execute(); int draw(); ~daMidna_c(); daMidna_c() : mBtpHeap(0x400), mBtkHeap(0x400) {} void onEndResetStateFlg0(daMidna_ERFLG0 pFlg) { mEndResetStateFlg0 |= pFlg; } void onStateFlg0(daMidna_FLG0 i_flag) { mStateFlg0 |= i_flag; } void offStateFlg0(daMidna_FLG0 i_flag) { mStateFlg0 &= ~i_flag; } void onStateFlg1(daMidna_FLG1 i_flag) { mStateFlg1 |= i_flag; } void offStateFlg1(daMidna_FLG1 i_flag) { mStateFlg1 &= ~i_flag; } u32 checkEndResetStateFlg0(daMidna_ERFLG0 flag) const { return mEndResetStateFlg0 & flag; } u32 checkStateFlg0(daMidna_FLG0 flag) const { return mStateFlg0 & flag; } u32 checkStateFlg1(daMidna_FLG1 flag) const { return mStateFlg1 & flag; } void setFaceNum(int num) { mFaceNum = num; } void setMotionNum(int num) { mMotionNum = num; } bool checkDemoTypeNone() const { return mDemoType == 0; } void changeOriginalDemo() { mDemoType = 3; } void changeDemoMode(u32 mode) { mDemoMode = mode; } BOOL checkPortalObjCall() { return checkStateFlg0(FLG0_PORTAL_OBJ_CALL); } BOOL checkNoHairScale() const { return checkStateFlg0(FLG0_NO_HAIR_SCALE); } BOOL checkNpcNear() const { return checkStateFlg0(FLG0_NPC_NEAR); } BOOL checkNpcFar() const { return checkStateFlg0(FLG0_NPC_FAR); } u32 checkNoDraw() const { return checkStateFlg0(FLG0_NO_DRAW); } BOOL checkNoInput() const { return checkStateFlg0(FLG0_NO_INPUT); } BOOL checkWolfNoPos() const { return checkStateFlg0(FLG0_WOLF_NO_POS); } int checkMetamorphoseEnable() { return (this->*mpFunc)(); } u32 checkShadowModelDrawDemoForce() const { return checkStateFlg1(FLG1_SHADOW_MODEL_DRAW_DEMO_FORCE); } void setForceNeckAimPos(const cXyz& i_pos) { onStateFlg0(FLG0_FORCE_NECK_AIM); mForceNeckAimPos = i_pos; } void onTagWaitPosWarp(const cXyz* param_0) { mTagWaitPos = *param_0; onStateFlg0(FLG0_TAG_WAIT); onEndResetStateFlg0(ERFLG0_UNK_2); } void onTagWaitPosPortalObj(const cXyz& i_pos) { mTagWaitPos = i_pos; onStateFlg0(FLG0_TAG_PORTAL); } void onTagWaitPos(const cXyz* param_0) { mTagWaitPos = *param_0; onStateFlg0(FLG0_TAG_WAIT); } void offTagWaitPos() { offStateFlg0((daMidna_FLG0)(FLG0_NO_HAIR_LEAD | FLG0_PORTAL_OBJ_CALL | FLG0_TAG_WAIT)); } void onTagNoHairLead() { onStateFlg0(FLG0_NO_HAIR_LEAD); } void onSideWarp() { onStateFlg1(FLG1_SIDE_WARP); } MtxP getMtxHairTop() { return mpShadowModel->getAnmMtx(10); } bool checkSetAnime(int param_0, daMidna_ANM i_anm) const { return mBckHeap[param_0].getIdx() == m_anmDataTable[i_anm].mResID; } bool checkReturnAnime() const { return mBckHeap[0].getIdx() == 0x1CA; } bool checkShadowModelDrawSmode() const { return field_0x84e == 3 || field_0x84e == 4 || field_0x84e == 2; } bool checkShadowModelDraw() const { return checkShadowModelDrawDemoForce() || checkShadowModelDrawSmode(); } bool checkShadowReturnEnd() const { return mBckHeap[0].getIdx() == 0x21C && mpMorf->isStop(); } bool checkShadowModeTalkWait() const { return (field_0x84e == 2 || field_0x84e == 1) ; } void setShadowReturn() { field_0x84e = 4; } bool checkPortalObjRide() const { return checkStateFlg0(FLG0_PORTAL_OBJ_CALL) && checkStateFlg0(FLG0_UNK_200); } BOOL checkShadowNoDraw() const { return checkStateFlg1(FLG1_SHADOW_NO_DRAW); } BOOL checkNoMaskDraw() const { return checkStateFlg1(FLG1_NO_MASK_DRAW); } BOOL checkDemoPortalWarpWait() const { return mDemoMode == 11; } static BOOL checkMidnaRealBody() { return dKy_darkworld_check() == true || dComIfGs_isTransformLV(3); } static bool checkMidnaTired() { /* dSv_event_flag_c::F_0250 - Cutscene - [cutscene: 21] reunion with Zelda / Midna revived (Hyrule Castle barrier appears) */ return dComIfGs_isTransformLV(3) && !dComIfGs_isEventBit(0x1E08); } void resetRatBody() {} bool checkFlyWaitAnime() const { // fakematch (doesn't match in debug) return (u16)mBckHeap[0].getIdx() == 0x1CB || ((u16)mBckHeap[0].getIdx() == 0x1C7 || (u16)mBckHeap[0].getIdx() == 0x1C8 || (u16)mBckHeap[0].getIdx() == 0x1C9); } void onForceMorfCancel() { onEndResetStateFlg0(ERFLG0_FORCE_MORF_CANCEL); } void setCargoActor(fopAc_ac_c* i_actor) { mpKago = (daKago_c*)i_actor; } void offCargoActor() { mpKago = NULL; } void onTagWaitPosPortalObj(const cXyz* i_pos) { mTagWaitPos = *i_pos; onStateFlg0(daMidna_FLG0(FLG0_PORTAL_OBJ_CALL | FLG0_TAG_WAIT)); } static u32 getOtherHeapSize() { return 0x1D0; } static daMidna_texData_s const m_texDataTable[21]; static daMidna_anmData_s const m_anmDataTable[53]; private: /* 0x568 */ request_of_phase_process_class mPhase; /* 0x570 */ J3DModel* mpModel; /* 0x574 */ J3DModel* mpShadowModel; /* 0x578 */ mDoExt_McaMorfSO* mpMorf; /* 0x57C */ daMidna_McaMorfCB1_c mMorfCB; /* 0x584 */ mDoExt_bckAnm mUpperBck; /* 0x5A0 */ mDoExt_bckAnm mFaceBck; /* 0x5BC */ J3DAnmTexPattern* mpFaceBtp; /* 0x5C0 */ J3DAnmTextureSRTKey* mpFaceBtk; /* 0x5C4 */ mDoExt_invisibleModel mInvModel; /* 0x5CC */ mDoExt_invisibleModel mMaskInvModel; /* 0x5D4 */ mDoExt_invisibleModel mHandsInvModel; /* 0x5DC */ mDoExt_invisibleModel mHairhandInvModel; /* 0x5E4 */ daPy_anmHeap_c mBckHeap[3]; /* 0x620 */ daPy_anmHeap_c mBtpHeap; /* 0x634 */ daPy_anmHeap_c mBtkHeap; /* 0x648 */ J3DAnmTextureSRTKey* mpMoyaBtk; /* 0x64C */ J3DAnmTextureSRTKey* mpMaskMoyaBtk; /* 0x650 */ J3DAnmTextureSRTKey* mpHandsMoyaBtk; /* 0x654 */ J3DAnmTextureSRTKey* mpHairhandMoyaBtk; /* 0x658 */ J3DAnmTevRegKey* mpAppearBrk; /* 0x65C */ J3DAnmTevRegKey* mpMaskAppearBrk; /* 0x660 */ J3DAnmTevRegKey* mpHairhandAppearBrk; /* 0x664 */ J3DAnmTevRegKey* mpGokouAppearBrk; /* 0x668 */ J3DAnmTevRegKey* field_0x668; /* 0x66C */ J3DAnmTevRegKey* mpDemoFCBlendBrk; /* 0x670 */ J3DModel* mpMaskBmd; /* 0x674 */ J3DModel* mpShadowMaskBmd; /* 0x678 */ J3DModel* mpHandsBmd; /* 0x67C */ J3DModel* mpShadowHandsBmd; /* 0x680 */ J3DModel* mpHairhandBmd; /* 0x684 */ J3DModel* mpShadowHairhandBmd; /* 0x688 */ J3DModel* mpDemoBDTmpBmd; /* 0x68C */ J3DModel* mpDemoBDMaskBmd; /* 0x690 */ J3DModel* mpDemoBDHandsBmd; /* 0x694 */ J3DModel* mpDemoBDHairhandBmd; /* 0x698 */ J3DModel* mpGokouBmd; /* 0x69C */ J3DShape* mpLeftHandShape; /* 0x6A0 */ J3DShape* mpRightHandShape; /* 0x6A4 */ J3DShape* mpShadowLeftHandShape; /* 0x6A8 */ J3DShape* mpShadowRightHandShape; /* 0x6AC */ J3DModel* mpDemoFCBlendBmd; /* 0x6B0 */ J3DModel* mpDemoFCTongueBmd; /* 0x6B4 */ J3DAnmTextureSRTKey* mpDemoFCTongueBtk; /* 0x6B8 */ mDoExt_bckAnm* mpDemoFCTmpBck; /* 0x6BC */ J3DDeformData* mpDemoFCTmpBls; /* 0x6C0 */ J3DAnmCluster* mpDemoFCTmpCluster; /* 0x6C4 */ mDoExt_blkAnm* mpDemoFCTmpBlk; /* 0x6C8 */ J3DModel* mpDemoHLTmpBmd; /* 0x6CC */ mDoExt_bckAnm* mpDemoHLTmpBck; /* 0x6D0 */ J3DModel* mpDemoHRTmpBmd; /* 0x6D4 */ mDoExt_bckAnm* mpDemoHRTmpBck; /* 0x6D8 */ J3DModel* mpDemoHDTmpBmd; /* 0x6DC */ mDoExt_bckAnm* mpDemoHDTmpBck; /* 0x6E0 */ J3DGXColorS10 field_0x6e0; /* 0x6E8 */ J3DGXColor field_0x6e8; /* 0x6EC */ J3DGXColor field_0x6ec; /* 0x6F0 */ daMidna_matAnm_c* mpEyeMatAnm[2]; /* 0x6F8 */ NPC_MIDNA_HIO_CLASS* mpHIO; /* 0x6FC */ Z2Creature mSound; /* 0x78C */ dMsgFlow_c mMsgFlow; /* 0x7D8 */ dBgS_LinkLinChk mLinChk; /* 0x848 */ u8 mMotionNum; /* 0x849 */ u8 mFaceNum; /* 0x84A */ u8 mFrameCounter; /* 0x84B */ u8 mFaceBckTimer; /* 0x84C */ u8 mEyeMoveTimer; /* 0x84D */ s8 mReverb; /* 0x84E */ u8 field_0x84e; /* 0x84F */ u8 mDemoType; /* 0x850 */ u8 field_0x850; /* 0x851 */ u8 field_0x851; /* 0x852 */ u8 field_0x852[0x85a - 0x852]; /* 0x85A */ s16 mPrevShapeAngleY; /* 0x85C */ s16 mHairAngleZ[5]; /* 0x866 */ s16 mHairAngleY[5]; /* 0x870 */ u8 field_0x870[0x872 - 0x870]; /* 0x872 */ s16 field_0x872; /* 0x874 */ s16 mBackboneAngleZ; /* 0x876 */ s16 mPlayerAngleY; /* 0x878 */ u16 mLeftHandShapeIdx; /* 0x87A */ u16 mRightHandShapeIdx; /* 0x87C */ s16 mDemoAngle; /* 0x87E */ s16 mJntNo; /* 0x880 */ csXyz mNeckAngle; /* 0x886 */ u8 field_0x886[0x88c - 0x886]; /* 0x88C */ int mStaffID; /* 0x890 */ u32 mStateFlg0; /* 0x894 */ u32 mStateFlg1; /* 0x898 */ u32 mEndResetStateFlg0; /* 0x89C */ u32 mShadowKey; /* 0x8A0 */ u32 mParticleKey1; /* 0x8A4 */ u32 mParticleKey2; /* 0x8A8 */ u32 mThroughEffectKey[6]; /* 0x8C0 */ u32 mDemoMode; /* 0x8C4 */ u32 mSoundID; /* 0x8C8 */ f32 mVoiceFrame; /* 0x8CC */ f32 mEyeMoveX; /* 0x8D0 */ f32 mEyeMoveY; /* 0x8D4 */ f32 field_0x8d4; /* 0x8D8 */ f32 mDemoSpeed; /* 0x8DC */ f32 field_0x8dc; /* 0x8E0 */ cXyz mHairPos[5]; /* 0x91C */ cXyz mHairDir[5]; /* 0x958 */ cXyz mHeadCenterPos; /* 0x964 */ cXyz mHairScale[5]; /* 0x9A0 */ cXyz field_0x9a0; /* 0x9AC */ cXyz mTagWaitPos; /* 0x9B8 */ cXyz mDemoPos; /* 0x9C4 */ cXyz mForceNeckAimPos; /* 0x9D0 */ daKago_c* mpKago; /* 0x9D4 */ daMidna_func mpFunc; }; STATIC_ASSERT(sizeof(daMidna_c) == 0x9E0); #endif /* D_A_MIDNA_H */