summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland <roland@wildpaws.xyz>2026-01-09 12:09:23 -0600
committerGitHub <noreply@github.com>2026-01-09 13:09:23 -0500
commit6893c2588e1a616072f39913a6dc09ac2c4f8705 (patch)
tree76d521fd774fdc185c60ab969418bc0d8a611b63
parentca83b5d1ae5887a4b5c4307c5fa4578338d7a4f3 (diff)
d_a_goal_flag - matching (#918)
* initial work on d_a_goal_flag * Update config.yml to extract symbols from d_a_goal_flag; also add l_pos and l_texCoord * 17% matching in .text * daGoal_Flag_c::CreateHeap matched * RopeMove 99% * Update d_a_goal_flag.cpp * getRacePath 100% * 31% in .text * 47% matching in .text * 56% matching in .text * 70% matching in .text Add definitions to inlines in daGFlag_packet_c and fully matched some daGFlag_packet_c methods. * 84% matching in .text Match daGFlag_packet_c::draw * 91% matching in .text - Formatting tweaks - Match TimerExecute - Add fopMsgM_MiniGameTerminater_create inline - Move daGoal_Flag_c::_create in the correct place to match .data * d_a_goal_flag matching 100% for retail * d_a_goal_flag demo 99% * Resolve _create fakematch * d_a_goal_flag demo matching 100% * link d_a_goal_flag for demo * Renaming of fields/variables and some refactoring * Refactoring continued - Change direct calls to VECDotProduct to cXyz::getDotProduct * Named more HIO fields and packet fields * Implement fopMsgM_MiniGameStarter_create * Name all used HIO fields * Named all fields in daGoal_Flag_c * Finishing touches
-rw-r--r--config/D44J01/config.yml12
-rw-r--r--config/GZLE01/config.yml12
-rw-r--r--config/GZLJ01/config.yml12
-rw-r--r--config/GZLP01/config.yml12
-rwxr-xr-xconfigure.py2
-rw-r--r--include/d/actor/d_a_goal_flag.h165
-rw-r--r--include/d/d_com_inf_game.h5
-rw-r--r--include/d/d_minigame_starter.h15
-rw-r--r--include/f_op/f_op_msg_mng.h10
-rw-r--r--src/d/actor/d_a_goal_flag.cpp1010
-rw-r--r--src/d/d_minigame_starter.cpp4
11 files changed, 1176 insertions, 83 deletions
diff --git a/config/D44J01/config.yml b/config/D44J01/config.yml
index 3b33821c..2735ec91 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 b5308963..9dbf1c4c 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 928b882f..79601b19 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 5e7c4706..d9bdc54c 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 25c8a877..91a66f0a 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 eae78ac0..8b4a3df5 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 5ad27040..51890c01 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 0dcf993b..fba8c557 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 9d428f87..a6bd7d32 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, &parameter, &parameter, 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 f6eea0bc..7b65cef3 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*) {
- /* Nonmatching */
+static BOOL daGoal_FlagDelete(void* i_this) {
+ return ((daGoal_Flag_c*)i_this)->_delete();
}
+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, &current.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 9b212c15..b383c345 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 */
}