summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/m_collision_bg.h141
-rw-r--r--include/m_common_data.h8
-rw-r--r--include/m_field_info.h17
-rw-r--r--include/m_field_make.h46
-rw-r--r--include/m_random_field.h44
-rw-r--r--include/segment_symbols.h2
-rw-r--r--include/tables/dmatables/dmadata_table_jp.h6
-rw-r--r--linker_scripts/jp/ignored_addresses.txt2
-rw-r--r--linker_scripts/jp/symbol_addrs_assets.txt3
-rw-r--r--linker_scripts/jp/symbol_addrs_code.txt102
-rw-r--r--linker_scripts/jp/symbol_addrs_overlays.txt120
-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
-rw-r--r--src/combi/data_combi.c6
-rw-r--r--src/combi/data_combi.h8
-rw-r--r--tools/splat_ext/combi.py52
-rw-r--r--yamls/jp/assets.yaml17
-rw-r--r--yamls/jp/code.yaml7
-rw-r--r--yamls/jp/overlays.yaml18
20 files changed, 1319 insertions, 190 deletions
diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h
index 9401fda..9e5d84e 100644
--- a/include/m_collision_bg.h
+++ b/include/m_collision_bg.h
@@ -8,7 +8,87 @@
struct Actor;
struct PosRot;
-enum BackgroundAttribute { mCoBG_ATTRIBUTE_0, mCOBG_ATTRIBUTE_NONE = 100 };
+// TODO: focus further investigation on attributes WATER, 30, HOLE, WAVE, 59-63, and NONE
+enum BackgroundAttribute {
+ /* 000 */ mCoBG_ATTRIBUTE_GRASS0,
+ /* 001 */ mCoBG_ATTRIBUTE_GRASS1,
+ /* 002 */ mCoBG_ATTRIBUTE_GRASS2,
+ /* 003 */ mCoBG_ATTRIBUTE_GRASS3,
+ /* 004 */ mCoBG_ATTRIBUTE_SOIL0,
+ /* 005 */ mCoBG_ATTRIBUTE_SOIL1,
+ /* 006 */ mCoBG_ATTRIBUTE_SOIL2,
+ /* 007 */ mCoBG_ATTRIBUTE_STONE, // stone path (not individual rocks)
+ /* 008 */ mCoBG_ATTRIBUTE_FLOOR, // seems to occupy all units in bottom row
+ /* 009 */ mCoBG_ATTRIBUTE_BUSH,
+
+ /* 010 */ mCoBG_ATTRIBUTE_HOLE, // unconfirmed (from ac-decomp)
+ /* 011 */ mCoBG_ATTRIBUTE_WAVE, // unconfirmed (from ac-decomp)
+
+ /* 012 */ mCoBG_ATTRIBUTE_WATER, // only used in small pond?
+ /* 013 */ mCoBG_ATTRIBUTE_WATERFALL,
+ /* 014 */ mCoBG_ATTRIBUTE_RIVER_N,
+ /* 015 */ mCoBG_ATTRIBUTE_RIVER_NW,
+ /* 016 */ mCoBG_ATTRIBUTE_RIVER_W,
+ /* 017 */ mCoBG_ATTRIBUTE_RIVER_SW,
+ /* 018 */ mCoBG_ATTRIBUTE_RIVER_S,
+ /* 019 */ mCoBG_ATTRIBUTE_RIVER_SE,
+ /* 020 */ mCoBG_ATTRIBUTE_RIVER_E,
+ /* 021 */ mCoBG_ATTRIBUTE_RIVER_NE,
+
+ /* 022 */ mCoBG_ATTRIBUTE_SAND,
+ /* 023 */ mCoBG_ATTRIBUTE_WOOD, // fences (train tracks/dump), large signs, bridge edges
+ /* 024 */ mCoBG_ATTRIBUTE_SEA, // only seems to appear in row with beach
+ /* 025 */ mCoBG_ATTRIBUTE_SHALLOW0_NW, // shallower diagonal sea shallows, sea to SE
+ /* 026 */ mCoBG_ATTRIBUTE_SHALLOW0_NE, // shallower diagonal sea shallows, sea to SW
+
+ /* 027 */ mCoBG_ATTRIBUTE_BRIDGE_NW, // diagonal bridge, river to NW
+ /* 028 */ mCoBG_ATTRIBUTE_BRIDGE_END, // "bridge" unit that ends above water (i.e. a pier)
+ /* 029 */ mCoBG_ATTRIBUTE_BRIDGE_SE, // diagonal bridge, river to SE
+ /* 030 */ mCoBG_ATTRIBUTE_30,
+ /* 031 */ mCoBG_ATTRIBUTE_BRIDGE_C, // diagonal bridge's central unit
+ /* 032 */ mCoBG_ATTRIBUTE_BRIDGE_N, // horizontal bridge, river/tracks to north (stone?)
+ /* 033 */ mCoBG_ATTRIBUTE_BRIDGE_E, // vertical bridge/steps, river/grass to east
+ /* 034 */ mCoBG_ATTRIBUTE_BRIDGE_W, // vertical bridge/steps, river/grass to west
+ /* 035 */ mCoBG_ATTRIBUTE_BRIDGE_S, // horizontal bridge, river to south
+
+ /* 036 */ mCoBG_ATTRIBUTE_SHALLOW1_S, // deeper horizontal sea shallows, sea to south
+ /* 037 */ mCoBG_ATTRIBUTE_SHALLOW1_NW, // deeper diagonal sea shallows, sea to SE
+ /* 038 */ mCoBG_ATTRIBUTE_SHALLOW1_NE, // deeper diagonal sea shallows, sea to SW
+
+ /* 039 */ mCoBG_ATTRIBUTE_BANK_SE, // diagonal riverbank, river to NW
+ /* 040 */ mCoBG_ATTRIBUTE_BANK_NE, // diagonal riverbank, river to SW
+ /* 041 */ mCoBG_ATTRIBUTE_BANK_NW, // diagonal riverbank, river to SE
+ /* 042 */ mCoBG_ATTRIBUTE_BANK_SW, // diagonal riverbank, river to NE
+ /* 043 */ mCoBG_ATTRIBUTE_BANK_N, // horizontal riverbank, river to north
+ /* 044 */ mCoBG_ATTRIBUTE_BANK_W, // vertical riverbank, river to east
+ /* 045 */ mCoBG_ATTRIBUTE_BANK_E, // vertical riverbank, river to west
+ /* 046 */ mCoBG_ATTRIBUTE_BANK_S, // horizontal riverbank, river to south
+
+ /* 047 */ mCoBG_ATTRIBUTE_CLIFF_S, // vertical cliff edge, valley to north (only in south tunnel wall?)
+ /* 048 */ mCoBG_ATTRIBUTE_CLIFF_W, // vertical cliff edge, valley to west
+ /* 049 */ mCoBG_ATTRIBUTE_CLIFF_E, // vertical cliff edge, valley to west
+ /* 050 */ mCoBG_ATTRIBUTE_CLIFF_N, // horizontal cliff edge, valley to south (also appears in north tunnel wall)
+
+ /* 051 */ mCoBG_ATTRIBUTE_TUNNEL_E_S, // east tunnel entrance, south corner
+ /* 052 */ mCoBG_ATTRIBUTE_TUNNEL_E_N, // east tunnel entrance, north corner
+ /* 053 */ mCoBG_ATTRIBUTE_TUNNEL_W_N, // west tunnel entrance, north corner
+ /* 054 */ mCoBG_ATTRIBUTE_TUNNEL_W_S, // west tunnel entrance, south corner
+
+ /* 055 */ mCoBG_ATTRIBUTE_CLIFF_SE, // diagonal cliff edge, valley to NW
+ /* 056 */ mCoBG_ATTRIBUTE_CLIFF_NE, // diagonal cliff edge, valley to SW
+ /* 057 */ mCoBG_ATTRIBUTE_CLIFF_NW, // diagonal cliff edge, valley to SE
+ /* 058 */ mCoBG_ATTRIBUTE_CLIFF_SW, // diagonal cliff edge, valley to NE
+
+ /* 059 */ mCoBG_ATTRIBUTE_BANK_WN, // corner riverbank, river/pond to north and west (need more data)
+ /* 060 */ mCoBG_ATTRIBUTE_BANK_UNK, // corner riverbank, unsure (found at beach on mini cliff with SAND to west,
+ // BANK_NE to east, BANK_E to north, SHALLOW1_NW to south)
+
+ /* 061 */ mCoBG_ATTRIBUTE_61,
+ /* 062 */ mCoBG_ATTRIBUTE_62,
+ /* 063 */ mCoBG_ATTRIBUTE_63, // appears very sparingly at soil-grass boundaries
+
+ /* 100 */ mCoBG_ATTRIBUTE_NONE = 100, // unconfirmed (from ac-decomp)
+};
// offset table
typedef struct mCoBG_unkStruct2 {
@@ -21,16 +101,18 @@ typedef struct mCoBG_unkStruct2 {
/* 0x06 */ s8 unk6;
} mCoBG_unkStruct2; // size = 0x7
+// clang-format off
// collision bg data
typedef struct mCoBG_unkStruct {
- /* 0x0 */ u32 unk0:1; // [31] shape
- /* 0x0 */ u32 unk1:5; // [30:25] center
- /* 0x0 */ u32 unk2:5; // [25:20] top_left
- /* 0x0 */ u32 unk3:5; // [20:15] bot_left
- /* 0x0 */ u32 unk4:5; // [15:10] top_right
- /* 0x0 */ u32 unk5:5; // [10:5] bot_right
- /* 0x0 */ u32 unk6:6; // [5:0] unit_attribute
+ /* 0x0 */ u32 unk0 : 1; // [31] shape
+ /* 0x0 */ u32 unk1 : 5; // [30:25] center
+ /* 0x0 */ u32 unk2 : 5; // [25:20] top_left
+ /* 0x0 */ u32 unk3 : 5; // [20:15] bot_left
+ /* 0x0 */ u32 unk4 : 5; // [15:10] top_right
+ /* 0x0 */ u32 unk5 : 5; // [10:5] bot_right
+ /* 0x0 */ u32 unitAttribute : 6; // [5:0] unit_attribute
} mCoBG_unkStruct; // size = 0x4
+// clang-format on
typedef union mCoBG_unkStructUnion {
mCoBG_unkStruct data;
@@ -62,30 +144,32 @@ typedef struct mCoBG_WallInfo {
* | ________ ________ ________ ___X____ | 0x1B | unk12
* | ________ ________ ________ ____XXXX | 0x1C | unk13
*/
+// clang-format off
typedef struct mCoBG_CheckResult {
- u32 onGround : 1; // on_ground
- u32 unk1 : 5; // hit_attribute_wall
- u32 hitWall : 5; // hit_wall
- u32 unk3 : 3; // hit_wall_count
- u32 unk4 : 1; // unk_flag0
- u32 unk5 : 6; // unit_attribute
- u32 unk6 : 1; // is_on_move_bg_obj
- u32 inWater : 1; // is_in_water
- u32 unk8 : 1; // unk_flag1
- u32 unk9 : 1; // unk_flag2
- u32 unk10 : 1; // unk_flag3
- u32 unk11 : 1; // unk_flag4
- u32 unk12 : 1; // unk_flag5
- u32 unk13 : 4; // unk_flag6
+ u32 onGround : 1; // on_ground
+ u32 unk1 : 5; // hit_attribute_wall
+ u32 hitWall : 5; // hit_wall
+ u32 unk3 : 3; // hit_wall_count
+ u32 unk4 : 1; // unk_flag0
+ u32 unk5 : 6; // unit_attribute
+ u32 unk6 : 1; // is_on_move_bg_obj
+ u32 inWater : 1; // is_in_water
+ u32 unk8 : 1; // unk_flag1
+ u32 unk9 : 1; // unk_flag2
+ u32 unk10 : 1; // unk_flag3
+ u32 unk11 : 1; // unk_flag4
+ u32 unk12 : 1; // unk_flag5
+ u32 unk13 : 4; // unk_flag6
} mCoBG_CheckResult;
+// clang-format on
-typedef struct mCoBG_Check{
+typedef struct mCoBG_Check {
/* 0x00 */ u8 unk0[0x11];
/* 0x14 */ mCoBG_CheckResult colResult;
/* 0x18 */ u8 unk18[0xC];
/* 0x24 */ mCoBG_WallInfo wallInfo[2];
/* 0x2C */ s16 unk2C;
-}mCoBG_Check; // size = 0x30
+} mCoBG_Check; // size = 0x30
// void func_80067430_jp();
// void func_800674B0_jp();
@@ -172,9 +256,10 @@ typedef struct mCoBG_Check{
// void func_8006B5C0_jp();
// void func_8006B664_jp();
// void func_8006B92C_jp();
-s32 mCoBG_RegistMoveBg(s8 *arg0, struct PosRot *arg1, xyz_t *arg2, s16 *arg3, f32 arg4, s32 arg5, s32 arg6, s32 arg7, s32 arg8, s32 arg9, s32 argA, f32 argB);
+s32 mCoBG_RegistMoveBg(s8* arg0, struct PosRot* arg1, xyz_t* arg2, s16* arg3, f32 arg4, s32 arg5, s32 arg6, s32 arg7,
+ s32 arg8, s32 arg9, s32 argA, f32 argB);
// void func_8006BAA8_jp();
-void mCoBG_CrossOffMoveBg(s32 arg0, struct Actor *actor);
+void mCoBG_CrossOffMoveBg(s32 arg0, struct Actor* actor);
void func_8006BB64_jp(void);
// void func_8006BB9C_jp();
// void func_8006BBE8_jp();
@@ -245,7 +330,7 @@ void func_8006C8D0_jp(void);
// void func_80071064_jp();
// void func_800713CC_jp();
// void func_80071460_jp();
-f32 mCoBG_GetShadowBgY_AngleS_FromWpos(s_xyz*, xyz_t,f32);
+f32 mCoBG_GetShadowBgY_AngleS_FromWpos(s_xyz*, xyz_t, f32);
// void func_800715B4_jp();
// void func_80071604_jp();
// void func_80071728_jp();
@@ -259,7 +344,7 @@ void mCoBG_GetBgNorm_FromWpos(xyz_t*, xyz_t);
// void func_800721C8_jp();
// void func_800721E4_jp();
// void func_80072238_jp();
-// void func_80072264_jp();
+s32 mCoBG_Attribute2CheckPlant(u32 attribute, const xyz_t* wpos); // void func_80072264_jp();
// void func_80072340_jp();
// void func_80072398_jp();
// void func_800723C4_jp();
diff --git a/include/m_common_data.h b/include/m_common_data.h
index 23836cd..5223795 100644
--- a/include/m_common_data.h
+++ b/include/m_common_data.h
@@ -19,6 +19,14 @@
#include "m_scene.h"
#include "m_demo.h"
+#define COMMON_GET(name) (common_data.name)
+#define COMMON_GET_POINTER(name) (&common_data.name)
+#define COMMON_SET(name, value) (common_data.name = (value))
+
+#define SAVE_GET(name) (COMMON_GET(save.name))
+#define SAVE_GET_POINTER(name) (COMMON_GET_POINTER(save.name))
+#define SAVE_SET(name, value) (COMMON_SET(save.name, value))
+
typedef enum Season {
/* 0 */ SPRING,
/* 1 */ SUMMER,
diff --git a/include/m_field_info.h b/include/m_field_info.h
index a061f1a..56c13d6 100644
--- a/include/m_field_info.h
+++ b/include/m_field_info.h
@@ -40,6 +40,7 @@ struct Game;
#define FI_BK_WORLDSIZE_HALF_X_F (FI_BK_WORLDSIZE_X_F / 2.0f)
#define FI_BK_WORLDSIZE_HALF_Z_F (FI_BK_WORLDSIZE_Z_F / 2.0f)
+#define mFI_NUM_SOUND_SOURCES 6
typedef enum FieldType {
/* 0 */ FI_FIELDTYPE_FG,
@@ -49,10 +50,10 @@ typedef enum FieldType {
/* 4 */ FI_FIELDTYPE_NPC_ROOM,
/* 5 */ FI_FIELDTYPE_DEMO,
/* 6 */ FI_FIELDTYPE_PLAYER_ROOM,
+
/* 7 */ FI_FIELDTYPE_NUM
} FieldType;
-
#define FI_TO_FIELD_ID(type, index) (((type) << 12) | (index))
#define FI_GET_TYPE(id) ((id) & 0xF000)
@@ -83,6 +84,16 @@ typedef enum FieldDirection {
/* 5 */ FI_MOVEDIR_MAX
} FieldDirection;
+// TODO: confirm 0 through 2 (POND and NUM confirmed)
+typedef enum FieldSoundSource {
+ /* 0 */ mFI_SOUND_SOURCE_NONE,
+ /* 1 */ mFI_SOUND_SOURCE_RIVER,
+ /* 2 */ mFI_SOUND_SOURCE_OCEAN,
+ /* 3 */ mFI_SOUND_SOURCE_POND,
+
+ /* 4 */ mFI_SOUND_SOURCE_NUM
+} FieldSoundSource;
+
#define FI_GET_PLAYER_ROOM_NO(fieldId) (((fieldId)-FI_FIELD_PLAYER0_ROOM) & 3)
#define FI_IS_PLAYER_ROOM(fieldId) \
((fieldId) == FI_FIELD_PLAYER0_ROOM || (fieldId) == FI_FIELD_PLAYER1_ROOM || \
@@ -151,10 +162,10 @@ mCoBG_unkStructUnion* mFI_UtNum2UtCol(s32 utX, s32 utZ);
// void func_80089698_jp();
// void func_80089704_jp();
// void func_800897D0_jp();
-// void func_80089888_jp();
+mCoBG_unkStructUnion* mFI_GetUnitCol(xyz_t wpos);
// void func_800898F4_jp();
// void func_800899CC_jp();
-// void func_80089A34_jp();
+struct FieldMakeBGSoundSource* mFI_GetSoundSourcePBlockNum(s32 blockX, s32 blockZ);
// void func_80089AAC_jp();
// void func_80089B1C_jp();
// void func_80089B94_jp();
diff --git a/include/m_field_make.h b/include/m_field_make.h
index 695418d..45cf282 100644
--- a/include/m_field_make.h
+++ b/include/m_field_make.h
@@ -4,6 +4,8 @@
#include "ultra64.h"
#include "unk.h"
#include "m_collision_bg.h"
+#include "m_field_info.h"
+#include "other_types.h"
struct Game;
@@ -20,6 +22,10 @@ struct Game;
#define UT_Z_NUM UT_BASE_NUM /* Spaces per block (acre) in z direction */
#define UT_TOTAL_NUM (UT_X_NUM * UT_Z_NUM)
+#define mFM_SOUND_SOURCE_NUM 6
+#define mFM_MOVE_ACTOR_NUM 16
+#define mFM_HANIWA_STEP_NUM 4
+
/*
* Naming convention for `RIVER`/`POOL`: directions indicated are flow of river
* (e.g. `RIVER_SOUTH` indicates a river that flows south through entire block,
@@ -124,10 +130,21 @@ typedef enum FieldMakeBlockType {
extern u8* g_block_type_p;
extern u32* g_block_kind_p; // s32 in ac-decomp--if problems arise, try changing type
+typedef struct FieldMakeCombination {
+ /* 0x0 */ u16 combinationType : 14; /* acre type index into `data_combi_table` */
+ /* 0x0 */ u16 height : 2; /* 0, 1, 2, or 3 (unused) */
+} FieldMakeCombination; // size = 0x2
+
typedef struct Foreground {
/* 0x000 */ u16 items[UT_Z_NUM][UT_X_NUM];
} Foreground; // size = 0x200
+typedef struct FieldMakeComboInfo {
+ /* 0x00 */ u16 bgId; // perhaps should be `bgName`?
+ /* 0x02 */ u16 fgId; // perhaps should be `fgName`?
+ /* 0x05 */ u8 blockType;
+} FieldMakeComboInfo; // size = 0x6
+
typedef struct FieldMakeMoveActor {
/* 0x0 */ u16 nameId;
/* 0x2 */ s8 utX;
@@ -142,19 +159,36 @@ typedef struct FieldMakeFGData {
/* 0x202 */ UNK_TYPE1 unk_202[4];
} FieldMakeFGData; // size = 0x206
+typedef struct FieldMakeBGSoundSource {
+ /* 0x0 */ s16 kind;
+ /* 0x4 */ xyz_t pos;
+} FieldMakeBGSoundSource; // size = 0x10
+
typedef struct FieldMakeFGInfo {
/* 0x00 */ u16 fgId;
/* 0x04 */ u16* itemsPtr;
- /* 0x08 */ UNK_TYPE1 unk_08[0x8C];
+ /* 0x08 */ UNK_PTR unk_08; // ac-decomp: u16* deposit_p
+ /* 0x0C */ FieldMakeMoveActor moveActors[mFM_MOVE_ACTOR_NUM];
+ /* 0x8C */ UNK_TYPE2 unk_08C; // ac-decomp: u16 move_actor_bit_data
+ /* 0x8E */ u8 haniwaStep[mFM_HANIWA_STEP_NUM];
} FieldMakeFGInfo; // size = 0x94
+// TODO: come up with better names to disambiguate the union `bgId` (which contains height data)
+// from the plain u16 `bgId` used in `FieldMakeComboInfo`
typedef struct FieldMakeBGInfo {
- /* 0x000 */ UNK_TYPE1 unk_000[0x14];
+ /* 0x000 */ FieldMakeCombination bgId; // stores `bgName` + height of corresponding block type from `data_combi_table`
+ /* 0x004 */ UNK_PTR unk_004; // ac-decomp: Gfx* opaque_gfx
+ /* 0x008 */ UNK_PTR unk_008; // ac-decomp: Gfx* translucent_gfx
+ /* 0x00C */ UNK_PTR unk_00C; // ac-decomp: EvwAnimeData* animation
+ /* 0x010 */ UNK_TYPE1 unk_010; // ac-decomp: s8 animation_count
+ /* 0x011 */ u8 blockType;
/* 0x014 */ u32 blockKind;
- /* 0x018 */ UNK_TYPE1 unk_018[0x08];
+ /* 0x018 */ RomOffset romStartAddr;
+ /* 0x01C */ s32 romSize;
/* 0x020 */ mCoBG_unkStructUnion collision[UT_Z_NUM][UT_X_NUM];
- /* 0x420 */ UNK_TYPE1 unk_024[0x160];
-} FieldMakeBGInfo; // size >= 0x57d
+ /* 0x420 */ u8 unk_420[UT_Z_NUM][UT_X_NUM]; // ac-decomp: u8 keep_h (holds `center` bitfield from corresponding `collision` entries)
+ /* 0x520 */ FieldMakeBGSoundSource soundSource[mFM_SOUND_SOURCE_NUM];
+} FieldMakeBGInfo; // size = 0x580
typedef struct FieldMakeBlockInfo {
/* 0x000 */ FieldMakeBGInfo bgInfo;
@@ -164,7 +198,7 @@ typedef struct FieldMakeBlockInfo {
typedef struct FieldMakeInfo {
/* 0x000 */ u16 fieldId;
/* 0x002 */ UNK_TYPE1 unk_000[0x146];
- /* 0x148 */ FieldMakeBlockInfo* blockInfo;
+ /* 0x148 */ FieldMakeBlockInfo* blockInfo; // length: BLOCK_TOTAL_NUM
/* 0x14C */ UNK_TYPE1 unk_14C[0x1A];
/* 0x166 */ u8 blockXMax;
/* 0x167 */ u8 blockZMax;
diff --git a/include/m_random_field.h b/include/m_random_field.h
index 256edbb..3a9bdc6 100644
--- a/include/m_random_field.h
+++ b/include/m_random_field.h
@@ -2,6 +2,9 @@
#define M_RANDOM_FIELD_H
#include "ultra64.h"
+#include "m_collision_bg.h"
+#include "game.h"
+#include "m_field_make.h"
#define RANDOM_FIELD_DIRECT_ERROR 100
@@ -14,6 +17,17 @@ typedef enum RandomFieldDirection {
/* 4 */ RANDOM_FIELD_DIRECT_NUM
} RandomFieldDirection;
+typedef enum RandomFieldGateType {
+ /* 0 */ mRF_GATE_NONE,
+ /* 1 */ mRF_GATE1_TYPE0,
+ /* 2 */ mRF_GATE1_TYPE1,
+ /* 3 */ mRF_GATE2_TYPE0,
+ /* 4 */ mRF_GATE2_TYPE1,
+ /* 5 */ mRF_GATE3_TYPE0,
+
+ /* 6 */ mRF_GATE_TYPE_NUM
+} RandomFieldGateType;
+
typedef struct RandomFieldGate {
/* 0x00 */ s32 ut0;
/* 0x04 */ s32 ut1;
@@ -53,20 +67,20 @@ typedef struct RandomFieldGate {
#define mRF_BLOCKKIND_CLIFF6 (1 << 30) // Bottom part of cliff that juts out, valley on left
#define mRF_BLOCKKIND_31 (1 << 31) // Not used in `mRF_block_info`
-// void func_800BCBA0_jp();
-// void func_800BCBDC_jp();
-// void func_800BCC20_jp();
-// void func_800BCC30_jp();
-// void func_800BCC40_jp();
-// void func_800BCCFC_jp();
-s32 mRF_Type2BlockInfo(u8 type);
-// void func_800BCDFC_jp();
-// void func_800BCE80_jp();
-// void func_800BCEA4_jp();
-// void func_800BCF64_jp();
-// void func_800BCFA4_jp();
-RandomFieldGate* mRF_BlockTypeDirect2GateData(s32*, u8, s32);
-// void func_800BD02C_jp();
-// void func_800BD1E4_jp();
+// void* mRF_Malloc(Game* game, size_t size);
+// void mRF_Free(Game* game, void* ptr);
+s32* mRF_StepNo(void);
+s32* mRF_TryCnt(void);
+// void mRF_PrintDebug(gfxprint* gfxprint);
+void mRF_MakeRandomField(FieldMakeCombination* combi_table, FieldMakeComboInfo* combi_info, s32 combi_count, Game* game);
+u32 mRF_Type2BlockInfo(u8 blockType);
+// u8 mRF_Info2BlockType(u32 blockInfo);
+// s32 mRF_GateType2GateCount(s32 gateType);
+s32 mRF_SearchPond(s32* utX, s32* utZ, s32 blockX, s32 blockZ);
+// s32 mRF_Attr2BeastRoadAttr(s32 attribute);
+// s32 mRF_BlockTypeDirect2GateType(u8 blockType, s32 direct);
+RandomFieldGate* mRF_BlockTypeDirect2GateData(s32* gateCount, u8 blockType, s32 direct);
+// s32 mRF_BlockInf2CheckBeastRoad(u8 blockType, mCoBG_unkStructUnion* collisionData);
+void mRF_CheckBeastRoad();
#endif
diff --git a/include/segment_symbols.h b/include/segment_symbols.h
index bdea287..50d0a21 100644
--- a/include/segment_symbols.h
+++ b/include/segment_symbols.h
@@ -96,6 +96,8 @@ DECLARE_SEGMENT(ovl__0079F810);
DECLARE_SEGMENT(ovl__007A10E0);
DECLARE_SEGMENT(catalog_ovl);
+DECLARE_SEGMENT(m_random_field_ovl);
+
DECLARE_SEGMENT(ac_set_ovl_insect);
DECLARE_SEGMENT(ac_set_ovl_gyoei);
diff --git a/include/tables/dmatables/dmadata_table_jp.h b/include/tables/dmatables/dmadata_table_jp.h
index 733798b..b8df70f 100644
--- a/include/tables/dmatables/dmadata_table_jp.h
+++ b/include/tables/dmatables/dmadata_table_jp.h
@@ -116,8 +116,8 @@ DEFINE_DMA_ENTRY(ovl__00814FA0, "ovl__00814FA0")
DEFINE_DMA_ENTRY(ovl__00814FA0_reloc, "ovl__00814FA0_reloc")
DEFINE_DMA_ENTRY(ovl__00815B70, "ovl__00815B70")
DEFINE_DMA_ENTRY(ovl__00815B70_reloc, "ovl__00815B70_reloc")
-DEFINE_DMA_ENTRY(ovl__0081AA60, "ovl__0081AA60")
-DEFINE_DMA_ENTRY(ovl__0081AA60_reloc, "ovl__0081AA60_reloc")
+DEFINE_DMA_ENTRY(m_random_field_ovl, "m_random_field_ovl")
+DEFINE_DMA_ENTRY(m_random_field_ovl_reloc, "m_random_field_ovl_reloc")
DEFINE_DMA_ENTRY(ovl__0081D9D0, "ovl__0081D9D0")
DEFINE_DMA_ENTRY(ovl__0081D9D0_reloc, "ovl__0081D9D0_reloc")
DEFINE_DMA_ENTRY(ac_set_ovl_insect, "ac_set_ovl_insect")
@@ -2288,7 +2288,7 @@ DEFINE_DMA_ENTRY(segment_01148000, "segment_01148000")
DEFINE_DMA_ENTRY(segment_0114A000, "segment_0114A000")
DEFINE_DMA_ENTRY(segment_01188000, "segment_01188000")
DEFINE_DMA_ENTRY(segment_011AB000, "segment_011AB000")
-DEFINE_DMA_ENTRY(segment_011E2000, "segment_011E2000")
+DEFINE_DMA_ENTRY(data_combi, "data_combi")
DEFINE_DMA_ENTRY(segment_011E3000, "segment_011E3000")
DEFINE_DMA_ENTRY(segment_011E4000, "segment_011E4000")
DEFINE_DMA_ENTRY(segment_011E5000, "segment_011E5000")
diff --git a/linker_scripts/jp/ignored_addresses.txt b/linker_scripts/jp/ignored_addresses.txt
index 0069d07..4859cad 100644
--- a/linker_scripts/jp/ignored_addresses.txt
+++ b/linker_scripts/jp/ignored_addresses.txt
@@ -31,6 +31,8 @@ D_E4D10 = 0xE4D10; // ignore:true
D_13D9A0 = 0x13D9A0; // ignore:true
D_675720 = 0x675720; // ignore:true
D_73F4D0 = 0x73F4D0; // ignore:true
+D_81AA60 = 0x81AA60; // ignore:true
+D_81D540 = 0x81D540; // ignore:true
__osBbIsBb = 0x80000388; // ignore:true
diff --git a/linker_scripts/jp/symbol_addrs_assets.txt b/linker_scripts/jp/symbol_addrs_assets.txt
index 16a412b..edcaa8e 100644
--- a/linker_scripts/jp/symbol_addrs_assets.txt
+++ b/linker_scripts/jp/symbol_addrs_assets.txt
@@ -1270,6 +1270,8 @@ act_house_goki_model_2 = 0x6000188; // segment:act_house_goki rom:0x1147188
act_house_goki_pal = 0x6000250; // segment:act_house_goki rom:0x1147250
act_house_goki_tex = 0x6000270; // segment:act_house_goki rom:0x1147270
+data_combi_table = 0x6000000; // segment:data_combi rom:0x11E2000 size:0x684
+
act_bee_v = 0x6000000; // segment:act_bee rom:0x11F4000 size:0x3A0
act_bee_C_model = 0x60003A0; // segment:act_bee rom:0x11F43A0
act_bee_B_model = 0x60004B8; // segment:act_bee rom:0x11F44B8
@@ -1350,3 +1352,4 @@ int_sum_clchest03_door_model = 0x6000D30; // segment:int_sum_clchest03 rom:0x15D
int_sum_clchest03_base_model = 0x6000DF0; // segment:int_sum_clchest03 rom:0x15D0DF0
cKF_je_r_int_sum_clchest03_tbl = 0x6000F38; // segment:int_sum_clchest03 rom:0x15D0F38
cKF_bs_r_int_sum_clchest03 = 0x6000F5C; // segment:int_sum_clchest03 rom:0x15D0F5C
+
diff --git a/linker_scripts/jp/symbol_addrs_code.txt b/linker_scripts/jp/symbol_addrs_code.txt
index 9439a58..9cd0ae5 100644
--- a/linker_scripts/jp/symbol_addrs_code.txt
+++ b/linker_scripts/jp/symbol_addrs_code.txt
@@ -776,7 +776,7 @@ func_80071DB4_jp = 0x80071DB4; // type:func
func_800721C8_jp = 0x800721C8; // type:func
func_800721E4_jp = 0x800721E4; // type:func
func_80072238_jp = 0x80072238; // type:func
-func_80072264_jp = 0x80072264; // type:func
+mCoBG_Attribute2CheckPlant = 0x80072264; // type:func
func_80072340_jp = 0x80072340; // type:func
func_80072398_jp = 0x80072398; // type:func
func_800723C4_jp = 0x800723C4; // type:func
@@ -1358,10 +1358,10 @@ mFI_UtNum2UtCol = 0x800895B8; // type:func
func_80089698_jp = 0x80089698; // type:func
func_80089704_jp = 0x80089704; // type:func
func_800897D0_jp = 0x800897D0; // type:func
-func_80089888_jp = 0x80089888; // type:func
+mFI_GetUnitCol = 0x80089888; // type:func
func_800898F4_jp = 0x800898F4; // type:func
func_800899CC_jp = 0x800899CC; // type:func
-func_80089A34_jp = 0x80089A34; // type:func
+mFI_GetSoundSourcePBlockNum = 0x80089A34; // type:func
func_80089AAC_jp = 0x80089AAC; // type:func
func_80089B1C_jp = 0x80089B1C; // type:func
func_80089B94_jp = 0x80089B94; // type:func
@@ -2857,21 +2857,21 @@ func_800BC6B0_jp = 0x800BC6B0; // type:func
func_800BC724_jp = 0x800BC724; // type:func
func_800BC830_jp = 0x800BC830; // type:func
mQst_PrintQuestInfo = 0x800BC938; // type:func
-func_800BCBA0_jp = 0x800BCBA0; // type:func
-func_800BCBDC_jp = 0x800BCBDC; // type:func
-func_800BCC20_jp = 0x800BCC20; // type:func
-func_800BCC30_jp = 0x800BCC30; // type:func
-func_800BCC40_jp = 0x800BCC40; // type:func
-func_800BCCFC_jp = 0x800BCCFC; // type:func
+mRF_Malloc = 0x800BCBA0; // type:func
+mRF_Free = 0x800BCBDC; // type:func
+mRF_StepNo = 0x800BCC20; // type:func
+mRF_TryCnt = 0x800BCC30; // type:func
+mRF_PrintDebug = 0x800BCC40; // type:func
+mRF_MakeRandomField = 0x800BCCFC; // type:func
mRF_Type2BlockInfo = 0x800BCDCC; // type:func
-func_800BCDFC_jp = 0x800BCDFC; // type:func
-func_800BCE80_jp = 0x800BCE80; // type:func
-func_800BCEA4_jp = 0x800BCEA4; // type:func
-func_800BCF64_jp = 0x800BCF64; // type:func
-func_800BCFA4_jp = 0x800BCFA4; // type:func
+mRF_Info2BlockType = 0x800BCDFC; // type:func
+mRF_GateType2GateCount = 0x800BCE80; // type:func
+mRF_SearchPond = 0x800BCEA4; // type:func
+mRF_Attr2BeastRoadAttr = 0x800BCF64; // type:func
+mRF_BlockTypeDirect2GateType = 0x800BCFA4; // type:func
mRF_BlockTypeDirect2GateData = 0x800BCFC8; // type:func
-func_800BD02C_jp = 0x800BD02C; // type:func
-func_800BD1E4_jp = 0x800BD1E4; // type:func
+mRF_BlockInf2CheckBeastRoad = 0x800BD02C; // type:func
+mRF_CheckBeastRoad = 0x800BD1E4; // type:func
gfx_set_fog_position = 0x800BD2B0; // type:func
gfx_set_fog_nosync = 0x800BD37C; // type:func
func_800BD3EC_jp = 0x800BD3EC; // type:func
@@ -4842,42 +4842,42 @@ D_8010C650_jp = 0x8010C650; // type:u8
D_8010C65C_jp = 0x8010C65C; //
D_8010C66C_jp = 0x8010C66C; // type:u16
D_8010C670_jp = 0x8010C670; // type:u16
-D_8010C680_jp = 0x8010C680; //
-D_8010C684_jp = 0x8010C684; //
-D_8010C694_jp = 0x8010C694; //
-D_8010C69C_jp = 0x8010C69C; // type:u8
-D_8010C6A4_jp = 0x8010C6A4; //
-D_8010C6B0_jp = 0x8010C6B0; //
+l_delivery_limit = 0x8010C680; // type:u8
+l_errand_limit = 0x8010C684; // type:u8
+l_contest_limit = 0x8010C694; // type:u8
+l_contest_fin_limit = 0x8010C69C; // type:u8
+l_limit_table = 0x8010C6A4; //
+l_limit_table_max = 0x8010C6B0; //
D_8010C6B8_jp = 0x8010C6B8; //
-D_8010C6C0_jp = 0x8010C6C0; //
-D_8010C6C4_jp = 0x8010C6C4; //
-D_8010C6C8_jp = 0x8010C6C8; //
-D_8010C6CC_jp = 0x8010C6CC; //
-D_8010C6F8_jp = 0x8010C6F8; //
-D_8010C848_jp = 0x8010C848; // type:u8
-D_8010C850_jp = 0x8010C850; //
-D_8010C858_jp = 0x8010C858; //
-D_8010C860_jp = 0x8010C860; //
-D_8010C868_jp = 0x8010C868; //
-D_8010C870_jp = 0x8010C870; //
-D_8010C878_jp = 0x8010C878; //
-D_8010C880_jp = 0x8010C880; //
-D_8010C888_jp = 0x8010C888; //
-D_8010C890_jp = 0x8010C890; //
-D_8010C8A0_jp = 0x8010C8A0; //
-D_8010C8B0_jp = 0x8010C8B0; //
-D_8010C8C0_jp = 0x8010C8C0; //
-D_8010C8D0_jp = 0x8010C8D0; //
-D_8010C8E0_jp = 0x8010C8E0; //
-D_8010C8F0_jp = 0x8010C8F0; //
-D_8010C900_jp = 0x8010C900; //
-D_8010C910_jp = 0x8010C910; //
-D_8010C928_jp = 0x8010C928; //
-D_8010C940_jp = 0x8010C940; //
-D_8010C958_jp = 0x8010C958; //
-D_8010C970_jp = 0x8010C970; //
-D_8010C9D0_jp = 0x8010C9D0; // type:u8
-D_8010CB20_jp = 0x8010CB20; //
+mRF_AllocatedBuf = 0x8010C6C0; //
+stepNo = 0x8010C6C4; //
+tryCnt = 0x8010C6C8; //
+mRF_DebugMsg = 0x8010C6CC; //
+mRF_block_info = 0x8010C6F8; //
+gate_count_table = 0x8010C848; // type:u8 size:0x6
+gate1_type0_up = 0x8010C850; //
+gate1_type0_lt = 0x8010C858; //
+gate1_type0_dn = 0x8010C860; //
+gate1_type0_rt = 0x8010C868; //
+gate1_type1_up = 0x8010C870; //
+gate1_type1_lt = 0x8010C878; //
+gate1_type1_dn = 0x8010C880; //
+gate1_type1_rt = 0x8010C888; //
+gate2_type0_up = 0x8010C890; //
+gate2_type0_lt = 0x8010C8A0; //
+gate2_type0_dn = 0x8010C8B0; //
+gate2_type0_rt = 0x8010C8C0; //
+gate2_type1_up = 0x8010C8D0; //
+gate2_type1_lt = 0x8010C8E0; //
+gate2_type1_dn = 0x8010C8F0; //
+gate2_type1_rt = 0x8010C900; //
+gate3_type0_up = 0x8010C910; //
+gate3_type0_lt = 0x8010C928; //
+gate3_type0_dn = 0x8010C940; //
+gate3_type0_rt = 0x8010C958; //
+mRF_gate_correct_info = 0x8010C970; //
+mRF_gate_info2 = 0x8010C9D0; // type:u8
+wpos = 0x8010CB20; // type:f32 size:0xC allow_duplicates:true
z_gsCPModeSet_Data = 0x8010CB30; // type:Gfx size:0x2D0
RSP_RDP_clear_data = 0x8010CE00; // type:Gfx size:0x60
fade_gfx = 0x8010CE60; // type:Gfx size:0x30
diff --git a/linker_scripts/jp/symbol_addrs_overlays.txt b/linker_scripts/jp/symbol_addrs_overlays.txt
index 1277f88..9792664 100644
--- a/linker_scripts/jp/symbol_addrs_overlays.txt
+++ b/linker_scripts/jp/symbol_addrs_overlays.txt
@@ -6654,7 +6654,7 @@ B_80921EB8_jp = 0x80921EB8; // type:s8
// .text
-func_80922800_jp = 0x80922800; // type:func
+mRF_GetRandom = 0x80922800; // type:func
func_80922840_jp = 0x80922840; // type:func
func_80922854_jp = 0x80922854; // type:func
func_8092288C_jp = 0x8092288C; // type:func
@@ -6698,62 +6698,61 @@ func_80924C9C_jp = 0x80924C9C; // type:func
func_80924DB0_jp = 0x80924DB0; // type:func
func_80924DF4_jp = 0x80924DF4; // type:func
func_80924E6C_jp = 0x80924E6C; // type:func
-func_80924EEC_jp = 0x80924EEC; // type:func
-
-// .data
-
-D_80925080_jp = 0x80925080; //
-D_809250B8_jp = 0x809250B8; //
-D_809250BC_jp = 0x809250BC; //
-D_809250C4_jp = 0x809250C4; //
-D_809250C8_jp = 0x809250C8; //
-D_809250D0_jp = 0x809250D0; //
-D_809250D4_jp = 0x809250D4; //
-D_809250DC_jp = 0x809250DC; //
-D_809250E8_jp = 0x809250E8; // type:u8
-D_809250F0_jp = 0x809250F0; //
-D_809250F4_jp = 0x809250F4; //
-D_809250FC_jp = 0x809250FC; //
-D_80925100_jp = 0x80925100; //
-D_80925108_jp = 0x80925108; //
-D_8092510C_jp = 0x8092510C; //
-D_80925114_jp = 0x80925114; //
-D_80925118_jp = 0x80925118; //
-D_80925120_jp = 0x80925120; //
-D_80925124_jp = 0x80925124; //
-D_8092512C_jp = 0x8092512C; //
-D_80925130_jp = 0x80925130; //
-D_80925138_jp = 0x80925138; //
-D_8092513C_jp = 0x8092513C; //
-D_80925144_jp = 0x80925144; //
-D_80925160_jp = 0x80925160; // type:u8
-D_80925168_jp = 0x80925168; //
-D_8092516C_jp = 0x8092516C; //
-D_80925174_jp = 0x80925174; //
-D_80925178_jp = 0x80925178; //
-D_80925180_jp = 0x80925180; //
-D_80925184_jp = 0x80925184; //
-D_8092518C_jp = 0x8092518C; //
-D_80925190_jp = 0x80925190; //
-D_80925198_jp = 0x80925198; //
-D_8092519C_jp = 0x8092519C; //
-D_809251A4_jp = 0x809251A4; //
-D_809251A8_jp = 0x809251A8; //
-D_809251B0_jp = 0x809251B0; //
-D_809251B4_jp = 0x809251B4; //
-D_809251BC_jp = 0x809251BC; //
-D_809251C0_jp = 0x809251C0; //
-D_809251D8_jp = 0x809251D8; //
-D_809251E8_jp = 0x809251E8; //
-D_809251F8_jp = 0x809251F8; //
-D_80925240_jp = 0x80925240; //
-D_80925248_jp = 0x80925248; //
-D_80925250_jp = 0x80925250; //
-D_80925258_jp = 0x80925258; //
-D_8092527C_jp = 0x8092527C; //
-D_8092528C_jp = 0x8092528C; // type:u8
-D_8092528D_jp = 0x8092528D; // type:u8
-D_80925294_jp = 0x80925294; // type:u16
+mRF_MakeRandomField_ovl = 0x80924EEC; // type:func
+
+// .data
+
+l_base_blocks = 0x80925080; // type:u8
+l_cliff_startA_factor = 0x809250B8; // type:u8 size:0x2
+l_cliff_startA = 0x809250BC; //
+l_cliff_startB_factor = 0x809250C4; // type:u8 size:0x3
+l_cliff_startB = 0x809250C8; //
+l_cliff_startC_factor = 0x809250D0; // type:u8 size:0x2
+l_cliff_startC = 0x809250D4; //
+l_cliff_start_table = 0x809250DC; //
+l_cliff_next_direct = 0x809250E8; // type:u8 size:0x7
+l_cliff1_next = 0x809250F0; // type:u8 size:0x3
+l_cliff1_next_class = 0x809250F4; //
+l_cliff2_next = 0x809250FC; // type:u8 size:0x2
+l_cliff2_next_class = 0x80925100; //
+l_cliff3_next = 0x80925108; // type:u8 size:0x2
+l_cliff3_next_class = 0x8092510C; //
+l_cliff4_next = 0x80925114; // type:u8 size:0x3
+l_cliff4_next_class = 0x80925118; //
+l_cliff5_next = 0x80925120; // type:u8 size:0x2
+l_cliff5_next_class = 0x80925124; //
+l_cliff6_next = 0x8092512C; // type:u8 size:0x2
+l_cliff6_next_class = 0x80925130; //
+l_cliff7_next = 0x80925138; // type:u8 size:0x3
+l_cliff7_next_class = 0x8092513C; //
+l_cliff_next_data = 0x80925144; //
+l_river_next_direct = 0x80925160; //
+l_river1_next = 0x80925168; // type:u8 size:0x3
+l_river1_next_class = 0x8092516C; //
+l_river2_next = 0x80925174; // type:u8 size:0x2
+l_river2_next_class = 0x80925178; //
+l_river3_next = 0x80925180; // type:u8 size:0x2
+l_river3_next_class = 0x80925184; //
+l_river4_next = 0x8092518C; // type:u8 size:0x2
+l_river4_next_class = 0x80925190; //
+l_river5_next = 0x80925198; // type:u8 size:0x3
+l_river5_next_class = 0x8092519C; //
+l_river6_next = 0x809251A4; // type:u8 size:0x2
+l_river6_next_class = 0x809251A8; //
+l_river7_next = 0x809251B0; // type:u8 size:0x3
+l_river7_next_class = 0x809251B4; //
+l_river_next_data = 0x809251BC; // size:0x1C
+x_offset = 0x809251D8; //
+z_offset = 0x809251E8; //
+blockGroup = 0x809251F8; //
+river1_album_data = 0x80925240; // type:u8 size:0x7
+river2_album_data = 0x80925248; // type:u8 size:0x7
+river3_album_data = 0x80925250; // type:u8 size:0x7
+river_no_album_data = 0x80925258; // type:u8 size:0x7
+river_cliff_album_data = 0x80925260; //
+startX_table = 0x8092527C; //
+cross_data = 0x8092528C; // type:u8 size:0x7
+init_cmb = 0x80925294; // type:u16 size:0x2
// .rodata
@@ -6762,15 +6761,14 @@ jtbl_809252BC_jp = 0x809252BC; // type:jtbl
// .bss
-B_809252E0_jp = 0x809252E0; //
-B_80925318_jp = 0x80925318; //
+keep_blocks = 0x809252E0; //
+challenge_flag = 0x80925318; //
B_80925350_jp = 0x80925350; // type:s16
B_809253C0_jp = 0x809253C0; // type:s16
B_80925430_jp = 0x80925430; //
B_80925468_jp = 0x80925468; //
B_809254A0_jp = 0x809254A0; //
-B_809254D8_jp = 0x809254D8; // type:s16
-B_80925548_jp = 0x80925548; //
+l_use_data = 0x809254D8; // type:s16 size:0x70
D_80925550_jp = 0x80925550; //
// .text
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);
+ }
+ }
+ }
+}
diff --git a/src/combi/data_combi.c b/src/combi/data_combi.c
new file mode 100644
index 0000000..7fc9b46
--- /dev/null
+++ b/src/combi/data_combi.c
@@ -0,0 +1,6 @@
+#include "data_combi.h"
+
+#include "assets/jp/combi/data_combi_table.inc.c"
+// TODO: // Determine whether define is needed at all; it is not included in this segment,
+// but present in DnM+ as `data_combi_table_number`.
+#define DATA_COMBI_TABLE_NUMBER = ARRAY_COUNT(data_combi_table);
diff --git a/src/combi/data_combi.h b/src/combi/data_combi.h
new file mode 100644
index 0000000..08523d5
--- /dev/null
+++ b/src/combi/data_combi.h
@@ -0,0 +1,8 @@
+#ifndef OBJECT_DATA_COMBI_H
+#define OBJECT_DATA_COMBI_H
+
+#include "m_field_make.h"
+
+extern FieldMakeComboInfo data_combi_table[];
+
+#endif
diff --git a/tools/splat_ext/combi.py b/tools/splat_ext/combi.py
new file mode 100644
index 0000000..c243b04
--- /dev/null
+++ b/tools/splat_ext/combi.py
@@ -0,0 +1,52 @@
+import math
+import struct
+from typing import Optional
+from splat.util import options, log
+from splat.segtypes.common.codesubsegment import CommonSegCodeSubsegment
+
+class N64SegCombi(CommonSegCodeSubsegment):
+ def __init__(self, rom_start, rom_end, type, name, vram_start, args, yaml):
+ super().__init__(rom_start, rom_end, type, name, vram_start, args=args, yaml=yaml),
+
+ self.file_text: Optional[str] = None
+ self.data_only = isinstance(yaml, dict) and yaml.get("data_only", False)
+
+ def scan(self, rom_bytes: bytes):
+ data = rom_bytes[self.rom_start : self.rom_end]
+ symbol = self.create_symbol(addr=self.vram_start, in_segment=True, type="data", define=True)
+ entry_len = 6
+ count = len(data) // entry_len
+ lines = []
+
+ if (len(data)) % entry_len != 0:
+ log.error(f"Error: combi segment {self.name} length ({len(data)}) is not a multiple of {entry_len}!")
+
+ if not self.data_only:
+ lines.append(options.opts.generated_c_preamble)
+ lines.append("")
+ lines.append("// Combination types are used as indices into this table.")
+ lines.append("// Combination type can be derived from an acre ID by (acreID >> 2)")
+ lines.append("// (the two least significant bits of an acre ID store its height)")
+ lines.append(f"FieldMakeComboInfo {symbol.name}[{count}] = {{")
+
+ index_digits = math.ceil(math.log(count, 16))
+
+ for index, FieldMakeComboInfo in enumerate(struct.iter_unpack(">HHBB", data)):
+ bgId, fgId, blockType, pad = FieldMakeComboInfo
+ lines.append(f" /* 0x{index:0{index_digits}X} */ {{ 0x{bgId:04X}, 0x{fgId:04X}, 0x{blockType:02X} }},")
+
+ if not self.data_only:
+ lines.append(f"}}; // size = 0x{count * 6:X}")
+ # lines.append("")
+ # lines.append(f"s32 {symbol.name}_number = {count};")
+
+ lines.append("")
+ self.file_text = "\n".join(lines)
+
+ def split(self, rom_bytes: bytes):
+ path = options.opts.asset_path / self.dir / f"{self.name}.inc.c"
+
+ if self.file_text and path:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ with open(path, "w", newline="\n") as f:
+ f.write(self.file_text)
diff --git a/yamls/jp/assets.yaml b/yamls/jp/assets.yaml
index 065bdd6..a70ba8b 100644
--- a/yamls/jp/assets.yaml
+++ b/yamls/jp/assets.yaml
@@ -7034,12 +7034,23 @@
align: 0x1000
- [0x11E1A20]
- - name: segment_011E2000
- type: bin
+ - name: data_combi
+ dir: combi
+ type: code
start: 0x11E2000
- # vram:
+ vram: 0x06000000
+ exclusive_ram_id: segment_06
compress: True
align: 0x1000
+ symbol_name_format: $VRAM_$ROM
+ subsegments:
+ - [auto, c, data_combi]
+ - start: 0x11E2000
+ type: .data
+ name: data_combi
+ subsegments:
+ - [0x11E2000, combi, data_combi_table]
+ - [0x11E2684]
- [0x11E2690]
- name: segment_011E3000
diff --git a/yamls/jp/code.yaml b/yamls/jp/code.yaml
index 4e12fab..c052055 100644
--- a/yamls/jp/code.yaml
+++ b/yamls/jp/code.yaml
@@ -71,7 +71,7 @@
- [0x6DA460, asm, code/6DA460]
- [0x6DB420, c, code/m_private]
- [0x6DE300, asm, code/6DE300]
- - [0x6E08E0, asm, code/m_random_field]
+ - [0x6E0840, c, code/m_random_field]
- [0x6E0F50, c, code/m_rcp]
- [0x6E2300, c, code/m_room_type]
- [0x6E30B0, c, code/m_scene_ftr]
@@ -184,7 +184,8 @@
- [0x72F980, .data, code/m_player_call]
- [0x72F9B0, data, code/72F9B0]
- [0x7302C0, .data, code/m_private]
- - [0x730320, data, code/730320]
+ - [0x730320, data, code/m_quest]
+ - [0x730360, .data, code/m_random_field]
- [0x7307D0, .data, code/m_rcp]
- [0x730B60, .data, code/m_room_type]
- [0x731740, data, code/731740]
@@ -257,7 +258,7 @@
- [0x73B0F0, rodata, code/73B0F0]
- [0x73B130, .rodata, code/m_private]
- [0x73B210, rodata, code/73B210]
- - [0x73B250, rodata, code/73B250]
+ - [0x73B250, .rodata, code/m_random_field]
- [0x73B360, .rodata, code/m_room_type]
- [0x73B3E0, .rodata, code/m_scene_ftr]
- [0x73B400, rodata, code/m_shop]
diff --git a/yamls/jp/overlays.yaml b/yamls/jp/overlays.yaml
index 9a28677..95ebcf5 100644
--- a/yamls/jp/overlays.yaml
+++ b/yamls/jp/overlays.yaml
@@ -1070,7 +1070,7 @@
subsegments:
- [0x81A1A0, data, overlays/other_ovl/ovl__00815B70/ovl__00815B70_reloc]
- - name: ovl__0081AA60
+ - name: m_random_field_ovl
type: code
start: 0x81AA60
vram: 0x80922800
@@ -1078,24 +1078,24 @@
compress: True
bss_size: 0x270
subsegments:
- - [0x81AA60, asm, overlays/other_ovl/ovl__0081AA60/ovl__0081AA60]
- - [0x81D2E0, data, overlays/other_ovl/ovl__0081AA60/ovl__0081AA60]
- - [0x81D500, rodata, overlays/other_ovl/ovl__0081AA60/ovl__0081AA60]
- - { start: 0x81D540, type: bss, vram: 0x809252E0, name: overlays/other_ovl/ovl__0081AA60/ovl__0081AA60 }
- - name: ovl__0081AA60_reloc
+ - [0x81AA60, asm, overlays/other_ovl/m_random_field_ovl/m_random_field_ovl]
+ - [0x81D2E0, data, overlays/other_ovl/m_random_field_ovl/m_random_field_ovl]
+ - [0x81D500, rodata, overlays/other_ovl/m_random_field_ovl/m_random_field_ovl]
+ - { start: 0x81D540, type: bss, vram: 0x809252E0, name: overlays/other_ovl/m_random_field_ovl/m_random_field_ovl }
+ - name: m_random_field_ovl_reloc
type: code
start: 0x81D540
vram: 0x80925550
- follows_vram: ovl__0081AA60
+ follows_vram: m_random_field_ovl
compress: True
subsegments:
- - [0x81D540, data, overlays/other_ovl/ovl__0081AA60/ovl__0081AA60_reloc]
+ - [0x81D540, data, overlays/other_ovl/m_random_field_ovl/m_random_field_ovl_reloc]
- name: ovl__0081D9D0
type: code
start: 0x81D9D0
vram: 0x809259E0
- follows_vram: ovl__0081AA60_reloc
+ follows_vram: m_random_field_ovl_reloc
compress: True
bss_size: 0x4E0
subsegments: