From a4d5910cdb9bed05fa5aea4476a3cf4ef178be06 Mon Sep 17 00:00:00 2001 From: kuchenmitsahne <25233413+kuchenmitsahne@users.noreply.github.com> Date: Wed, 4 Jun 2025 19:38:23 -0400 Subject: m_random_field OK (#241) * 25 functions OK * 10 functions OK * Add block type and block kind enums/defines * Formatting/style pass * Move `FieldMakeBlockType` to `m_field_make` * Remove unused/duplicate defines * Split data out for `m_quest` and `m_random_field`; rename data symbols * Generate `m_random_field.c` and rename function symbols. * mRF_BlockTypeDirect2GateType, mRF_BlockTypeDirect2GateData OK * mRF_Type2BlockInfo, mRF_Info2BlockType, mRF_GateType2GateCount, mRF_SearchPond, mRF_Attr2BeastRoadAttr, mRF_CheckBeastRoad OK * mFI_GetUnitCol OK; mRF_PrintDebug and mRF_BlockInf2CheckBeastRoad OK (pending data import). * Fix `m_random_field` code split; all newly included functions OK * Fix mRF_Malloc return type; formatting pass * Name m_random_field_ovl * Rename data symbols (m_random_field_ovl). * Rename symbols (all functions named) * Import data * Declare overlay segment; rename symbols * mRF_MakeRandomField OK (all functions matching). * Extract asset `data_combi_table` * Clean up mRF_MakeRandomField; document m_field_make.h * Rename mCoBG_unkStruct->unk6 as unitAttribute * Misc cleanup and formatting. * Rename additional data symbols (m_random_field_ovl). * Formatting pass * Improve documentation of BackgroundAttribute enum. * Formatting pass; add omitted attribute. --- src/code/m_field_info.c | 20 +- src/code/m_npc.c | 7 +- src/code/m_random_field.c | 883 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 902 insertions(+), 8 deletions(-) create mode 100644 src/code/m_random_field.c (limited to 'src/code') 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); + } + } + } +} -- cgit v1.2.3