summaryrefslogtreecommitdiff
path: root/src/code
diff options
context:
space:
mode:
Diffstat (limited to 'src/code')
-rw-r--r--src/code/m_field_info.c20
-rw-r--r--src/code/m_npc.c7
-rw-r--r--src/code/m_random_field.c883
3 files changed, 902 insertions, 8 deletions
diff --git a/src/code/m_field_info.c b/src/code/m_field_info.c
index 66722a8..85c8c3b 100644
--- a/src/code/m_field_info.c
+++ b/src/code/m_field_info.c
@@ -6,7 +6,7 @@
s32 mFI_BlockCheck(s32 blockX, s32 blockZ);
-// mCoBG_unkStructUnion l_edge_ut = { { 0, 31, 31, 31, 31, 31, mCoBG_ATTRIBUTE_0 } };
+// mCoBG_unkStructUnion l_edge_ut = { { 0, 31, 31, 31, 31, 31, mCoBG_ATTRIBUTE_GRASS0 } };
extern mCoBG_unkStructUnion l_edge_ut;
extern FieldMakeInfo* g_fdinfo;
@@ -511,13 +511,23 @@ mCoBG_unkStructUnion* mFI_UtNum2UtCol(s32 utX, s32 utZ) {
#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800897D0_jp.s")
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80089888_jp.s")
+mCoBG_unkStructUnion* mFI_GetUnitCol(xyz_t wpos) {
+ s32 utX;
+ s32 utZ;
+ s32 validWpos = mFI_Wpos2UtNum(&utX, &utZ, wpos);
+
+ if (!validWpos) {
+ return &l_edge_ut;
+ } else {
+ return mFI_UtNum2UtCol(utX, utZ);
+ }
+}
#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800898F4_jp.s")
#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800899CC_jp.s")
-#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80089A34_jp.s")
+#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_GetSoundSourcePBlockNum.s")
#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80089AAC_jp.s")
@@ -749,7 +759,7 @@ s32 mFI_GetWaveUtinBlock(s32* arg0, s32* arg1, s32 arg2, s32 arg3) {
for (i = 0; i < 0x100; i++) {
- if (func_80076358_jp(var_s1->data.unk6) == 1) {
+ if (func_80076358_jp(var_s1->data.unitAttribute) == 1) {
var_s3 += 1;
}
@@ -762,7 +772,7 @@ s32 mFI_GetWaveUtinBlock(s32* arg0, s32* arg1, s32 arg2, s32 arg3) {
for (i = 0; i < 0x100; i++) {
- if (func_80076358_jp(var_s1->data.unk6) == 1) {
+ if (func_80076358_jp(var_s1->data.unitAttribute) == 1) {
if (var_s2 <= 0) {
arg0[0] = i & 0xF;
diff --git a/src/code/m_npc.c b/src/code/m_npc.c
index 7320eb9..deb9a3c 100644
--- a/src/code/m_npc.c
+++ b/src/code/m_npc.c
@@ -3563,7 +3563,8 @@ s32 mNpc_CheckNpcSet(s32 bx, s32 bz, s32 ut_x, s32 ut_z) {
s32 res = FALSE;
if (collision != NULL && items != NULL) {
- res = mNpc_CheckNpcSet_fgcol(items[ut_z * UT_X_NUM + ut_x], collision[ut_z * UT_X_NUM + ut_x].data.unk6);
+ res =
+ mNpc_CheckNpcSet_fgcol(items[ut_z * UT_X_NUM + ut_x], collision[ut_z * UT_X_NUM + ut_x].data.unitAttribute);
}
return res;
@@ -3595,7 +3596,7 @@ s32 mNpc_GetMakeUtNuminBlock_hard_area(s32* utX, s32* utZ, s32 bx, s32 bz, s32 r
for (i = restrictArea; i < UT_Z_NUM - restrictArea; i++) {
for (j = restrictArea; j < UT_X_NUM - restrictArea; j++) {
idx = i * UT_X_NUM + j;
- if (mNpc_CheckNpcSet_fgcol_hard(items[idx], col[idx].data.unk6) == TRUE) {
+ if (mNpc_CheckNpcSet_fgcol_hard(items[idx], col[idx].data.unitAttribute) == TRUE) {
if (col[idx].data.unk1 == col[idx].data.unk2 && col[idx].data.unk1 == col[idx].data.unk3 &&
col[idx].data.unk1 == col[idx].data.unk4 && col[idx].data.unk1 == col[idx].data.unk5) {
nowUtX = 8 - j;
@@ -3645,7 +3646,7 @@ s32 mNpc_GetMakeUtNuminBlock_area(s32* utX, s32* utZ, s32 bx, s32 bz, s32 restri
if (fgTop != NULL && col != NULL) {
for (i = restrictArea; i < UT_Z_NUM - restrictArea; i++) {
for (j = restrictArea; j < UT_X_NUM - restrictArea; j++) {
- if (mNpc_CheckNpcSet_fgcol(fgTop[i * UT_X_NUM + j], col[i * UT_X_NUM + j].data.unk6) == TRUE) {
+ if (mNpc_CheckNpcSet_fgcol(fgTop[i * UT_X_NUM + j], col[i * UT_X_NUM + j].data.unitAttribute) == TRUE) {
*fgPtr |= 1 << j;
candidates++;
}
diff --git a/src/code/m_random_field.c b/src/code/m_random_field.c
new file mode 100644
index 0000000..4de9980
--- /dev/null
+++ b/src/code/m_random_field.c
@@ -0,0 +1,883 @@
+#include "global.h"
+#include "m_common_data.h"
+#include "m_random_field.h"
+#include "m_field_make.h"
+#include "m_field_info.h"
+#include "m_scene_table.h"
+#include "m_malloc.h"
+#include "gamealloc.h"
+#include "game.h"
+#include "ovlmgr.h"
+#include "segment_symbols.h"
+
+// Original name unknown. Pointer to malloc'd memory in mRF_MakeRandomField
+UNK_PTR mRF_AllocatedBuf = NULL;
+
+// Original name unknown.
+void* mRF_Malloc(Game* game, size_t size) {
+ if (game != NULL) {
+ return gamealloc_malloc(&game->alloc, size);
+ }
+
+ return zelda_malloc(size);
+}
+
+// Original name unknown.
+void mRF_Free(Game* game, void* ptr) {
+ if (ptr != NULL) {
+ if (game != NULL) {
+ gamealloc_free(&game->alloc, ptr);
+
+ return;
+ }
+
+ zelda_free(ptr);
+ }
+}
+
+// Original name unknown
+s32 stepNo = 0;
+
+// Get pointer to stepNo
+s32* mRF_StepNo(void) {
+ return &stepNo;
+}
+
+// Original name unknown
+s32 tryCnt = 0;
+
+// Get pointer to tryCnt
+s32* mRF_TryCnt(void) {
+ return &tryCnt;
+}
+
+// Original name unknown
+const char* mRF_DebugMsg[] = { "BGFGショキカ", "カワガケセイセイ", "ウミセイセイ", "ハシサカセイセイ", "コウバンヒロバセイセイ", "ミセユウビンキョクセイセイ",
+ "イケセイセ", "ベースセッテイ", "ウミニカワセイセイ", "ブロックセンタク", "ランダムカンリョウ" };
+
+void mRF_PrintDebug(gfxprint* gfxprint) {
+ gfxprint_color(gfxprint, 200, 200, 250, 255);
+ gfxprint_locate8x8(gfxprint, 3, 21);
+ gfxprint_printf(gfxprint, "RandomTry %d", tryCnt);
+ gfxprint_color(gfxprint, 200, 200, 250, 255);
+ gfxprint_locate8x8(gfxprint, 3, 22);
+ gfxprint_printf(gfxprint, "RandomStep %s", mRF_DebugMsg[stepNo]);
+}
+
+#if 1
+// clang-format off
+// Provided indices correspond to block type, not struct size
+u32 mRF_block_info[mFM_BLOCK_TYPE_NUM] = {
+ /* 0x00 */ mRF_BLOCKKIND_BORDER,
+ /* 0x01 */ mRF_BLOCKKIND_BORDER,
+ /* 0x02 */ mRF_BLOCKKIND_BORDER,
+ /* 0x03 */ mRF_BLOCKKIND_BORDER,
+ /* 0x04 */ mRF_BLOCKKIND_BORDER,
+ /* 0x05 */ mRF_BLOCKKIND_BORDER,
+ /* 0x06 */ mRF_BLOCKKIND_BORDER,
+ /* 0x07 */ mRF_BLOCKKIND_BORDER,
+ /* 0x08 */ mRF_BLOCKKIND_BORDER,
+ /* 0x09 */ mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_TUNNEL,
+ /* 0x0A */ mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_TUNNEL,
+ /* 0x0B */ mRF_BLOCKKIND_STATION | mRF_BLOCKKIND_RAILROAD,
+ /* 0x0C */ mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_DUMP,
+ /* 0x0D */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RAILROAD,
+ /* 0x0E */ mRF_BLOCKKIND_PLAYER,
+ /* 0x0F */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_CLIFF0,
+ /* 0x10 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_CLIFF1,
+ /* 0x11 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_CLIFF2,
+ /* 0x12 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_CLIFF3,
+ /* 0x13 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_CLIFF4,
+ /* 0x14 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_CLIFF5,
+ /* 0x15 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_CLIFF6,
+ /* 0x16 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER0 | mRF_BLOCKKIND_CLIFF0,
+ /* 0x17 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER1 | mRF_BLOCKKIND_CLIFF0,
+ /* 0x18 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER0 | mRF_BLOCKKIND_CLIFF2,
+ /* 0x19 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER0 | mRF_BLOCKKIND_CLIFF3,
+ /* 0x1A */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER0 | mRF_BLOCKKIND_CLIFF4,
+ /* 0x1B */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER0 | mRF_BLOCKKIND_CLIFF5,
+ /* 0x1C */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER0 | mRF_BLOCKKIND_CLIFF6,
+ /* 0x1D */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER1 | mRF_BLOCKKIND_CLIFF0,
+ /* 0x1E */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER1 | mRF_BLOCKKIND_CLIFF1,
+ /* 0x1F */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER1 | mRF_BLOCKKIND_CLIFF2,
+ /* 0x20 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER1 | mRF_BLOCKKIND_CLIFF3,
+ /* 0x21 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER1 | mRF_BLOCKKIND_CLIFF4,
+ /* 0x22 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER2 | mRF_BLOCKKIND_CLIFF0,
+ /* 0x23 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER2 | mRF_BLOCKKIND_CLIFF3,
+ /* 0x24 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER2 | mRF_BLOCKKIND_CLIFF4,
+ /* 0x25 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER2 | mRF_BLOCKKIND_CLIFF5,
+ /* 0x26 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_WATERFALL | mRF_BLOCKKIND_RIVER2 | mRF_BLOCKKIND_CLIFF6,
+ /* 0x27 */ mRF_BLOCKKIND_NONE,
+ /* 0x28 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER0,
+ /* 0x29 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER1,
+ /* 0x2A */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER2,
+ /* 0x2B */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER3,
+ /* 0x2C */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER4,
+ /* 0x2D */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER5,
+ /* 0x2E */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_RIVER6,
+ /* 0x2F */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER0,
+ /* 0x30 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER1,
+ /* 0x31 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER2,
+ /* 0x32 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER3,
+ /* 0x33 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER4,
+ /* 0x34 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER5,
+ /* 0x35 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_RIVER6,
+ /* 0x36 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE | mRF_BLOCKKIND_CLIFF0,
+ /* 0x37 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE | mRF_BLOCKKIND_CLIFF1,
+ /* 0x38 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE | mRF_BLOCKKIND_CLIFF2,
+ /* 0x39 */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE | mRF_BLOCKKIND_CLIFF3,
+ /* 0x3A */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE | mRF_BLOCKKIND_CLIFF4,
+ /* 0x3B */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE | mRF_BLOCKKIND_CLIFF5,
+ /* 0x3C */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_SLOPE | mRF_BLOCKKIND_CLIFF6,
+ /* 0x3D */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_BORDER,
+ /* 0x3E */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_BORDER,
+ /* 0x3F */ mRF_BLOCKKIND_MARINE,
+ /* 0x40 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_CLIFF0,
+ /* 0x41 */ mRF_BLOCKKIND_SHOP,
+ /* 0x42 */ mRF_BLOCKKIND_SHRINE,
+ /* 0x43 */ mRF_BLOCKKIND_POSTOFFICE,
+ /* 0x44 */ mRF_BLOCKKIND_POLICE,
+ /* 0x45 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER0,
+ /* 0x46 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER1,
+ /* 0x47 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER2,
+ /* 0x48 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER3,
+ /* 0x49 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER4,
+ /* 0x4A */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER5,
+ /* 0x4B */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_POOL | mRF_BLOCKKIND_RIVER6,
+ /* 0x4C */ mRF_BLOCKKIND_BORDER,
+ /* 0x4D */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BORDER | mRF_BLOCKKIND_RIVER0,
+ /* 0x4E */ mRF_BLOCKKIND_CLIFF | mRF_BLOCKKIND_BORDER | mRF_BLOCKKIND_CLIFF0,
+ /* 0x4F */ mRF_BLOCKKIND_RAILROAD | mRF_BLOCKKIND_BORDER,
+ /* 0x50 */ mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_BORDER,
+ /* 0x51 */ mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_BORDER,
+ /* 0x52 */ mRF_BLOCKKIND_RIVER | mRF_BLOCKKIND_BRIDGE | mRF_BLOCKKIND_MARINE | mRF_BLOCKKIND_RIVER0,
+ /* 0x53 */ mRF_BLOCKKIND_NONE,
+};
+
+u8 gate_count_table[mRF_GATE_TYPE_NUM] = { 0, 1, 1, 2, 2, 3 };
+
+#define GATE_UT(z, x) ((((z)&0xF) << 4) | ((x)&0xF))
+#define GATE(z0, x0, z1, x1) \
+ { GATE_UT(z0, x0), GATE_UT(z1, x1) }
+
+RandomFieldGate gate1_type0_up[1] = { GATE(0, 7, 1, 7) };
+RandomFieldGate gate1_type0_lt[1] = { GATE(7, 0, 7, 1) };
+RandomFieldGate gate1_type0_dn[1] = { GATE(15, 7, 14, 7) };
+RandomFieldGate gate1_type0_rt[1] = { GATE(7, 15, 7, 14) };
+
+RandomFieldGate gate1_type1_up[1] = { GATE(0, 7, 1, 7) };
+RandomFieldGate gate1_type1_lt[1] = { GATE(9, 0, 9, 1) };
+RandomFieldGate gate1_type1_dn[1] = { GATE(15, 7, 14, 7) };
+RandomFieldGate gate1_type1_rt[1] = { GATE(9, 15, 9, 14) };
+
+RandomFieldGate gate2_type0_up[2] = { GATE(0, 5, 1, 5), GATE(0, 12, 1, 12) };
+RandomFieldGate gate2_type0_lt[2] = { GATE(5, 0, 5, 1), GATE(12, 0, 12, 1) };
+RandomFieldGate gate2_type0_dn[2] = { GATE(15, 5, 14, 5), GATE(15, 12, 14, 12) };
+RandomFieldGate gate2_type0_rt[2] = { GATE(5, 15, 5, 14), GATE(12, 15, 12, 14) };
+
+RandomFieldGate gate2_type1_up[2] = { GATE(0, 2, 1, 2), GATE(0, 11, 1, 11) };
+RandomFieldGate gate2_type1_lt[2] = { GATE(2, 0, 2, 1), GATE(11, 0, 11, 1) };
+RandomFieldGate gate2_type1_dn[2] = { GATE(15, 2, 14, 2), GATE(15, 11, 14, 11) };
+RandomFieldGate gate2_type1_rt[2] = { GATE(2, 15, 2, 14), GATE(11, 15, 11, 14) };
+
+RandomFieldGate gate3_type0_up[3] = { GATE(0, 2, 1, 2), GATE(0, 8, 1, 8), GATE(0, 12, 1, 12) };
+RandomFieldGate gate3_type0_lt[3] = { GATE(2, 0, 2, 1), GATE(8, 0, 8, 1), GATE(12, 0, 12, 1) };
+RandomFieldGate gate3_type0_dn[3] = { GATE(15, 2, 14, 2), GATE(15, 8, 14, 8), GATE(15, 12, 14, 12) };
+RandomFieldGate gate3_type0_rt[3] = { GATE(2, 15, 2, 14), GATE(8, 15, 8, 14), GATE(12, 15, 12, 14) };
+
+RandomFieldGate* mRF_gate_correct_info[mRF_GATE_TYPE_NUM][RANDOM_FIELD_DIRECT_NUM] = {
+ { NULL, NULL, NULL, NULL },
+ { gate1_type0_up, gate1_type0_lt, gate1_type0_dn, gate1_type0_rt },
+ { gate1_type1_up, gate1_type1_lt, gate1_type1_dn, gate1_type1_rt },
+ { gate2_type0_up, gate2_type0_lt, gate2_type0_dn, gate2_type0_rt },
+ { gate2_type1_up, gate2_type1_lt, gate2_type1_dn, gate2_type1_rt },
+ { gate3_type0_up, gate3_type0_lt, gate3_type0_dn, gate3_type0_rt },
+};
+
+// Order of gate types for each block is north, west, south, east.
+// Provided indices correspond to block type, not struct size
+u8 mRF_gate_info2[mFM_BLOCK_TYPE_NUM][RANDOM_FIELD_DIRECT_NUM] = {
+ /* 0x00 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x01 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x02 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x03 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x04 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x05 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x06 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x07 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x08 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x09 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x0A */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x0B */ {
+ mRF_GATE_NONE,
+ mRF_GATE1_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE1
+ },
+ /* 0x0C */ {
+ mRF_GATE_NONE,
+ mRF_GATE1_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE1
+ },
+ /* 0x0D */ {
+ mRF_GATE_NONE,
+ mRF_GATE1_TYPE1,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE1
+ },
+ /* 0x0E */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x0F */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x10 */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x11 */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x12 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x13 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x14 */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x15 */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x16 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x17 */ {
+ mRF_GATE3_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x18 */ {
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x19 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x1A */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x1B */ {
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x1C */ {
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x1D */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0
+ },
+ /* 0x1E */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x1F */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x20 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE0,
+ mRF_GATE3_TYPE0
+ },
+ /* 0x21 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x22 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0
+ },
+ /* 0x23 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE0,
+ mRF_GATE3_TYPE0
+ },
+ /* 0x24 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x25 */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x26 */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE3_TYPE0
+ },
+ /* 0x27 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x28 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x29 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x2A */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x2B */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x2C */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x2D */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x2E */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x2F */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x30 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x31 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x32 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x33 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x34 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x35 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x36 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x37 */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x38 */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x39 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x3A */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x3B */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x3C */ {
+ mRF_GATE2_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE0
+ },
+ /* 0x3D */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x3E */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x3F */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE_NONE,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x40 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE_NONE,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x41 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE1
+ },
+ /* 0x42 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x43 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE1
+ },
+ /* 0x44 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x45 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x46 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x47 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x48 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x49 */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x4A */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x4B */ {
+ mRF_GATE1_TYPE0,
+ mRF_GATE1_TYPE0,
+ mRF_GATE2_TYPE1,
+ mRF_GATE2_TYPE1
+ },
+ /* 0x4C */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x4D */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x4E */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x4F */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x50 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x51 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ },
+ /* 0x52 */ {
+ mRF_GATE2_TYPE1,
+ mRF_GATE1_TYPE0,
+ mRF_GATE_NONE,
+ mRF_GATE1_TYPE0
+ },
+ /* 0x53 */ {
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE,
+ mRF_GATE_NONE
+ }
+};
+// clang-format on
+#endif
+
+extern void mRF_MakeRandomField_ovl(FieldMakeCombination* combi_table, FieldMakeComboInfo* combi_info, s32 combi_count,
+ Game* game);
+typedef void (*MakeRandomFieldOvlFunc)(FieldMakeCombination* combi_table, FieldMakeComboInfo* combi_info,
+ s32 combi_count);
+
+void mRF_MakeRandomField(FieldMakeCombination* combi_table, FieldMakeComboInfo* combi_info, s32 combi_count,
+ Game* game) {
+ MakeRandomFieldOvlFunc functionPtr;
+ size_t bufferSize = SEGMENT_VRAM_SIZE(m_random_field_ovl);
+
+ mRF_AllocatedBuf = mRF_Malloc(game, bufferSize);
+ stepNo = 0;
+ tryCnt = 0;
+
+ if (mRF_AllocatedBuf != NULL) {
+ ovlmgr_Load(SEGMENT_ROM_START(m_random_field_ovl), SEGMENT_ROM_END(m_random_field_ovl),
+ SEGMENT_VRAM_START(m_random_field_ovl), SEGMENT_VRAM_END(m_random_field_ovl), mRF_AllocatedBuf);
+ functionPtr = (MakeRandomFieldOvlFunc)SEGMENT_VRAM_RESOLVE_ADDR(m_random_field_ovl, mRF_AllocatedBuf,
+ mRF_MakeRandomField_ovl);
+ functionPtr(combi_table, combi_info, combi_count);
+ mRF_Free(game, mRF_AllocatedBuf);
+ }
+}
+
+u32 mRF_Type2BlockInfo(u8 blockType) {
+ if (blockType < mFM_BLOCK_TYPE_NUM) {
+ return mRF_block_info[blockType];
+ }
+
+ return mRF_BLOCKKIND_NONE;
+}
+
+/* @unused */
+u8 mRF_Info2BlockType(u32 blockInfo) {
+ s32 blockType = 0;
+
+ for (blockType = 0; blockType < mFM_BLOCK_TYPE_NUM; blockType += 1) {
+ if (blockInfo == mRF_block_info[blockType]) {
+ return (u8)blockType;
+ }
+ }
+
+ return mFM_BLOCK_TYPE_NONE;
+}
+
+s32 mRF_GateType2GateCount(s32 gateType) {
+
+ if (gateType < mRF_GATE_TYPE_NUM) {
+ return gate_count_table[gateType];
+ }
+
+ return 0;
+}
+
+s32 mRF_SearchPond(s32* utX, s32* utZ, s32 blockX, s32 blockZ) {
+ FieldMakeBGSoundSource* soundSourceInfo = mFI_GetSoundSourcePBlockNum(blockX, blockZ);
+
+ if (soundSourceInfo != NULL) {
+ s32 i;
+
+ for (i = 0; i < mFI_NUM_SOUND_SOURCES; i++, soundSourceInfo++) {
+ if (soundSourceInfo->kind == mFI_SOUND_SOURCE_POND) {
+ if (mFI_Wpos2UtNum(utX, utZ, soundSourceInfo->pos)) {
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+s32 mRF_Attr2BeastRoadAttr(s32 attribute) {
+ switch (attribute) {
+ case mCoBG_ATTRIBUTE_GRASS0:
+ case mCoBG_ATTRIBUTE_GRASS1:
+ return mCoBG_ATTRIBUTE_GRASS2;
+
+ case mCoBG_ATTRIBUTE_SOIL0:
+ case mCoBG_ATTRIBUTE_SOIL1:
+ return mCoBG_ATTRIBUTE_SOIL2;
+
+ default:
+ return attribute;
+ }
+}
+
+s32 mRF_BlockTypeDirect2GateType(u8 block_type, s32 direct) {
+ return mRF_gate_info2[block_type][direct];
+}
+
+RandomFieldGate* mRF_BlockTypeDirect2GateData(s32* gateCount, u8 blockType, s32 direct) {
+ s32 type = mRF_BlockTypeDirect2GateType(blockType, direct);
+ s32 count = mRF_GateType2GateCount(type);
+
+ *gateCount = count;
+ return mRF_gate_correct_info[type][direct];
+}
+
+s32 mRF_BlockInf2CheckBeastRoad(u8 blockType, mCoBG_unkStructUnion* collisionData) {
+ // fairly specific variable declaration order required for match
+ s32 colUt;
+ s32 gateCount;
+ s32 i;
+ s32 j;
+ u32 attrib;
+ mCoBG_unkStructUnion* col;
+ RandomFieldGate* gateP;
+
+ s32 changedAttributeCount = 0;
+ xyz_t wpos = { 0.0f, 0.0f, 0.0f };
+
+ for (i = 0; i < RANDOM_FIELD_DIRECT_NUM; i++) {
+ gateP = mRF_BlockTypeDirect2GateData(&gateCount, blockType, i);
+
+ if (gateP != NULL) {
+ for (j = 0; j < gateCount; j++) {
+ /* process first unit */
+ {
+ colUt = gateP[j].ut0;
+ col = collisionData + (u8)colUt;
+ attrib = col->data.unitAttribute;
+
+ mFI_UtNum2CenterWpos(&wpos, colUt & 0xF, (colUt >> 4) & 0xF);
+
+ /* only bother updating the unit attribute if the unit can grow collideable plants in it */
+ if (mCoBG_Attribute2CheckPlant(attrib, &wpos) > 0) {
+ col->data.unitAttribute = mRF_Attr2BeastRoadAttr(attrib);
+ changedAttributeCount++;
+ }
+ }
+
+ /* process second unit */
+ {
+ colUt = gateP[j].ut1;
+ col = collisionData + (u8)colUt;
+ attrib = col->data.unitAttribute;
+
+ mFI_UtNum2CenterWpos(&wpos, colUt & 0xF, (colUt >> 4) & 0xF);
+
+ /* only bother updating the unit attribute if the unit can grow collideable plants in it */
+ if (mCoBG_Attribute2CheckPlant(attrib, &wpos) > 0) {
+ col->data.unitAttribute = mRF_Attr2BeastRoadAttr(attrib);
+ changedAttributeCount++;
+ }
+ }
+ }
+ }
+ }
+
+ // Note that although these return values are required to match,
+ // they don't appear to be used by calling code.
+ if (changedAttributeCount != 0) {
+ return 0;
+ }
+
+ return 1;
+}
+
+void mRF_CheckBeastRoad() {
+ if (SAVE_GET(sceneNo) == SCENE_FG) {
+ s32 blockXMax = mFI_GetBlockXMax() - 1;
+ s32 blockZMax = mFI_GetBlockZMax() - 1;
+ s32 blockX;
+ s32 blockZ;
+
+ for (blockZ = 1; blockZ < blockZMax; blockZ++) {
+ for (blockX = 1; blockX < blockXMax; blockX++) {
+ mCoBG_unkStructUnion* collisionData = mFI_GetBkNum2ColTop(blockX, blockZ);
+ u8 type = mFI_BkNum2BlockType(blockX, blockZ);
+
+ mRF_BlockInf2CheckBeastRoad(type, collisionData);
+ }
+ }
+ }
+}