diff --git a/config/D44J01/config.yml b/config/D44J01/config.yml index 3b33821c7..2735ec91f 100644 --- a/config/D44J01/config.yml +++ b/config/D44J01/config.yml @@ -1564,6 +1564,18 @@ modules: symbols: config/D44J01/rels/d_a_goal_flag/symbols.txt # map: orig/D44J01/files/maps/d_a_goal_flag.map ldscript_template: config/GZLE01/rels/ldscript.tpl + extract: + - symbol: l_txa_dummy_hataTEX + binary: assets/l_txa_dummy_hataTEX.bin + header: assets/l_txa_dummy_hataTEX.h + - symbol: l_goal_flag_DL + binary: assets/l_goal_flag_DL.bin + header: assets/l_goal_flag_DL.h + - symbol: l_goal_flag_matDL + binary: assets/l_goal_flag_matDL.bin + header: assets/l_goal_flag_matDL.h + header_type: none + custom_type: matDL - object: files/rels/d_a_gy.rel hash: c211c153be3b6349186f77d84bc86b13b66aa139 diff --git a/config/GZLE01/config.yml b/config/GZLE01/config.yml index b53089636..9dbf1c4c0 100644 --- a/config/GZLE01/config.yml +++ b/config/GZLE01/config.yml @@ -1353,6 +1353,18 @@ modules: splits: config/GZLE01/rels/d_a_goal_flag/splits.txt symbols: config/GZLE01/rels/d_a_goal_flag/symbols.txt ldscript_template: config/GZLE01/rels/ldscript.tpl + extract: + - symbol: l_txa_dummy_hataTEX + binary: assets/l_txa_dummy_hataTEX.bin + header: assets/l_txa_dummy_hataTEX.h + - symbol: l_goal_flag_DL + binary: assets/l_goal_flag_DL.bin + header: assets/l_goal_flag_DL.h + - symbol: l_goal_flag_matDL + binary: assets/l_goal_flag_matDL.bin + header: assets/l_goal_flag_matDL.h + header_type: none + custom_type: matDL - object: files/rels/d_a_gy.rel hash: 6acc3205358c2770f479b59e282a84e1826874ab diff --git a/config/GZLJ01/config.yml b/config/GZLJ01/config.yml index 928b882f2..79601b19e 100644 --- a/config/GZLJ01/config.yml +++ b/config/GZLJ01/config.yml @@ -1135,6 +1135,18 @@ modules: splits: config/GZLJ01/rels/d_a_goal_flag/splits.txt symbols: config/GZLJ01/rels/d_a_goal_flag/symbols.txt ldscript_template: config/GZLE01/rels/ldscript.tpl + extract: + - symbol: l_txa_dummy_hataTEX + binary: assets/l_txa_dummy_hataTEX.bin + header: assets/l_txa_dummy_hataTEX.h + - symbol: l_goal_flag_DL + binary: assets/l_goal_flag_DL.bin + header: assets/l_goal_flag_DL.h + - symbol: l_goal_flag_matDL + binary: assets/l_goal_flag_matDL.bin + header: assets/l_goal_flag_matDL.h + header_type: none + custom_type: matDL - object: files/rels/d_a_gy.rel splits: config/GZLJ01/rels/d_a_gy/splits.txt diff --git a/config/GZLP01/config.yml b/config/GZLP01/config.yml index 5e7c47069..d9bdc54cb 100644 --- a/config/GZLP01/config.yml +++ b/config/GZLP01/config.yml @@ -1135,6 +1135,18 @@ modules: splits: config/GZLP01/rels/d_a_goal_flag/splits.txt symbols: config/GZLP01/rels/d_a_goal_flag/symbols.txt ldscript_template: config/GZLE01/rels/ldscript.tpl + extract: + - symbol: l_txa_dummy_hataTEX + binary: assets/l_txa_dummy_hataTEX.bin + header: assets/l_txa_dummy_hataTEX.h + - symbol: l_goal_flag_DL + binary: assets/l_goal_flag_DL.bin + header: assets/l_goal_flag_DL.h + - symbol: l_goal_flag_matDL + binary: assets/l_goal_flag_matDL.bin + header: assets/l_goal_flag_matDL.h + header_type: none + custom_type: matDL - object: files/rels/d_a_gy.rel splits: config/GZLP01/rels/d_a_gy/splits.txt diff --git a/configure.py b/configure.py index 25c8a8771..91a66f0a6 100755 --- a/configure.py +++ b/configure.py @@ -1599,7 +1599,7 @@ config.libs = [ ActorRel(NonMatching, "d_a_fm"), ActorRel(NonMatching, "d_a_gm"), ActorRel(NonMatching, "d_a_gnd"), - ActorRel(NonMatching, "d_a_goal_flag"), + ActorRel(Matching, "d_a_goal_flag"), ActorRel(NonMatching, "d_a_gy"), ActorRel(NonMatching, "d_a_icelift"), ActorRel(NonMatching, "d_a_kb"), diff --git a/include/d/actor/d_a_goal_flag.h b/include/d/actor/d_a_goal_flag.h index eae78ac0d..8b4a3df5b 100644 --- a/include/d/actor/d_a_goal_flag.h +++ b/include/d/actor/d_a_goal_flag.h @@ -1,50 +1,153 @@ #ifndef D_A_GOAL_FLAG_H #define D_A_GOAL_FLAG_H +#include "JSystem/J3DGraphBase/J3DPacket.h" #include "f_op/f_op_actor.h" +#include "m_Do/m_Do_ext.h" -class daGoal_Flag_c : public fopAc_ac_c { +class dPath; + +class daGFlag_HIO_c { public: - inline cPhs_State _create(); - inline bool _delete(); - inline bool _draw(); - inline bool _execute(); - void getRopePos(int, int) {} - void setAction(int (daGoal_Flag_c::*)()) {} + daGFlag_HIO_c() { + m04 = -1; // Unused HIO field + mDrawCelShaded = true; + m07 = 0; // Unused HIO field + m06 = 0; // Unused HIO field + m08 = 0; // Unused HIO field + mWindScalePhaseInc = 0x2ee; + mNormalFlutterPhaseInc = 0x800; + mFlagWavePhaseInc = 0xbd1; + mTimeLimit = 240; // In seconds; 4 minutes - void getRacePath(unsigned char); - void RopeMove(); - void CreateBuoyRaces(); - void goal_check(); - void flag_move(); - void get_cloth_anim_factor(cXyz*, cXyz*, cXyz*, int, int); - void CreateHeap(); - void getDemoAction(int); - void RaceStart(); - void TimerExecute(); - void RaceEnd(); + // Maximum amount of rupees you can get in these minigames + mPerfectRupeeScore = 150; + // How long the player must wait until they can end the results screen; 5 seconds (150 frames) + mEndCamEarlyFrame = 150; + + m09 = 0; // Unused HIO field + mWindScale1 = 12.0f; + mWindScale2 = 4.0f; + mFlagSagFactor = -1.0f; + mClothStiffness = 0.4f; + mRopeColorR = 0xff; + mRopeColorG = 0x80; + mRopeColorB = 0x80; + } + inline virtual ~daGFlag_HIO_c(); public: - /* Place member variables here */ -}; + /* 0x04 */ s8 m04; + /* 0x05 */ bool mDrawCelShaded; + /* 0x06 */ s8 m06; + /* 0x07 */ s8 m07; + /* 0x08 */ s8 m08; + /* 0x09 */ s8 m09; + /* 0x0A */ /* 2 bytes of alignment padding */ + /* 0x0C */ u32 mWindScalePhaseInc; + /* 0x10 */ u32 mNormalFlutterPhaseInc; + /* 0x14 */ u32 mFlagWavePhaseInc; + /* 0x18 */ u32 mTimeLimit; + /* 0x1C */ s32 mPerfectRupeeScore; + /* 0x20 */ s32 mEndCamEarlyFrame; + /* 0x24 */ u32 mRopeColorR; + /* 0x28 */ u32 mRopeColorG; + /* 0x2C */ u32 mRopeColorB; + /* 0x30 */ f32 mWindScale1; + /* 0x34 */ f32 mWindScale2; + /* 0x38 */ f32 mFlagSagFactor; + /* 0x3C */ f32 mClothStiffness; +}; // Size: 0x40 +STATIC_ASSERT(sizeof(daGFlag_HIO_c) == 0x40); -class daGFlag_packet_c { +class daGFlag_packet_c : public J3DPacket { public: - void changeCurrentPos() {} - void getDPos() {} - void getMtx() {} - void getNrm() {} - void getOffsetVec() {} - void getPos() {} - void getTexObjP() {} - void getToonTexObjP() {} - void setTevStr(dKy_tevstr_c*) {} + daGFlag_packet_c() { + mCurrArr = 0; + mNormalFlutterPhase = 0; + } + virtual ~daGFlag_packet_c() {} + void changeCurrentPos() { mCurrArr ^= 1; } + cXyz* getDPos() { return mDPos[mCurrArr]; } + MtxP getMtx() { return mMtx; } + cXyz* getNrm() { return mNrm[mCurrArr]; } + cXyz* getOffsetVec() { return mVelocity; } + cXyz* getPos() { return mPos[mCurrArr]; } + GXTexObj* getTexObjP() { return &mTexObj; } + GXTexObj* getToonTexObjP() { return &mToonTexObj; } + void setTevStr(dKy_tevstr_c* i_tevStr_p) { mpTevStr = i_tevStr_p; } + cXyz* getBackNrm() { return mBackNrm[mCurrArr]; } void setTexObj(unsigned char); void setToonTexObj(); void draw(); void setBackNrm(); void setNrmVtx(cXyz*, int, int); -}; +public: + /* 0x0010 */ s16 mNormalFlutterPhase; + /* 0x0012 */ s16 mFlagWavePhase; + /* 0x0014 */ GXTexObj mTexObj; + /* 0x0034 */ GXTexObj mToonTexObj; + /* 0x0054 */ Mtx mMtx; + /* 0x0084 */ dKy_tevstr_c* mpTevStr; + /* 0x0088 */ cXyz mPos[2][45]; + /* 0x04C0 */ cXyz mDPos[2][45]; + /* 0x08F8 */ cXyz mNrm[2][45]; + /* 0x0D30 */ cXyz mBackNrm[2][45]; + /* 0x1168 */ cXyz mVelocity[45]; + /* 0x1384 */ u8 mCurrArr; + /* 0x1385 */ /* 3 bytes of alignment padding */ +}; // Size: 0x1388 +STATIC_ASSERT(sizeof(daGFlag_packet_c) == 0x1388); + +class daGoal_Flag_c : public fopAc_ac_c { +public: + typedef BOOL (daGoal_Flag_c::*ProcFunc)(); + +public: + inline cPhs_State _create(); + inline bool _delete(); + inline bool _draw(); + inline bool _execute(); + cXyz* getRopePos(int i_matIdx, int i_segmentIdx) { + return &mRopeLines[i_matIdx].getPos(0)[i_segmentIdx * 4]; + } + void setAction(ProcFunc i_proc) { mCurrProc = i_proc; } + + BOOL getRacePath(u8); + void RopeMove(); + BOOL CreateBuoyRaces(); + int goal_check(); + void flag_move(); + cXyz get_cloth_anim_factor(cXyz*, cXyz*, cXyz*, int, int); + BOOL CreateHeap(); + int getDemoAction(int); + BOOL RaceStart(); + BOOL TimerExecute(); + BOOL RaceEnd(); + +public: + /* 0x0290 */ daGFlag_packet_c mFlagPacket; + /* 0x1618 */ request_of_phase_process_class mClothPhs; + /* 0x1620 */ request_of_phase_process_class mFlagPhs; + /* 0x1628 */ Mtx mMtx; + /* 0x1658 */ cXyz mGoalFlagPolePos[2]; + /* 0x1670 */ s16 mWindScalePhase; + /* 0x1672 */ /* 2 bytes of alignment padding */ + /* 0x1674 */ fpc_ProcID mTimerProcID; + /* 0x1678 */ fpc_ProcID mMgameStartProcID; + /* 0x167C */ fpc_ProcID mMgameTermProcID; + /* 0x1680 */ f32 mPrevPlayerLineSide; + /* 0x1684 */ s16 mRaceEndState; + /* 0x1686 */ s16 mCamFramesPassed; + /* 0x1688 */ u8 mRaceStartState; + /* 0x1689 */ /* 3 bytes of alignment padding */ + /* 0x168C */ dPath* mpRopePaths[4]; + /* 0x169C */ s32 mNumRopeBuoys[4]; + /* 0x16AC */ s32 mNumRopes; + /* 0x16B0 */ mDoExt_3DlineMat0_c mRopeLines[4]; + /* 0x1720 */ ProcFunc mCurrProc; +}; // Size: 0x172C +STATIC_ASSERT(sizeof(daGoal_Flag_c) == 0x172C); #endif /* D_A_GOAL_FLAG_H */ diff --git a/include/d/d_com_inf_game.h b/include/d/d_com_inf_game.h index 5ad270405..51890c018 100644 --- a/include/d/d_com_inf_game.h +++ b/include/d/d_com_inf_game.h @@ -584,6 +584,7 @@ public: mMinigameFlags ^= 1 << (i_gameType - 1); // toggle Nth bit mMinigameResult = 0; } + u8 getMiniGameResult() { return mMinigameResult; } void setMiniGameResult(u8 i_result) { mMinigameResult = i_result; } @@ -2687,6 +2688,10 @@ inline void dComIfGp_setMiniGameResult(u8 result) { g_dComIfG_gameInfo.play.setMiniGameResult(result); } +inline u8 dComIfGp_getMiniGameResult() { + return g_dComIfG_gameInfo.play.getMiniGameResult(); +} + enum dActionStatus_e { /* 0x00 */ dActStts_BLANK_e, /* 0x01 */ dActStts_LOOK_e, // "Look" diff --git a/include/d/d_minigame_starter.h b/include/d/d_minigame_starter.h index 0dcf993b7..fba8c557a 100644 --- a/include/d/d_minigame_starter.h +++ b/include/d/d_minigame_starter.h @@ -2,6 +2,7 @@ #define D_MINIGAME_STARTER_H #include "dolphin/types.h" +#include "f_op/f_op_msg.h" class JKRArchive; struct fopMsgM_pane_class; @@ -18,16 +19,20 @@ public: void draw(); }; -class dMinigame_Starter_c { +class dMinigame_Starter_c : public msg_class { public: - void countStart() {} + void countStart() { if (!field_0x111) field_0x111 = true; } void _create(); void _execute(); void _draw(); void _delete(); - void startCheck(); - void deleteCheck(); -}; + BOOL startCheck(); + BOOL deleteCheck(); +public: + /* 0x0FC */ u8 field_0x0FC[0x111 - 0x0FC]; + /* 0x111 */ bool field_0x111; + /* 0x112 */ u8 field_0x112[0x114 - 0x112]; +}; // Size: 0x114 #endif /* D_MINIGAME_STARTER_H */ diff --git a/include/f_op/f_op_msg_mng.h b/include/f_op/f_op_msg_mng.h index 9d428f872..a6bd7d326 100644 --- a/include/f_op/f_op_msg_mng.h +++ b/include/f_op/f_op_msg_mng.h @@ -323,7 +323,15 @@ JKRExpHeap* fopMsgM_createExpHeap(u32); fpc_ProcID fopMsgM_Create(s16, fopMsgCreateFunc, void*); fpc_ProcID fopMsgM_create(s16 i_procName, fopAc_ac_c* param_1 = NULL, cXyz* param_2 = NULL, u32* param_3 = NULL, u32* param_4 = NULL, fopMsgCreateFunc createFunc = NULL); +inline fpc_ProcID fopMsgM_MiniGameStarter_create(s16 i_procName, u8 param_1, u16 param_2, fopMsgCreateFunc createFunc) { + u32 parameter = param_1; + parameter |= param_2 << 16; + return fopMsgM_create(i_procName, NULL, NULL, ¶meter, ¶meter, createFunc); +} fpc_ProcID fop_MGameTerm_create(s16, s16, s16, int, int, fopMsgCreateFunc); +inline fpc_ProcID fopMsgM_MiniGameTerminater_create(s16 param_0, s16 param_1, s16 param_2, int param_3, int param_4, fopMsgCreateFunc createFunc) { + return fop_MGameTerm_create(param_0, param_1, param_2, param_3, param_4, createFunc); +} void fopMsgM_Delete(void* process); fopMsg_prm_class* fopMsgM_GetAppend(void* msg); void fopMsgM_destroyExpHeap(JKRExpHeap*); @@ -340,7 +348,7 @@ char* fopMsgM_messageGet(char* msg, u32 string_id); void fopMsgM_passwordGet(char*, u32); fpc_ProcID fop_Timer_create(s16 param_0, u8 param_1, u16 param_2, u8 param_3, u8 param_4, f32 param_5, f32 param_6, f32 param_7, f32 param_8, fopMsgCreateFunc createFunc); -inline fpc_ProcID fopMsgM_Timer_create(s16 param_0, u8 param_1, u32 param_2, u8 param_3, u8 param_4, +inline fpc_ProcID fopMsgM_Timer_create(s16 param_0, u8 param_1, u16 param_2, u8 param_3, u8 param_4, f32 param_5, f32 param_6, f32 param_7, f32 param_8, fopMsgCreateFunc createFunc) { return fop_Timer_create(param_0, param_1, param_2, param_3, param_4, param_5, param_6, param_7, diff --git a/src/d/actor/d_a_goal_flag.cpp b/src/d/actor/d_a_goal_flag.cpp index f6eea0bce..7b65cef3b 100644 --- a/src/d/actor/d_a_goal_flag.cpp +++ b/src/d/actor/d_a_goal_flag.cpp @@ -5,97 +5,992 @@ #include "d/dolzel_rel.h" // IWYU pragma: keep #include "d/actor/d_a_goal_flag.h" +#include "d/actor/d_a_npc_sarace.h" +#include "d/d_kankyo_wether.h" +#include "d/d_minigame_starter.h" +#if VERSION == VERSION_DEMO +#include "d/d_s_play.h" +#endif +#include "d/res/res_cloth.h" +#include "d/res/res_gflag.h" +#include "d/res/res_tgflag.h" +#include "d/d_path.h" #include "d/d_procname.h" #include "d/d_priority.h" +#include "assets/l_txa_dummy_hataTEX.h" +#include "m_Do/m_Do_controller_pad.h" + +static Vec l_pos[] = { + { -1000.0f, 0.0f, 0.0f }, + { -750.0f, 0.0f, 0.0f }, + { -500.0f, 0.0f, 0.0f }, + { -250.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f }, + { 250.0f, 0.0f, 0.0f }, + { 500.0f, 0.0f, 0.0f }, + { 750.0f, 0.0f, 0.0f }, + { 1000.0f, 0.0f, 0.0f }, + { -1000.0f, -100.0f, 0.0f }, + { -750.0f, -100.0f, 0.0f }, + { -500.0f, -100.0f, 0.0f }, + { -250.0f, -100.0f, 0.0f }, + { 0.0f, -100.0f, 0.0f }, + { 250.0f, -100.0f, 0.0f }, + { 500.0f, -100.0f, 0.0f }, + { 750.0f, -100.0f, 0.0f }, + { 1000.0f, -100.0f, 0.0f }, + { -1000.0f, -200.0f, 0.0f }, + { -750.0f, -200.0f, 0.0f }, + { -500.0f, -200.0f, 0.0f }, + { -250.0f, -200.0f, 0.0f }, + { 0.0f, -200.0f, 0.0f }, + { 250.0f, -200.0f, 0.0f }, + { 500.0f, -200.0f, 0.0f }, + { 750.0f, -200.0f, 0.0f }, + { 1000.0f, -200.0f, 0.0f }, + { -1000.0f, -300.0f, 0.0f }, + { -750.0f, -300.0f, 0.0f }, + { -500.0f, -300.0f, 0.0f }, + { -250.0f, -300.0f, 0.0f }, + { 0.0f, -300.0f, 0.0f }, + { 250.0f, -300.0f, 0.0f }, + { 500.0f, -300.0f, 0.0f }, + { 750.0f, -300.0f, 0.0f }, + { 1000.0f, -300.0f, 0.0f }, + { -1000.0f, -400.0f, 0.0f }, + { -750.0f, -400.0f, 0.0f }, + { -500.0f, -400.0f, 0.0f }, + { -250.0f, -400.0f, 0.0f }, + { 0.0f, -400.0f, 0.0f }, + { 250.0f, -400.0f, 0.0f }, + { 500.0f, -400.0f, 0.0f }, + { 750.0f, -400.0f, 0.0f }, + { 1000.0f, -400.0f, 0.0f } +}; + +static cXy l_texCoord[] = { + { 1.0f, 0.0f }, + { 0.875f, 0.0f }, + { 0.75f, 0.0f }, + { 0.625f, 0.0f }, + { 0.5f, 0.0f }, + { 0.375f, 0.0f }, + { 0.25f, 0.0f }, + { 0.125f, 0.0f }, + { 0.0f, 0.0f }, + { 1.0f, 0.25f }, + { 0.875f, 0.25f }, + { 0.75f, 0.25f }, + { 0.625f, 0.25f }, + { 0.5f, 0.25f }, + { 0.375f, 0.25f }, + { 0.25f, 0.25f }, + { 0.125f, 0.25f }, + { 0.0f, 0.25f }, + { 1.0f, 0.5f }, + { 0.875f, 0.5f }, + { 0.75f, 0.5f }, + { 0.625f, 0.5f }, + { 0.5f, 0.5f }, + { 0.375f, 0.5f }, + { 0.25f, 0.5f }, + { 0.125f, 0.5f }, + { 0.0f, 0.5f }, + { 1.0f, 0.75f }, + { 0.875f, 0.75f }, + { 0.75f, 0.75f }, + { 0.625f, 0.75f }, + { 0.5f, 0.75f }, + { 0.375f, 0.75f }, + { 0.25f, 0.75f }, + { 0.125f, 0.75f }, + { 0.0f, 0.75f }, + { 1.0f, 1.0f }, + { 0.875f, 1.0f }, + { 0.75f, 1.0f }, + { 0.625f, 1.0f }, + { 0.5f, 1.0f }, + { 0.375f, 1.0f }, + { 0.25f, 1.0f }, + { 0.125f, 1.0f }, + { 0.0f, 1.0f } +}; + +#include "assets/l_goal_flag_DL.h" +#include "assets/l_goal_flag_matDL.h" +l_goal_flag_matDL(l_txa_dummy_hataTEX); + +static const char* sub_arcname_tbl[] = { + "Gflag", + "Tgflag" +}; +static const char arcname[] = "Cloth"; + +static daGFlag_HIO_c l_HIO; + +daGFlag_HIO_c::~daGFlag_HIO_c() { + m04 = -1; +} + /* 000000EC-00000210 .text setTexObj__16daGFlag_packet_cFUc */ -void daGFlag_packet_c::setTexObj(unsigned char) { - /* Nonmatching */ +void daGFlag_packet_c::setTexObj(u8 i_arcIdx) { + static char* arc_name_tbl[] = { + "Gflag", + "Tgflag" + }; + static const int index_tbl[] = { + GFLAG_BTI_B_FRAGGAIKOT, + TGFLAG_BTI_B_FRAGTORI + }; + // index_tbl likely existed in this function but passing + // an element of it into getObjectRes breaks the match + ResTIMG* tex_info_p = (ResTIMG*) dComIfG_getObjectRes(arc_name_tbl[i_arcIdx], 3); + GXBool mipmap_cnt_over_one = GXBool(tex_info_p->mipmapCount > 1); + GXInitTexObj( + &mTexObj, + (u8*)tex_info_p + tex_info_p->imageOffset, + tex_info_p->width, + tex_info_p->height, + GXTexFmt(tex_info_p->format), + GXTexWrapMode(tex_info_p->wrapS), + GXTexWrapMode(tex_info_p->wrapT), + mipmap_cnt_over_one + ); + GXInitTexObjLOD( + &mTexObj, + GXTexFilter(tex_info_p->minFilter), + GXTexFilter(tex_info_p->magFilter), + (f32)tex_info_p->minLOD * 0.125f, + (f32)tex_info_p->maxLOD * 0.125f, + (f32)tex_info_p->LODBias * 0.01f, + GXBool(tex_info_p->biasClamp), + GXBool(tex_info_p->doEdgeLOD), + GXAnisotropy(tex_info_p->maxAnisotropy) + ); } /* 00000210-00000330 .text setToonTexObj__16daGFlag_packet_cFv */ void daGFlag_packet_c::setToonTexObj() { - /* Nonmatching */ + ResTIMG* tex_info_p = (ResTIMG*) dComIfG_getObjectRes("Cloth", CLOTH_BTI_CLOTHTOON); + GXBool mipmap_cnt_over_one = GXBool(tex_info_p->mipmapCount > 1); + GXInitTexObj( + &mToonTexObj, + (u8*)tex_info_p + tex_info_p->imageOffset, + tex_info_p->width, + tex_info_p->height, + GXTexFmt(tex_info_p->format), + GXTexWrapMode(tex_info_p->wrapS), + GXTexWrapMode(tex_info_p->wrapT), + mipmap_cnt_over_one + ); + GXInitTexObjLOD( + &mToonTexObj, + GXTexFilter(tex_info_p->minFilter), + GXTexFilter(tex_info_p->magFilter), + (f32)tex_info_p->minLOD * 0.125f, + (f32)tex_info_p->maxLOD * 0.125f, + (f32)tex_info_p->LODBias * 0.01f, + GXBool(tex_info_p->biasClamp), + GXBool(tex_info_p->doEdgeLOD), + GXAnisotropy(tex_info_p->maxAnisotropy) + ); } /* 00000330-00000978 .text draw__16daGFlag_packet_cFv */ void daGFlag_packet_c::draw() { - /* Nonmatching */ + j3dSys.reinitGX(); +#if VERSION > VERSION_JPN + GXSetNumIndStages(0); +#endif + dKy_GxFog_tevstr_set(mpTevStr); + dKy_setLight_mine(mpTevStr); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_INDEX8); + GXSetVtxDesc(GX_VA_NRM, GX_INDEX8); + GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_F32, 0); + GXSetArray(GX_VA_POS, &mDPos[mCurrArr], sizeof(cXyz)); + GXSetArray(GX_VA_NRM, &mNrm[mCurrArr], sizeof(cXyz)); + GXSetArray(GX_VA_TEX0, l_texCoord, sizeof(cXy)); + GXLoadTexObj(getTexObjP(), GX_TEXMAP0); + GXLoadTexObj(getToonTexObjP(), GX_TEXMAP1); + GXSetNumChans(1); + u8 num_tev_stages, lightMask; + if (mpTevStr->mColorK1.a != 0) { + num_tev_stages = 3; + lightMask = 3; + } else { + num_tev_stages = 2; + lightMask = 1; + } + if (l_HIO.mDrawCelShaded) { + GXSetChanCtrl(GX_COLOR0, true, GX_SRC_REG, GX_SRC_REG, lightMask, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(2); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + GXSetTexCoordGen2(GX_TEXCOORD1, GX_TG_SRTG, GX_TG_COLOR0, GX_IDENTITY, false, GX_PTIDENTITY); + GXSetNumTevStages(num_tev_stages); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP1); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C0, GX_CC_C1, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + if (num_tev_stages == 3) { + GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP0, GX_TEV_SWAP2); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_C2, GX_CC_TEXC, GX_CC_CPREV); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + } + } else { + GXSetChanCtrl(GX_COLOR0, true, GX_SRC_REG, GX_SRC_REG, lightMask, GX_DF_CLAMP, GX_AF_NONE); + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + GXSetNumTevStages(num_tev_stages); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP1, GX_TEV_SWAP0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_C0, GX_CC_C1, GX_CC_RASC, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + if (num_tev_stages == 3) { + GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP2, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_C2, GX_CC_RASC, GX_CC_CPREV); + GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + } + } + GXSetTevColorS10(GX_TEVREG0, mpTevStr->mColorC0); + GXSetTevColor(GX_TEVREG1, mpTevStr->mColorK0); + GXSetTevColor(GX_TEVREG2, mpTevStr->mColorK1); + GXCallDisplayList(l_goal_flag_matDL, 32); + GXLoadPosMtxImm(mMtx, 0); + GXLoadNrmMtxImm(mMtx, 0); + GXSetCullMode(GX_CULL_BACK); + GXCallDisplayList(l_goal_flag_DL, 256); + GXSetCullMode(GX_CULL_FRONT); + GXSetArray(GX_VA_NRM, &mBackNrm[mCurrArr], sizeof(cXyz)); + GXCallDisplayList(l_goal_flag_DL, 256); +#if VERSION > VERSION_JPN + J3DShape::sOldVcdVatCmd = 0; +#endif } /* 00000978-00000A04 .text setBackNrm__16daGFlag_packet_cFv */ void daGFlag_packet_c::setBackNrm() { - /* Nonmatching */ -} + cXyz* nrm_arr = mNrm[mCurrArr]; + cXyz* back_nrm_arr = mBackNrm[mCurrArr]; + for (int i = 0; i < ARRAY_SSIZE(*mBackNrm); i++) { + back_nrm_arr->setall(0.0f); + *back_nrm_arr -= *nrm_arr; + + nrm_arr++; + back_nrm_arr++; + } +} /* 00000A04-00000E78 .text setNrmVtx__16daGFlag_packet_cFP4cXyzii */ -void daGFlag_packet_c::setNrmVtx(cXyz*, int, int) { - /* Nonmatching */ +void daGFlag_packet_c::setNrmVtx(cXyz* o_nrm, int i_col, int i_row) { + cXyz* dpos_arr = getDPos(); + cXyz horizontal_edge; + cXyz vertical_edge; + cXyz tri_normal; + cXyz averaged_normal; + cXyz center_vertex = dpos_arr[(i_row * 9) + i_col]; + averaged_normal.setall(0.0f); + + if (i_col != 0) { + horizontal_edge = dpos_arr[(i_row * 9) + (i_col - 1)] - center_vertex; + if (i_row != 0) { + vertical_edge = dpos_arr[(i_row - 1) * 9 + i_col] - center_vertex; + tri_normal = vertical_edge.outprod(horizontal_edge); + tri_normal = tri_normal.normZP(); + averaged_normal += tri_normal; + } + if (i_row != 4) { + vertical_edge = dpos_arr[(i_row + 1) * 9 + i_col] - center_vertex; + tri_normal = horizontal_edge.outprod(vertical_edge); + tri_normal = tri_normal.normZP(); + averaged_normal += tri_normal; + } + } + if (i_col != 8) { + horizontal_edge = dpos_arr[(i_col + 1) + i_row * 9] - center_vertex; + if (i_row != 0) { + vertical_edge = dpos_arr[(i_row - 1) * 9 + i_col] - center_vertex; + tri_normal = horizontal_edge.outprod(vertical_edge); + tri_normal = tri_normal.normZP(); + averaged_normal += tri_normal; + } + if (i_row != 4) { + vertical_edge = dpos_arr[(i_row + 1) * 9 + i_col] - center_vertex; + tri_normal = vertical_edge.outprod(horizontal_edge); + tri_normal = tri_normal.normZP(); + averaged_normal += tri_normal; + } + } + averaged_normal = averaged_normal.normZC(); + + MtxPush(); + cMtx_YrotM(*calc_mtx, + DEMO_SELECT(REG10_S(2) + 0x200, 512.0f) * + cM_ssin( + mNormalFlutterPhase + + (i_col * (DEMO_SELECT(REG10_S(3), 0) + -0x400) + + i_row * (DEMO_SELECT(REG10_S(4), 0) + 0x100)) + ) + ); + cMtx_XrotM(*calc_mtx, + DEMO_SELECT(REG10_S(5) + 0x200, 512.0f) * + cM_scos( + mNormalFlutterPhase + + (i_col * (DEMO_SELECT(REG10_S(6), 0) + -0x400) + + i_row * (DEMO_SELECT(REG10_S(7), 0) + 0x100)) + ) + ); + MtxPosition(&averaged_normal, &tri_normal); + o_nrm->set(tri_normal.normZP()); + MtxPull(); } /* 00000EB4-00000F80 .text getRacePath__13daGoal_Flag_cFUc */ -void daGoal_Flag_c::getRacePath(unsigned char) { - /* Nonmatching */ +BOOL daGoal_Flag_c::getRacePath(u8 i_pathId) { + int i = 0; + mpRopePaths[i] = dPath_GetRoomPath(i_pathId, fopAcM_GetRoomNo(this)); + if (!mpRopePaths[i]) { + return FALSE; + } + + mNumRopeBuoys[i] = mpRopePaths[i]->m_num; + u8 next_path_id = mpRopePaths[i]->m_nextID; + for (i++; i < ARRAY_SSIZE(mpRopePaths) && next_path_id != 0xFFU; i++) { + mpRopePaths[i] = dPath_GetRoomPath(next_path_id, fopAcM_GetRoomNo(this)); + mNumRopeBuoys[i] = mpRopePaths[i]->m_num; + next_path_id = mpRopePaths[i]->m_nextID; + } + mNumRopes = i; + + return TRUE; } /* 00000F80-000010F4 .text RopeMove__13daGoal_Flag_cFv */ void daGoal_Flag_c::RopeMove() { - /* Nonmatching */ + static const f32 down_offset[] = { + 0.0f, 150.0f, 225.0f, 150.0f + }; + for (int i = 0; i < mNumRopes; i++) { + cXyz* rope_start = getRopePos(i, 0); + cXyz* rope_end = getRopePos(i, mNumRopeBuoys[i]); + rope_end->set(*rope_start); + for (int j = 0; j < (int)(mNumRopeBuoys[i] << 2); j++) { + int interpolated_point = j & 3; + int anchor_point = j >> 2; + if (interpolated_point != 0) { + cXyz* A = getRopePos(i, anchor_point); + cXyz* B = getRopePos(i, anchor_point + 1); + cXyz& C = getRopePos(i, anchor_point)[interpolated_point]; + f32 t = (f32)interpolated_point * 0.25f; + f32 one_minus_t = 1.0f - t; + C.set((*A) * one_minus_t + (*B) * t); + C.y -= down_offset[interpolated_point]; + } + } + } } /* 000010F4-0000123C .text CreateBuoyRaces__13daGoal_Flag_cFv */ -void daGoal_Flag_c::CreateBuoyRaces() { - /* Nonmatching */ +BOOL daGoal_Flag_c::CreateBuoyRaces() { + int i; + dPnt* rope_points_p; + cXyz* segment; + for (i = 0; i < mNumRopes; i++) { + rope_points_p = mpRopePaths[i]->m_points; + segment = getRopePos(i, 0); + for (int j = 0; j < mNumRopeBuoys[i]; j++, rope_points_p++, segment++) { + cXyz rope_point_pos; + rope_point_pos.set( + rope_points_p->m_position.x, + rope_points_p->m_position.y, + rope_points_p->m_position.z + ); + fopAcM_createChild( + PROC_Obj_Buoyrace, + fopAcM_GetID(this), + j | (i << 8), &rope_point_pos, + fopAcM_GetRoomNo(this), + NULL + ); + segment->set( + rope_points_p->m_position.x, + rope_points_p->m_position.y + 250.0f, + rope_points_p->m_position.z + ); + } + segment->set(*getRopePos(i, 0)); + } + return TRUE; } /* 0000123C-00001450 .text goal_check__13daGoal_Flag_cFv */ -void daGoal_Flag_c::goal_check() { - /* Nonmatching */ +int daGoal_Flag_c::goal_check() { + int o_result; + cXyz player_from_line_start = dComIfGp_getPlayer(0)->current.pos - mGoalFlagPolePos[0]; + + cXyz finish_line_dir = mGoalFlagPolePos[1] - mGoalFlagPolePos[0]; + + finish_line_dir.y = 0.0f; + finish_line_dir = finish_line_dir.normZP(); + + player_from_line_start.y = 0.0f; + + f32 finish_line_len = (mGoalFlagPolePos[1] - mGoalFlagPolePos[0]).absXZ(); + f32 player_along_line = finish_line_dir.getDotProduct(player_from_line_start); + + cXyz finish_line_normal; + finish_line_normal.set(finish_line_dir.z, 0.0f, -finish_line_dir.x); + + // Positive values mean the player is behind the finish line + // Negative values mean the player is in front of it + f32 player_finish_side = finish_line_normal.getDotProduct(player_from_line_start); + + o_result = 0; // Not yet crossed the finish line + if (player_along_line > 0.0f && player_along_line < finish_line_len) { + if (mPrevPlayerLineSide > 0.0f && player_finish_side <= 0.0f) { + o_result = 1; // Crossed the finish line normally + } else if (mPrevPlayerLineSide <= 0.0f && player_finish_side > 0.0f) { + o_result = -1; // Crossed the finish line the wrong way + } + } + + mPrevPlayerLineSide = player_finish_side; + return o_result; } /* 00001450-0000183C .text flag_move__13daGoal_Flag_cFv */ void daGoal_Flag_c::flag_move() { - /* Nonmatching */ + cXyz cloth_anim_factor; + cXyz* prev_pos_arr = mFlagPacket.getPos(); + cXyz* prev_nrm_arr = mFlagPacket.getNrm(); + mFlagPacket.changeCurrentPos(); + cXyz* curr_pos_arr = mFlagPacket.getPos(); + cXyz* velocity_arr = mFlagPacket.getOffsetVec(); + + mWindScalePhase += l_HIO.mWindScalePhaseInc; + mFlagPacket.mNormalFlutterPhase += l_HIO.mNormalFlutterPhaseInc; + mFlagPacket.mFlagWavePhase += l_HIO.mFlagWavePhaseInc; + + f32 scale_blend_factor = 0.5f + (cM_ssin(mWindScalePhase) * 0.5f); + f32 wind_vector_scale = l_HIO.mWindScale1 * scale_blend_factor + (l_HIO.mWindScale2 * (1.0f - scale_blend_factor)); + + cMtx_YrotS(*calc_mtx, -current.angle.y); + cXyz wind_vector; + MtxPosition(dKyw_get_wind_vec(), &wind_vector); + f32 mag = wind_vector.getSquareMag(); + + if (cM3d_IsZero(mag)) { + wind_vector = cXyz::Zero; + } else { + wind_vector = wind_vector.norm(); + wind_vector.x *= DEMO_SELECT(REG10_F(24) + 0.2f, 0.2f); + wind_vector *= wind_vector_scale; + } + + int index; + for (int i = 0; i < 9; i++) { + for (int j = 0; j < 5; j++) { + index = i + j * 9; + curr_pos_arr[index].set(prev_pos_arr[index]); + cloth_anim_factor = get_cloth_anim_factor( + prev_pos_arr, + prev_nrm_arr, + &wind_vector, + i, + j + ); + velocity_arr[index] += cloth_anim_factor; + velocity_arr[index] *= DEMO_SELECT(0.85f - REG10_F(25), 0.85f); + curr_pos_arr[index] += velocity_arr[index]; + } + } + + cXyz* curr_dpos_arr = mFlagPacket.getDPos(); + for (int k = 0; k < 9; k++) { + for (int l = 0; l < 5; l++) { + index = k + l * 9; + curr_dpos_arr[index] = curr_pos_arr[index]; + f32 center_to_edge_falloff = ((20.25f - std::abs(4.5f - (f32)k) * std::abs(4.5f - (f32)k)) / 20.25f); + curr_dpos_arr[index].z += ( + DEMO_SELECT(40.0f + REG10_F(10), 40.0f) * + center_to_edge_falloff * + cM_ssin(k * 0x4000 + l * 0x2000 + mFlagPacket.mFlagWavePhase) + ); + } + } + + cXyz* curr_nrm_p = mFlagPacket.getNrm(); + for (int m = 0; m < 5; m++) { + for (int n = 0; n < 9; n++) { + mFlagPacket.setNrmVtx(curr_nrm_p, n, m); + curr_nrm_p++; + } + } + + mFlagPacket.setBackNrm(); + DCStoreRangeNoSync(mFlagPacket.getDPos(), sizeof(mFlagPacket.mDPos[0])); +#if VERSION > VERSION_JPN + DCStoreRangeNoSync(mFlagPacket.getNrm(), sizeof(mFlagPacket.mNrm[0])); + DCStoreRangeNoSync(mFlagPacket.getBackNrm(), sizeof(mFlagPacket.mBackNrm[0])); +#endif } +static BOOL checkCreateHeap(fopAc_ac_c*); + +/* 00002400-00002968 .text _create__13daGoal_Flag_cFv */ +cPhs_State daGoal_Flag_c::_create() { + cPhs_State cloth_resload_state; + cPhs_State flag_resload_state; + u8 arc_index; + dPath* path_p; + + fopAcM_SetupActor(this, daGoal_Flag_c); + + u8 prm = fopAcM_GetParam(this) & 0xFF; + cloth_resload_state = dComIfG_resLoad(&mClothPhs, "Cloth"); + +#if VERSION > VERSION_DEMO + if (cloth_resload_state != cPhs_COMPLEATE_e) { + return cloth_resload_state; + } +#endif + + if (prm == 0 || prm == 0xFF) { + arc_index = 0; + flag_resload_state = dComIfG_resLoad(&mFlagPhs, "Gflag"); + scale.set(1.05f, 1.0f, 1.0f); + } else { + arc_index = 1; + flag_resload_state = dComIfG_resLoad(&mFlagPhs, "Tgflag"); + scale.set(0.98f, 1.0f, 1.0f); + } + + +#if VERSION > VERSION_DEMO + if (flag_resload_state != cPhs_COMPLEATE_e) { + return flag_resload_state; + } +#else + if (cloth_resload_state == cPhs_ERROR_e || flag_resload_state == cPhs_ERROR_e) { + return cPhs_ERROR_e; + } + if (cloth_resload_state != cPhs_COMPLEATE_e) { + return cloth_resload_state; + } + if (flag_resload_state != cPhs_COMPLEATE_e) { + return flag_resload_state; + } + + int dummy_int = 4; + if (dummy_int == 4) +#endif + { + u8 path_id = fopAcM_GetParam(this) >> 16u; + if (path_id != 0xFF) { + path_p = dPath_GetRoomPath(path_id, fopAcM_GetRoomNo(this)); + if (path_p) { + u8 path_id = path_p->m_nextID; + if (getRacePath(path_id)) { + if (fopAcM_entrySolidHeap(this, checkCreateHeap, 0x10000)) { + CreateBuoyRaces(); + } else { + return cPhs_ERROR_e; + } + } + } else { + return cPhs_ERROR_e; + } + } else { + return cPhs_ERROR_e; + } + + cXyz* pos_arr = mFlagPacket.getPos(); + for (int i = 0; i < 45; i++, pos_arr++) { + pos_arr->set(l_pos[i]); + } + + mFlagPacket.setTexObj(arc_index); + mFlagPacket.setToonTexObj(); + + path_id = fopAcM_GetParam(this) >> 16u; + path_p = dPath_GetRoomPath(path_id, fopAcM_GetRoomNo(this)); + + if (path_p) { + mGoalFlagPolePos[0].set(path_p->m_points[0].m_position); + mGoalFlagPolePos[1].set(path_p->m_points[1].m_position); + } + + mDoMtx_stack_c::transS(current.pos); + mDoMtx_stack_c::YrotM(shape_angle.y); + mDoMtx_stack_c::scaleM(scale); + MTXCopy(mDoMtx_stack_c::get(), mMtx); + if ( + strcmp(dComIfGp_getStartStageName(), "Ocean") == 0 && + dComIfGp_getStartStagePoint() == 1 + ) { + u16 time_limit = l_HIO.mTimeLimit; + u16 time_limit_modifier = (u16)dComIfGs_getEventReg(dSv_event_flag_c::UNK_AAFF) * 10; + time_limit -= time_limit_modifier; + mTimerProcID = fopMsgM_Timer_create( + PROC_TIMER, + 2, + time_limit, + 3, + 0, + 221.0f, + 439.0f, + 32.0f, + 419.0f, + NULL + ); + + mMgameStartProcID = fopMsgM_MiniGameStarter_create( + PROC_MINIGAME_STARTER, + 0, + 0x200, + NULL + ); + + dComIfGp_startMiniGame(1); + dComIfGp_setMiniGameRupee(0); + + setAction(&daGoal_Flag_c::RaceStart); + mRaceStartState = 0; + } + + cXyz initial_player_from_start = dComIfGp_getPlayer(0)->current.pos - mGoalFlagPolePos[0]; + + cXyz finish_line_dir = mGoalFlagPolePos[1] - mGoalFlagPolePos[0]; + finish_line_dir.y = 0.0f; + finish_line_dir = finish_line_dir.normZP(); + + cXyz finish_line_normal; + finish_line_normal.set(finish_line_dir.z, 0.0f, -finish_line_dir.x); + + mPrevPlayerLineSide = finish_line_normal.getDotProduct(initial_player_from_start); + mRaceEndState = 0; + + for (int i = 0; i < 20; i++) { + flag_move(); + } + } + + return cPhs_COMPLEATE_e; +} + + /* 0000183C-00001970 .text get_cloth_anim_sub_factor__FP4cXyzP4cXyzP4cXyzf */ -void get_cloth_anim_sub_factor(cXyz*, cXyz*, cXyz*, float) { - /* Nonmatching */ +void get_cloth_anim_sub_factor(cXyz* i_posP, cXyz* i_otherP, cXyz* o_dst, f32 i_idealDist) { + cXyz vec_to_neighbor = *i_otherP - *i_posP; + cXyz correction_dir = vec_to_neighbor.normZP(); + + f32 diff_from_ideal = (vec_to_neighbor.abs() - i_idealDist); + diff_from_ideal *= l_HIO.mClothStiffness; + + correction_dir *= diff_from_ideal; + *o_dst += correction_dir; } /* 00001970-00001CC0 .text get_cloth_anim_factor__13daGoal_Flag_cFP4cXyzP4cXyzP4cXyzii */ -void daGoal_Flag_c::get_cloth_anim_factor(cXyz*, cXyz*, cXyz*, int, int) { - /* Nonmatching */ +cXyz daGoal_Flag_c::get_cloth_anim_factor(cXyz* i_posArr, cXyz* i_nrmArr, cXyz* i_windVecP, int i_col, int i_row) { + int index = (i_row * 9) + i_col; + cXyz pos = i_posArr[index]; + f32 dot = i_windVecP->getDotProduct(i_nrmArr[index]); + if ((i_row == 0 || i_row == 4) && (i_col == 0 || i_col == 8)) { + return cXyz::Zero; + } else { + cXyz anim_factor = i_nrmArr[index] * dot; + anim_factor.y += l_HIO.mFlagSagFactor * ((float)i_row * 0.25f); + if (i_col != 0) { + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col - 1) + (i_row * 9)], + &anim_factor, 250.0f); + if (i_row != 0) { + get_cloth_anim_sub_factor( + &pos, &i_posArr[i_col + (i_row - 1) * 9], + &anim_factor, 120.0f); + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col - 1) + (i_row - 1) * 9], + &anim_factor, 277.3085f); + } + if (i_row != 4) { + get_cloth_anim_sub_factor( + &pos, &i_posArr[i_col + (i_row + 1) * 9], + &anim_factor, 120.0f); + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col - 1) + (i_row + 1) * 9], + &anim_factor, 277.3085f); + } + if (i_col != 8) { + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col + 1) + i_row * 9], + &anim_factor, 250.0f); + if (i_row != 0) { + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col + 1) + (i_row - 1) * 9], + &anim_factor, 277.3085f); + } + if (i_row != 4) { + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col + 1) + (i_row + 1) * 9], + &anim_factor, 277.3085f); + } + } + return anim_factor; + } else { + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col + 1) + (i_row * 9)], + &anim_factor, 250.0f); + if (i_row != 0) { + get_cloth_anim_sub_factor( + &pos, &i_posArr[i_col + (i_row - 1) * 9], + &anim_factor, 120.0f); + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col + 1) + (i_row - 1) * 9], + &anim_factor, 277.3085f); + } + if (i_row != 4) { + get_cloth_anim_sub_factor( + &pos, &i_posArr[i_col + (i_row + 1) * 9], + &anim_factor, 120.0f); + get_cloth_anim_sub_factor( + &pos, &i_posArr[(i_col + 1) + (i_row + 1) * 9], + &anim_factor, 277.3085f); + } + return anim_factor; + } + } } /* 00001CC0-00001CE0 .text checkCreateHeap__FP10fopAc_ac_c */ -static BOOL checkCreateHeap(fopAc_ac_c*) { - /* Nonmatching */ +static BOOL checkCreateHeap(fopAc_ac_c* i_actor) { + return ((daGoal_Flag_c*)i_actor)->CreateHeap(); } /* 00001CE0-00001D74 .text CreateHeap__13daGoal_Flag_cFv */ -void daGoal_Flag_c::CreateHeap() { - /* Nonmatching */ +BOOL daGoal_Flag_c::CreateHeap() { + for (int i = 0; i < mNumRopes; i++) { + if (!mRopeLines[i].init(1, (mNumRopeBuoys[i] << 2) + 1, 0)) { + return FALSE; + } + } + return TRUE; +} + +bool daGoal_Flag_c::_delete() { + u8 prm = fopAcM_GetParam(this) & 0xFF; + dComIfG_resDeleteDemo(&mClothPhs, arcname); + dComIfG_resDeleteDemo(&mFlagPhs, sub_arcname_tbl[prm]); + + if (dComIfGp_getMiniGameType() == 1) { + if (dComIfGp_getMiniGameResult() == 1) { + daNpc_Sarace_c::ship_race_result = 2; + daNpc_Sarace_c::ship_race_rupee = dComIfGp_getMiniGameRupee(); + } else if (dComIfGp_getMiniGameResult() == 2) { + daNpc_Sarace_c::ship_race_result = 1; + daNpc_Sarace_c::ship_race_rupee = dComIfGp_getMiniGameRupee(); + } + dComIfGp_endMiniGame(1); + } + + return true; } /* 00001D74-00001DB4 .text getDemoAction__13daGoal_Flag_cFi */ -void daGoal_Flag_c::getDemoAction(int) { - /* Nonmatching */ +int daGoal_Flag_c::getDemoAction(int param_1) { + static char* ActionNames[] = { + "00_dummy", + "01_dummy", + "02_dummy", + "03_dummy", + "04_dummy" + }; + return dComIfGp_evmng_getMyActIdx(param_1, ActionNames, 5, FALSE, 0); } /* 00001DB4-00001F60 .text RaceStart__13daGoal_Flag_cFv */ -void daGoal_Flag_c::RaceStart() { - /* Nonmatching */ +BOOL daGoal_Flag_c::RaceStart() { + int staff_idx = dComIfGp_evmng_getMyStaffId("Gflag"); + int action_idx = getDemoAction(staff_idx); + + if (mRaceStartState == 0) { + if (staff_idx != -1 && action_idx == 0) { + dComIfGp_evmng_cutEnd(staff_idx); + } else { + return TRUE; + } + mRaceStartState++; + } else { + dTimer_c* timer_p = (dTimer_c*) fopMsgM_SearchByID(mTimerProcID); + dMinigame_Starter_c* mgame_start_p = (dMinigame_Starter_c*) fopMsgM_SearchByID(mMgameStartProcID); + + if (action_idx == 1 && mgame_start_p) { + mgame_start_p->countStart(); + dComIfGp_evmng_cutEnd(staff_idx); + } + + if (timer_p && mgame_start_p && mgame_start_p->startCheck()) { + dComIfGp_evmng_cutEnd(staff_idx); + timer_p->start(7); + if (mRaceStartState == 1) { + mDoAud_bgmStart(JA_BGM_SEA_GAME); + mRaceStartState++; + } + } + + if (dComIfGp_evmng_endCheck("race_start_cam")) { + setAction(&daGoal_Flag_c::TimerExecute); + mRaceStartState = 0; + } + } + return TRUE; } /* 00001F60-00002290 .text TimerExecute__13daGoal_Flag_cFv */ -void daGoal_Flag_c::TimerExecute() { - /* Nonmatching */ +BOOL daGoal_Flag_c::TimerExecute() { + dTimer_c* timer_p = (dTimer_c *) fopMsgM_SearchByID(mTimerProcID); + s32 finish_type; + int goal_chk; + int rupees_collected; + int remaining_time; + dMinigame_Starter_c* mgame_start_p; + if (mMgameStartProcID != -1) { + mgame_start_p = (dMinigame_Starter_c*) fopMsgM_SearchByID(mMgameStartProcID); + if (mgame_start_p && mgame_start_p->deleteCheck()) { + fopMsgM_Delete(mgame_start_p); + mMgameStartProcID = -1; + } + } + + goal_chk = goal_check(); + + if (goal_chk == 1) { + if (mRaceEndState == 1) { + timer_p->end(-1); + if (dComIfGp_getMiniGameRupee() == 0) { + mRaceEndState = 2; + } else { + mRaceEndState = 3; + } + } else { + mRaceEndState = 1; + } + } else if (goal_chk == -1) { + timer_p->end(-1); + mDoAud_seStart(JA_SE_SGAME_TIMER_0); + mRaceEndState = 2; + } + + if (timer_p->getRestTimeMs() == 0 && (timer_p->end(-1), mRaceEndState != 3)) { + mRaceEndState = 2; + mDoAud_seStart(JA_SE_SGAME_TIMER_0); + } + + if (mRaceEndState == 3 || mRaceEndState == 2) { + if (eventInfo.checkCommandDemoAccrpt()) { + timer_p->timerHide(); + if (mRaceEndState == 3) { + // 1 is standard finish, 2 is perfect (got all 150 rupees) + finish_type = dComIfGp_getMiniGameRupee() < l_HIO.mPerfectRupeeScore ? 1 : 2; + dComIfGp_setMiniGameResult(1); + } else { + // 0 is did not finish or got no rupees + finish_type = 0; + dComIfGp_setMiniGameResult(2); + } + if (u16(finish_type) == 1 || u16(finish_type) == 2) { + mDoAud_bgmStart(JA_BGM_SEA_GOAL); + } else { + mDoAud_bgmStart(JA_BGM_SEA_FAIL); + } + dComIfGp_clearPlayerStatus0(0, daPyStts0_TELESCOPE_LOOK_e); + rupees_collected = dComIfGp_getMiniGameRupee(); + remaining_time = timer_p->getRestTimeMs() / 10; + mMgameTermProcID = fopMsgM_MiniGameTerminater_create( + PROC_MINIGAME_TERMINATER, + 0, + finish_type, + remaining_time, + rupees_collected, + NULL + ); + fopMsgM_SearchByID(mMgameTermProcID); // Unused return + mCamFramesPassed = 0; + setAction(&daGoal_Flag_c::RaceEnd); + mRaceStartState = 0; + } else { + static char* event_name_tbl[] = { + "race_goal_cam", + "race_fail_cam", + }; + char* event_name = event_name_tbl[mRaceEndState != 3 ? 1 : 0]; + fopAcM_orderOtherEvent2(this, event_name, dEvtFlag_NOPARTNER_e); + eventInfo.onCondition(dEvtCnd_UNK2_e); + } + } + + return TRUE; } /* 00002290-000023E0 .text RaceEnd__13daGoal_Flag_cFv */ -void daGoal_Flag_c::RaceEnd() { - /* Nonmatching */ +BOOL daGoal_Flag_c::RaceEnd() { + static char* event_name_tbl[] = { + "race_goal_cam", + "race_fail_cam", + }; + + mCamFramesPassed++; + + dTimer_c* timer_p; + if ( + mTimerProcID != -1 && + (timer_p = (dTimer_c*)fopMsgM_SearchByID(mTimerProcID)) && + timer_p->deleteCheck() + ) { + fopMsgM_Delete(timer_p); + mTimerProcID = -1; + } + + int staff_idx = dComIfGp_evmng_getMyStaffId("Gflag"); + + if (staff_idx != -1) { + dComIfGp_evmng_cutEnd(staff_idx); + } + + BOOL end_chk = dComIfGp_evmng_endCheck(event_name_tbl[mRaceEndState != 3 ? 1 : 0]); + + if (end_chk || (mCamFramesPassed > l_HIO.mEndCamEarlyFrame && + (CPad_CHECK_TRIG_A(0) || CPad_CHECK_TRIG_B(0) || CPad_CHECK_TRIG_START(0)) )) { + dComIfGp_setNextStage("sea", 1, 0x30); + } + + return true; } /* 000023E0-00002400 .text daGoal_FlagCreate__FPv */ @@ -103,24 +998,53 @@ static cPhs_State daGoal_FlagCreate(void* i_this) { return ((daGoal_Flag_c*)i_this)->_create(); } -/* 00002400-00002968 .text _create__13daGoal_Flag_cFv */ -cPhs_State daGoal_Flag_c::_create() { - /* Nonmatching */ +/* 000029CC-00002AAC .text daGoal_FlagDelete__FPv */ +static BOOL daGoal_FlagDelete(void* i_this) { + return ((daGoal_Flag_c*)i_this)->_delete(); } -/* 000029CC-00002AAC .text daGoal_FlagDelete__FPv */ -static BOOL daGoal_FlagDelete(void*) { - /* Nonmatching */ -} +bool daGoal_Flag_c::_execute() { + if (mCurrProc != NULL) { + (this->*mCurrProc)(); + } + flag_move(); + RopeMove(); + return true; +} /* 00002AAC-00002B14 .text daGoal_FlagExecute__FPv */ -static BOOL daGoal_FlagExecute(void*) { - /* Nonmatching */ +static BOOL daGoal_FlagExecute(void* i_this) { + return ((daGoal_Flag_c*)i_this)->_execute(); +} + +bool daGoal_Flag_c::_draw() { + g_env_light.settingTevStruct(TEV_TYPE_ACTOR, ¤t.pos, &tevStr); + + MtxTrans(current.pos.x, current.pos.y, current.pos.z, FALSE); + cMtx_YrotM(*calc_mtx, current.angle.y); + MtxScale(scale.x, scale.y, scale.z, TRUE); + + cMtx_concat(j3dSys.getViewMtx(), *calc_mtx, mFlagPacket.getMtx()); + + mFlagPacket.setTevStr(&tevStr); + j3dSys.getDrawBuffer(0)->entryImm(&mFlagPacket, 0); + + for (int i = 0; i < mNumRopes; i++) { + GXColor rope_color; + rope_color.r = l_HIO.mRopeColorR; + rope_color.g = l_HIO.mRopeColorG; + rope_color.b = l_HIO.mRopeColorB; + rope_color.a = 0xFF; + mRopeLines[i].update((mNumRopeBuoys[i] << 2) + 1, 20.0f, rope_color, 0, &tevStr); + dComIfGd_set3DlineMat(&mRopeLines[i]); + } + + return true; } /* 00002B14-00002CA4 .text daGoal_FlagDraw__FPv */ -static BOOL daGoal_FlagDraw(void*) { - /* Nonmatching */ +static BOOL daGoal_FlagDraw(void* i_this) { + return ((daGoal_Flag_c*)i_this)->_draw(); } /* 00002CA4-00002CAC .text daGoal_FlagIsDelete__FPv */ diff --git a/src/d/d_minigame_starter.cpp b/src/d/d_minigame_starter.cpp index 9b212c157..b383c345b 100644 --- a/src/d/d_minigame_starter.cpp +++ b/src/d/d_minigame_starter.cpp @@ -29,12 +29,12 @@ void dMinigame_Starter_c::_delete() { } /* 80206328-8020634C .text startCheck__19dMinigame_Starter_cFv */ -void dMinigame_Starter_c::startCheck() { +BOOL dMinigame_Starter_c::startCheck() { /* Nonmatching */ } /* 8020634C-80206360 .text deleteCheck__19dMinigame_Starter_cFv */ -void dMinigame_Starter_c::deleteCheck() { +BOOL dMinigame_Starter_c::deleteCheck() { /* Nonmatching */ }