diff options
| -rw-r--r-- | include/code_variables.h | 3 | ||||
| -rw-r--r-- | include/m_collision_bg.h | 2 | ||||
| -rw-r--r-- | include/m_field_info.h | 90 | ||||
| -rw-r--r-- | include/m_field_make.h | 134 | ||||
| -rw-r--r-- | include/m_random_field.h | 42 | ||||
| -rw-r--r-- | linker_scripts/jp/symbol_addrs_code.txt | 48 | ||||
| -rw-r--r-- | src/code/m_field_info.c | 435 | ||||
| -rw-r--r-- | src/code/m_npc_walk.c | 2 |
8 files changed, 645 insertions, 111 deletions
diff --git a/include/code_variables.h b/include/code_variables.h index b484b81..f889763 100644 --- a/include/code_variables.h +++ b/include/code_variables.h @@ -397,9 +397,6 @@ extern s32 CanLookGokiCount; // extern UNK_TYPE D_8010674C_jp; // extern UNK_TYPE D_80106794_jp; // extern UNK_TYPE D_801067A4_jp; -// extern UNK_TYPE D_80106814_jp; -// extern UNK_TYPE D_80106818_jp; -// extern UNK_TYPE D_80106820_jp; // extern UNK_TYPE D_80106824_jp; // extern UNK_TYPE D_80106828_jp; // extern UNK_TYPE D_8010682C_jp; diff --git a/include/m_collision_bg.h b/include/m_collision_bg.h index 1cb0f4e..9401fda 100644 --- a/include/m_collision_bg.h +++ b/include/m_collision_bg.h @@ -8,6 +8,8 @@ struct Actor; struct PosRot; +enum BackgroundAttribute { mCoBG_ATTRIBUTE_0, mCOBG_ATTRIBUTE_NONE = 100 }; + // offset table typedef struct mCoBG_unkStruct2 { /* 0x00 */ u8 unk0; diff --git a/include/m_field_info.h b/include/m_field_info.h index f6519a1..a061f1a 100644 --- a/include/m_field_info.h +++ b/include/m_field_info.h @@ -22,6 +22,9 @@ struct Game; #define FI_UT_WORLDSIZE_Z FI_UT_BASE_SIZE #define FI_UT_WORLDSIZE_Z_F (f32)FI_UT_WORLDSIZE_Z +#define FI_UT_WORLDSIZE_HALF_X_F (FI_UT_WORLDSIZE_X_F / 2.0f) +#define FI_UT_WORLDSIZE_HALF_Z_F (FI_UT_WORLDSIZE_X_F / 2.0f) + #define FI_BK_WORLDSIZE_BASE (FI_UT_BASE_SIZE * UT_BASE_NUM) #define FI_BK_WORLDSIZE_BASE_F ((f32)FI_BK_WORLDSIZE_BASE) @@ -31,6 +34,12 @@ struct Game; #define FI_BK_WORLDSIZE_X_F FI_BK_WORLDSIZE_BASE_F #define FI_BK_WORLDSIZE_Z_F FI_BK_WORLDSIZE_BASE_F +#define FI_BK_WORLDSIZE_HALF_X (FI_BK_WORLDSIZE_X / 2) +#define FI_BK_WORLDSIZE_HALF_Z (FI_BK_WORLDSIZE_Z / 2) + +#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) + typedef enum FieldType { /* 0 */ FI_FIELDTYPE_FG, @@ -48,12 +57,31 @@ typedef enum FieldType { #define FI_GET_TYPE(id) ((id) & 0xF000) typedef enum FieldRoom { + /* 0x3000 */ FI_FIELD_ROOM0 = FI_TO_FIELD_ID(FI_FIELDTYPE_ROOM, 0), + /* 0x3001 */ FI_FIELD_ROOM_SHOP0, + /* 0x3002 */ FI_FIELD_ROOM_UNK_3002, + /* 0x3003 */ FI_FIELD_ROOM_UNK_3003, + /* 0x3004 */ FI_FIELD_ROOM_UNK_3004, + /* 0x3005 */ FI_FIELD_ROOM_UNK_3005, + /* 0x3006 */ FI_FIELD_ROOM_SHOP1, + /* 0x3007 */ FI_FIELD_ROOM_SHOP2, + /* 0x3008 */ FI_FIELD_ROOM_SHOP3_1, + /* 0x3009 */ FI_FIELD_ROOM_SHOP3_2, /* 0x6000 */ FI_FIELD_PLAYER0_ROOM = FI_TO_FIELD_ID(FI_FIELDTYPE_PLAYER_ROOM, 0), /* 0x6001 */ FI_FIELD_PLAYER1_ROOM, /* 0x6002 */ FI_FIELD_PLAYER2_ROOM, /* 0x6003 */ FI_FIELD_PLAYER3_ROOM } FieldRoom; +typedef enum FieldDirection { + /* 0 */ FI_MOVEDIR_NONE, + /* 1 */ FI_MOVEDIR_RIGHT, + /* 2 */ FI_MOVEDIR_LEFT, + /* 3 */ FI_MOVEDIR_UP, + /* 4 */ FI_MOVEDIR_DOWN, + + /* 5 */ FI_MOVEDIR_MAX +} FieldDirection; #define FI_GET_PLAYER_ROOM_NO(fieldId) (((fieldId)-FI_FIELD_PLAYER0_ROOM) & 3) #define FI_IS_PLAYER_ROOM(fieldId) \ @@ -66,34 +94,34 @@ struct FieldMakeBlockInfo* mFI_GetBlockTopP(void); u16 mFI_GetFieldId(void); // void func_80087C9C_jp(); // void func_80087D30_jp(); -// void func_80087DC8_jp(); -// void func_80087E14_jp(); -s32 mFI_GetBlockXMax(void); -s32 mFI_GetBlockZMax(void); +s32 mFI_CheckShopFieldName(u16 fieldName); +s32 mFI_CheckShop(void); +u8 mFI_GetBlockXMax(void); +u8 mFI_GetBlockZMax(void); // void func_80087ED0_jp(); // void func_80088018_jp(); -// void func_80088160_jp(); +// s32 mFI_GetBlockNum(s32 blockX, s32 blockZ); // void func_8008819C_jp(); // s32 mFI_BlockCheck(s32 blockX, s32 blockZ); -// void func_80088270_jp(); -// void func_800882AC_jp(); -// void func_800882FC_jp(); -// void func_80088320_jp(); -s32 mFI_Wpos2UtNum(s32*, s32*, xyz_t); -// void func_80088458_jp(); -s32 mFI_Wpos2UtCenterWpos(xyz_t*, xyz_t); -// void func_800885A8_jp(); -s32 mFI_Wpos2BlockNum(s32*, s32*, xyz_t); -s32 mFI_Wpos2BkandUtNuminBlock(s32*,s32*, s32* ,s32* ,xyz_t); -// void func_8008883C_jp(); -// void func_800888AC_jp(); -// void func_80088938_jp(); -// void func_800889D8_jp(); -// void func_80088A58_jp(); +// s32 mFI_UtNumCheck(int utX, int utZ, int blockXMax, int blockZMax); +// s32 mFI_WposCheck(xyz_t wpos); +s32 mFI_WposX2UtNumX(f32 wposX); +s32 mFI_WposZ2UtNumZ(f32 wposZ); +s32 mFI_Wpos2UtNum(s32* utX, s32* utZ, xyz_t wpos); +s32 mFI_UtNum2CenterWpos(xyz_t* wpos, int utX, int utZ); +s32 mFI_Wpos2UtCenterWpos(xyz_t* wpos, xyz_t sourcePos); +// s32 mFI_Wpos2UtNum_inBlock(s32* utX, s32* utZ, xyz_t wpos); +s32 mFI_Wpos2BlockNum(s32* blockX, s32* blockZ, xyz_t wpos); +s32 mFI_Wpos2BkandUtNuminBlock(s32* blockX, s32* blockZ, s32* utX, s32* utZ, xyz_t wpos); +// s32 mFI_UtNum2BlockNum(s32* blockX, s32* blockZ, s32 utX, s32 utZ); +// s32 mFI_GetUtNumInBK(s32* blockUtX, s32* blockUtZ, s32 utX, s32 utZ); +// s32 mFI_WpostoLposInBK(xyz_t* lpos, xyz_t wpos); +// s32 mFI_LposInBKtoWpos(xyz_t* wpos, xyz_t lpos, s32 blockX, s32 blockZ); +// s32 mFI_ScrollCheck(xyz_t wpos, u8 dir); s32 mFI_BkNum2WposXZ(f32* worldPosX, f32* worldPosZ, s32 blockX, s32 blockZ); -void mFI_UtNum2PosXZInBk(f32*, f32*, s32, s32); -// void func_80088BFC_jp(); -void mFI_BkandUtNum2CenterWpos(xyz_t*, s32, s32, s32, s32); +void mFI_UtNum2PosXZInBk(f32* posX, f32* posZ, s32 utX, s32 utZ); +// void mFI_BkandUtNum2Wpos(xyz_t* wpos, s32 blockX, s32 blockZ, s32 utX, s32 utZ); +void mFI_BkandUtNum2CenterWpos(xyz_t* wpos, s32 blockX, s32 blockZ, s32 utX, s32 utZ); // void func_80088CBC_jp(); // void func_80088CD0_jp(); // void func_80088CE4_jp(); @@ -110,16 +138,16 @@ void mFI_BkandUtNum2CenterWpos(xyz_t*, s32, s32, s32, s32); // void func_8008907C_jp(); // void func_80089114_jp(); // void func_800891AC_jp(); -u8 mFI_BkNum2BlockType(s32,s32); +u8 mFI_BkNum2BlockType(s32 blockX, s32 blockZ); // s32 mFI_GetPuleTypeIdx(u8 type); s32 mFI_GetPuleIdx(void); -// void func_80089348_jp(); -// void func_800893C8_jp(); -s32 mFI_CheckBlockKind_OR(s32, s32, s32); -s32 mFI_BlockKind2BkNum(s32*,s32*,s32); -// void func_800894D0_jp(); -mCoBG_unkStructUnion* mFI_GetBkNum2ColTop(s32 arg0, s32 arg1); -// void func_800895B8_jp(); +u32 mFI_BkNum2BlockKind(s32 blockX, s32 blockZ); +s32 mFI_CheckBlockKind(s32 blockX, s32 blockZ, u32 blockKind); +s32 mFI_CheckBlockKind_OR(s32 blockX, s32 blockZ, u32 blockKindOr); +s32 mFI_BlockKind2BkNum(s32* blockX, s32* blockZ, u32 kind); +void mFI_GetSpecialBlockNum(s32* blockPos, u32* kinds, s32 count); +mCoBG_unkStructUnion* mFI_GetBkNum2ColTop(s32 blockX, s32 blockZ); +mCoBG_unkStructUnion* mFI_UtNum2UtCol(s32 utX, s32 utZ); // void func_80089698_jp(); // void func_80089704_jp(); // void func_800897D0_jp(); diff --git a/include/m_field_make.h b/include/m_field_make.h index a287939..695418d 100644 --- a/include/m_field_make.h +++ b/include/m_field_make.h @@ -3,15 +3,16 @@ #include "ultra64.h" #include "unk.h" +#include "m_collision_bg.h" struct Game; #define BLOCK_X_NUM 7 -#define BLOCK_Z_NUM 10 +#define BLOCK_Z_NUM 8 #define BLOCK_TOTAL_NUM (BLOCK_X_NUM * BLOCK_Z_NUM) #define FG_BLOCK_X_NUM (BLOCK_X_NUM - 2) /* 5 */ -#define FG_BLOCK_Z_NUM (BLOCK_Z_NUM - 4) /* 6 */ +#define FG_BLOCK_Z_NUM (BLOCK_Z_NUM - 2) /* 6 */ #define FG_BLOCK_TOTAL_NUM (FG_BLOCK_X_NUM * FG_BLOCK_Z_NUM) #define UT_BASE_NUM 16 @@ -19,6 +20,110 @@ 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) +/* + * Naming convention for `RIVER`/`POOL`: directions indicated are flow of river + * (e.g. `RIVER_SOUTH` indicates a river that flows south through entire block, + * `RIVER_WEST_SOUTH` indicates a river that flows west and then south, etc.) + * + * Naming convention for `CLIFF`: direction indicated is side with valley + * (e.g. `CORNER_RIGHT_TOP` indicates the top part of a corner cliff + * with the valley on the right). However, directions for border cliffs simply + * indicate the side of the map. + */ +typedef enum FieldMakeBlockType { + /* 0x00 */ mFM_BLOCK_TYPE_BORDER_CLIFF_TOP, + /* 0x01 */ mFM_BLOCK_TYPE_BORDER_CLIFF_RIVER, + /* 0x02 */ mFM_BLOCK_TYPE_BORDER_CLIFF_LEFT, + /* 0x03 */ mFM_BLOCK_TYPE_3, // Unused (no entries in `data_combi_table`) + /* 0x04 */ mFM_BLOCK_TYPE_BORDER_CLIFF_RIGHT, + /* 0x05 */ mFM_BLOCK_TYPE_BORDER_CLIFF_CORNER_TOP_LEFT, + /* 0x06 */ mFM_BLOCK_TYPE_6, // Unused (no entries in `data_combi_table`) + /* 0x07 */ mFM_BLOCK_TYPE_7, // Unused (no entries in `data_combi_table`) + /* 0x08 */ mFM_BLOCK_TYPE_BORDER_CLIFF_CORNER_TOP_RIGHT, + /* 0x09 */ mFM_BLOCK_TYPE_BORDER_CLIFF_TUNNEL_LEFT, + /* 0x0A */ mFM_BLOCK_TYPE_BORDER_CLIFF_TUNNEL_RIGHT, + /* 0x0B */ mFM_BLOCK_TYPE_TRACKS_STATION, + /* 0x0C */ mFM_BLOCK_TYPE_TRACKS_DUMP, + /* 0x0D */ mFM_BLOCK_TYPE_TRACKS_RIVER, + /* 0x0E */ mFM_BLOCK_TYPE_PLAYER_HOUSE, + /* 0x0F */ mFM_BLOCK_TYPE_CLIFF_HORIZONTAL, + /* 0x10 */ mFM_BLOCK_TYPE_CLIFF_CORNER_RIGHT_BOTTOM, + /* 0x11 */ mFM_BLOCK_TYPE_CLIFF_VERTICAL_RIGHT, + /* 0x12 */ mFM_BLOCK_TYPE_CLIFF_CORNER_RIGHT_TOP, + /* 0x13 */ mFM_BLOCK_TYPE_CLIFF_CORNER_LEFT_TOP, + /* 0x14 */ mFM_BLOCK_TYPE_CLIFF_VERTICAL_LEFT, + /* 0x15 */ mFM_BLOCK_TYPE_CLIFF_CORNER_LEFT_BOTTOM, + /* 0x16 */ mFM_BLOCK_TYPE_WATERFALL_SOUTH_CLIFF_HORIZONTAL, + /* 0x17 */ mFM_BLOCK_TYPE_WATERFALL_SOUTH_CLIFF_CORNER_RIGHT_BOTTOM, + /* 0x18 */ mFM_BLOCK_TYPE_RIVER_SOUTH_CLIFF_VERTICAL_RIGHT, + /* 0x19 */ mFM_BLOCK_TYPE_RIVER_SOUTH_CLIFF_CORNER_RIGHT_TOP, + /* 0x1A */ mFM_BLOCK_TYPE_WATERFALL_SOUTH_CLIFF_CORNER_LEFT_TOP, + /* 0x1B */ mFM_BLOCK_TYPE_RIVER_SOUTH_CLIFF_VERTICAL_LEFT, + /* 0x1C */ mFM_BLOCK_TYPE_RIVER_SOUTH_CLIFF_CORNER_LEFT_BOTTOM, + /* 0x1D */ mFM_BLOCK_TYPE_RIVER_EAST_CLIFF_HORIZONTAL, // Correct according to ACSE, should be verified in-game + /* 0x1E */ mFM_BLOCK_TYPE_WATERFALL_EAST_CLIFF_CORNER_RIGHT_BOTTOM, + /* 0x1F */ mFM_BLOCK_TYPE_WATERFALL_EAST_CLIFF_VERTICAL_RIGHT, + /* 0x20 */ mFM_BLOCK_TYPE_RIVER_EAST_CLIFF_CORNER_RIGHT_TOP, + /* 0x21 */ mFM_BLOCK_TYPE_RIVER_EAST_CLIFF_CORNER_LEFT_TOP, + /* 0x22 */ mFM_BLOCK_TYPE_RIVER_WEST_CLIFF_HORIZONTAL, + /* 0x23 */ mFM_BLOCK_TYPE_RIVER_WEST_CLIFF_CORNER_RIGHT_TOP, + /* 0x24 */ mFM_BLOCK_TYPE_RIVER_WEST_CLIFF_CORNER_LEFT_TOP, + /* 0x25 */ mFM_BLOCK_TYPE_WATERFALL_WEST_CLIFF_VERTICAL_LEFT, + /* 0x26 */ mFM_BLOCK_TYPE_WATERFALL_WEST_CLIFF_CORNER_LEFT_BOTTOM, + /* 0x27 */ mFM_BLOCK_TYPE_FLAT, // Grassy field + /* 0x28 */ mFM_BLOCK_TYPE_RIVER_SOUTH, + /* 0x29 */ mFM_BLOCK_TYPE_RIVER_EAST, + /* 0x2A */ mFM_BLOCK_TYPE_RIVER_WEST, + /* 0x2B */ mFM_BLOCK_TYPE_RIVER_SOUTH_EAST, + /* 0x2C */ mFM_BLOCK_TYPE_RIVER_EAST_SOUTH, + /* 0x2D */ mFM_BLOCK_TYPE_RIVER_SOUTH_WEST, + /* 0x2E */ mFM_BLOCK_TYPE_RIVER_WEST_SOUTH, + /* 0x2F */ mFM_BLOCK_TYPE_RIVER_SOUTH_BRIDGE, + /* 0x30 */ mFM_BLOCK_TYPE_RIVER_EAST_BRIDGE, + /* 0x31 */ mFM_BLOCK_TYPE_RIVER_WEST_BRIDGE, + /* 0x32 */ mFM_BLOCK_TYPE_RIVER_SOUTH_EAST_BRIDGE, + /* 0x33 */ mFM_BLOCK_TYPE_RIVER_EAST_SOUTH_BRIDGE, + /* 0x34 */ mFM_BLOCK_TYPE_RIVER_SOUTH_WEST_BRIDGE, + /* 0x35 */ mFM_BLOCK_TYPE_RIVER_WEST_SOUTH_BRIDGE, + /* 0x36 */ mFM_BLOCK_TYPE_SLOPE_HORIZONTAL, + /* 0x37 */ mFM_BLOCK_TYPE_SLOPE_CORNER_RIGHT_BOTTOM, + /* 0x38 */ mFM_BLOCK_TYPE_SLOPE_VERTICAL_RIGHT, + /* 0x39 */ mFM_BLOCK_TYPE_SLOPE_CORNER_RIGHT_TOP, + /* 0x3A */ mFM_BLOCK_TYPE_SLOPE_CORNER_LEFT_TOP, + /* 0x3B */ mFM_BLOCK_TYPE_SLOPE_VERTICAL_LEFT, + /* 0x3C */ mFM_BLOCK_TYPE_SLOPE_CORNER_LEFT_BOTTOM, + /* 0x3D */ mFM_BLOCK_TYPE_BORDER_CLIFF_TRANSITION_LEFT, + /* 0x3E */ mFM_BLOCK_TYPE_BORDER_CLIFF_TRANSITION_RIGHT, + /* 0x3F */ mFM_BLOCK_TYPE_BEACH, + /* 0x40 */ mFM_BLOCK_TYPE_BEACH_RIVER, + /* 0x41 */ mFM_BLOCK_TYPE_SHOP, + /* 0x42 */ mFM_BLOCK_TYPE_SHRINE, + /* 0x43 */ mFM_BLOCK_TYPE_POST_OFFICE, + /* 0x44 */ mFM_BLOCK_TYPE_POLICE_BOX, + /* 0x45 */ mFM_BLOCK_TYPE_POOL_SOUTH, + /* 0x46 */ mFM_BLOCK_TYPE_POOL_EAST, + /* 0x47 */ mFM_BLOCK_TYPE_POOL_WEST, + /* 0x48 */ mFM_BLOCK_TYPE_POOL_SOUTH_EAST, + /* 0x49 */ mFM_BLOCK_TYPE_POOL_EAST_SOUTH, + /* 0x4A */ mFM_BLOCK_TYPE_POOL_SOUTH_WEST, + /* 0x4B */ mFM_BLOCK_TYPE_POOL_WEST_SOUTH, + /* 0x4C */ mFM_BLOCK_TYPE_76, + /* 0x4D */ mFM_BLOCK_TYPE_77, + /* 0x4E */ mFM_BLOCK_TYPE_78, + /* 0x4F */ mFM_BLOCK_TYPE_79, + /* 0x50 */ mFM_BLOCK_TYPE_BORDER_CLIFF_OCEAN_LEFT, + /* 0x51 */ mFM_BLOCK_TYPE_BORDER_CLIFF_OCEAN_RIGHT, + /* 0x52 */ mFM_BLOCK_TYPE_BEACH_RIVER_BRIDGE, + /* 0x53 */ mFM_BLOCK_TYPE_OCEAN, + + /* 0x54 */ mFM_BLOCK_TYPE_NUM, + + /* 0xFF */ mFM_BLOCK_TYPE_NONE = 0xFF +} 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 Foreground { /* 0x000 */ u16 items[UT_Z_NUM][UT_X_NUM]; } Foreground; // size = 0x200 @@ -43,11 +148,28 @@ typedef struct FieldMakeFGInfo { /* 0x08 */ UNK_TYPE1 unk_08[0x8C]; } FieldMakeFGInfo; // size = 0x94 -typedef struct FieldMakeBlockInfo { - /* 0x000 */ UNK_TYPE1 unk_000[0x580]; +typedef struct FieldMakeBGInfo { + /* 0x000 */ UNK_TYPE1 unk_000[0x14]; + /* 0x014 */ u32 blockKind; + /* 0x018 */ UNK_TYPE1 unk_018[0x08]; + /* 0x020 */ mCoBG_unkStructUnion collision[UT_Z_NUM][UT_X_NUM]; + /* 0x420 */ UNK_TYPE1 unk_024[0x160]; +} FieldMakeBGInfo; // size >= 0x57d + +typedef struct FieldMakeBlockInfo { + /* 0x000 */ FieldMakeBGInfo bgInfo; /* 0x580 */ FieldMakeFGInfo fgInfo; } FieldMakeBlockInfo; // size = 0x614 +typedef struct FieldMakeInfo { + /* 0x000 */ u16 fieldId; + /* 0x002 */ UNK_TYPE1 unk_000[0x146]; + /* 0x148 */ FieldMakeBlockInfo* blockInfo; + /* 0x14C */ UNK_TYPE1 unk_14C[0x1A]; + /* 0x166 */ u8 blockXMax; + /* 0x167 */ u8 blockZMax; +} FieldMakeInfo; // size >= 0x168 + // void func_80084ED0_jp(); // void func_80084FAC_jp(); // void func_800850E4_jp(); @@ -78,7 +200,7 @@ typedef struct FieldMakeBlockInfo { // void func_80086E30_jp(); // void func_80086F08_jp(); // void func_80086FA8_jp(); -void mFM_SetFieldInitData(s32,s32); +void mFM_SetFieldInitData(s32, s32); void func_80087004_jp(void); void func_80087280_jp(void); // void func_80087380_jp(); @@ -89,6 +211,6 @@ void mFM_InitFgCombiSaveData(struct Game* game); // void func_80087788_jp(); // void func_800877CC_jp(); void mFM_RenewalReserve(void); -u16 mFM_GetReseveName(s32,s32); +u16 mFM_GetReseveName(s32,s32); #endif diff --git a/include/m_random_field.h b/include/m_random_field.h index ba52e3e..256edbb 100644 --- a/include/m_random_field.h +++ b/include/m_random_field.h @@ -3,10 +3,6 @@ #include "ultra64.h" - -#define RANDOM_FIELD_BLOCKKIND_SHRINE (1 << 2) - -#define RANDOM_FIELD_BLOCK_TYPE_MAX 108 #define RANDOM_FIELD_DIRECT_ERROR 100 typedef enum RandomFieldDirection { @@ -16,20 +12,54 @@ typedef enum RandomFieldDirection { /* 3 */ RANDOM_FIELD_DIRECT_EAST, /* 4 */ RANDOM_FIELD_DIRECT_NUM -}RandomFieldDirection; +} RandomFieldDirection; typedef struct RandomFieldGate { /* 0x00 */ s32 ut0; /* 0x04 */ s32 ut1; } RandomFieldGate; +#define mRF_BLOCKKIND_NONE (0 << 0) +#define mRF_BLOCKKIND_PLAYER (1 << 0) // Player houses +#define mRF_BLOCKKIND_SHOP (1 << 1) +#define mRF_BLOCKKIND_SHRINE (1 << 2) +#define mRF_BLOCKKIND_POLICE (1 << 3) +#define mRF_BLOCKKIND_POSTOFFICE (1 << 4) +#define mRF_BLOCKKIND_STATION (1 << 5) +#define mRF_BLOCKKIND_CLIFF (1 << 6) +#define mRF_BLOCKKIND_RIVER (1 << 7) +#define mRF_BLOCKKIND_WATERFALL (1 << 8) +#define mRF_BLOCKKIND_BRIDGE (1 << 9) +#define mRF_BLOCKKIND_RAILROAD (1 << 10) +#define mRF_BLOCKKIND_MARINE (1 << 11) // Beach +#define mRF_BLOCKKIND_BORDER (1 << 12) +#define mRF_BLOCKKIND_TUNNEL (1 << 13) +#define mRF_BLOCKKIND_SLOPE (1 << 14) +#define mRF_BLOCKKIND_POOL (1 << 15) // The large pond, not the small pools +#define mRF_BLOCKKIND_DUMP (1 << 16) +#define mRF_BLOCKKIND_RIVER0 (1 << 17) // Flows south +#define mRF_BLOCKKIND_RIVER1 (1 << 18) // Flows east +#define mRF_BLOCKKIND_RIVER2 (1 << 19) // Flows west +#define mRF_BLOCKKIND_RIVER3 (1 << 20) // Flows south then east +#define mRF_BLOCKKIND_RIVER4 (1 << 21) // Flows east then south +#define mRF_BLOCKKIND_RIVER5 (1 << 22) // Flows south then west +#define mRF_BLOCKKIND_RIVER6 (1 << 23) // Flows west then south +#define mRF_BLOCKKIND_CLIFF0 (1 << 24) // Cliff that goes horizontally in an arc across entire block +#define mRF_BLOCKKIND_CLIFF1 (1 << 25) // Bottom part of cliff which juts out, valley on right +#define mRF_BLOCKKIND_CLIFF2 (1 << 26) // Cliff that goes vertically across entire block, valley on right +#define mRF_BLOCKKIND_CLIFF3 (1 << 27) // Top part of cliff which juts out, valley on right +#define mRF_BLOCKKIND_CLIFF4 (1 << 28) // Top part of cliff which juts out, valley on left +#define mRF_BLOCKKIND_CLIFF5 (1 << 29) // Cliff that goes vertically across entire block, valley on left +#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(); -// void func_800BCDCC_jp(); +s32 mRF_Type2BlockInfo(u8 type); // void func_800BCDFC_jp(); // void func_800BCE80_jp(); // void func_800BCEA4_jp(); diff --git a/linker_scripts/jp/symbol_addrs_code.txt b/linker_scripts/jp/symbol_addrs_code.txt index d83cf9a..3e62572 100644 --- a/linker_scripts/jp/symbol_addrs_code.txt +++ b/linker_scripts/jp/symbol_addrs_code.txt @@ -1301,33 +1301,33 @@ mFI_GetBlockTopP = 0x80087C64; // type:func mFI_GetFieldId = 0x80087C88; // type:func func_80087C9C_jp = 0x80087C9C; // type:func func_80087D30_jp = 0x80087D30; // type:func -func_80087DC8_jp = 0x80087DC8; // type:func -func_80087E14_jp = 0x80087E14; // type:func +mFI_CheckShopFieldName = 0x80087DC8; // type:func +mFI_CheckShop = 0x80087E14; // type:func mFI_GetBlockXMax = 0x80087E58; // type:func mFI_GetBlockZMax = 0x80087E94; // type:func func_80087ED0_jp = 0x80087ED0; // type:func func_80088018_jp = 0x80088018; // type:func -func_80088160_jp = 0x80088160; // type:func -func_8008819C_jp = 0x8008819C; // type:func +mFI_GetBlockNum = 0x80088160; // type:func +mFI_GetUtNum = 0x8008819C; // type:func mFI_BlockCheck = 0x800881AC; // type:func -func_80088270_jp = 0x80088270; // type:func -func_800882AC_jp = 0x800882AC; // type:func -func_800882FC_jp = 0x800882FC; // type:func -func_80088320_jp = 0x80088320; // type:func +mFI_UtNumCheck = 0x80088270; // type:func +mFI_WposCheck = 0x800882AC; // type:func +mFI_WposX2UtNumX = 0x800882FC; // type:func +mFI_WposZ2UtNumZ = 0x80088320; // type:func mFI_Wpos2UtNum = 0x80088344; // type:func -func_80088458_jp = 0x80088458; // type:func +mFI_UtNum2CenterWpos = 0x80088458; // type:func mFI_Wpos2UtCenterWpos = 0x800884E0; // type:func -func_800885A8_jp = 0x800885A8; // type:func +mFI_Wpos2UtNum_inBlock = 0x800885A8; // type:func mFI_Wpos2BlockNum = 0x80088710; // type:func mFI_Wpos2BkandUtNuminBlock = 0x80088780; // type:func -func_8008883C_jp = 0x8008883C; // type:func -func_800888AC_jp = 0x800888AC; // type:func -func_80088938_jp = 0x80088938; // type:func -func_800889D8_jp = 0x800889D8; // type:func -func_80088A58_jp = 0x80088A58; // type:func +mFI_UtNum2BlockNum = 0x8008883C; // type:func +mFI_GetUtNumInBK = 0x800888AC; // type:func +mFI_WpostoLposInBK = 0x80088938; // type:func +mFI_LposInBKtoWpos = 0x800889D8; // type:func +mFI_ScrollCheck = 0x80088A58; // type:func mFI_BkNum2WposXZ = 0x80088B3C; // type:func mFI_UtNum2PosXZInBk = 0x80088BC0; // type:func -func_80088BFC_jp = 0x80088BFC; // type:func +mFI_BkandUtNum2Wpos = 0x80088BFC; // type:func mFI_BkandUtNum2CenterWpos = 0x80088C74; // type:func func_80088CBC_jp = 0x80088CBC; // type:func func_80088CD0_jp = 0x80088CD0; // type:func @@ -1348,13 +1348,13 @@ func_800891AC_jp = 0x800891AC; // type:func mFI_BkNum2BlockType = 0x80089268; // type:func mFI_GetPuleTypeIdx = 0x800892CC; // type:func mFI_GetPuleIdx = 0x8008930C; // type:func -func_80089348_jp = 0x80089348; // type:func -func_800893C8_jp = 0x800893C8; // type:func +mFI_BkNum2BlockKind = 0x80089348; // type:func +mFI_CheckBlockKind = 0x800893C8; // type:func mFI_CheckBlockKind_OR = 0x80089404; // type:func mFI_BlockKind2BkNum = 0x80089440; // type:func -func_800894D0_jp = 0x800894D0; // type:func +mFI_GetSpecialBlockNum = 0x800894D0; // type:func mFI_GetBkNum2ColTop = 0x80089538; // type:func -func_800895B8_jp = 0x800895B8; // type:func +mFI_UtNum2UtCol = 0x800895B8; // type:func func_80089698_jp = 0x80089698; // type:func func_80089704_jp = 0x80089704; // type:func func_800897D0_jp = 0x800897D0; // type:func @@ -2863,7 +2863,7 @@ func_800BCC20_jp = 0x800BCC20; // type:func func_800BCC30_jp = 0x800BCC30; // type:func func_800BCC40_jp = 0x800BCC40; // type:func func_800BCCFC_jp = 0x800BCCFC; // type:func -func_800BCDCC_jp = 0x800BCDCC; // 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 @@ -4577,9 +4577,9 @@ D_80106738_jp = 0x80106738; // D_8010674C_jp = 0x8010674C; // D_80106794_jp = 0x80106794; // D_801067A4_jp = 0x801067A4; // -D_80106814_jp = 0x80106814; // -D_80106818_jp = 0x80106818; // -D_80106820_jp = 0x80106820; // +g_block_type_p = 0x80106814; // +g_block_kind_p = 0x80106818; // size:0x4 +l_edge_ut = 0x80106820; // D_80106824_jp = 0x80106824; // D_80106828_jp = 0x80106828; // D_8010682C_jp = 0x8010682C; // diff --git a/src/code/m_field_info.c b/src/code/m_field_info.c index 9277fa6..66722a8 100644 --- a/src/code/m_field_info.c +++ b/src/code/m_field_info.c @@ -1,70 +1,291 @@ #include "global.h" #include "m_field_info.h" +#include "m_random_field.h" #include "m_collision_bg.h" #include "libc64/qrand.h" -s32 mFI_GetPuleTypeIdx(u8 type); s32 mFI_BlockCheck(s32 blockX, s32 blockZ); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_ClearFieldData.s") +// mCoBG_unkStructUnion l_edge_ut = { { 0, 31, 31, 31, 31, 31, mCoBG_ATTRIBUTE_0 } }; +extern mCoBG_unkStructUnion l_edge_ut; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_CheckFieldData.s") +extern FieldMakeInfo* g_fdinfo; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_GetBlockTopP.s") +void mFI_ClearFieldData(void) { + g_fdinfo = NULL; +} + +s32 mFI_CheckFieldData(void) { + s32 result = FALSE; + + if (g_fdinfo != 0) { + result = TRUE; + } + + return result; +} -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_GetFieldId.s") +FieldMakeBlockInfo* mFI_GetBlockTopP() { + FieldMakeBlockInfo* blockInfo = NULL; + + if (g_fdinfo != NULL) { + blockInfo = g_fdinfo->blockInfo; + } + + return blockInfo; +} + +u16 mFI_GetFieldId(void) { + /* @BUG - check for null pointer omitted (fixed by AC at latest) */ + return g_fdinfo->fieldId; +} #pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80087C9C_jp.s") #pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80087D30_jp.s") -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80087DC8_jp.s") +s32 mFI_CheckShopFieldName(u16 fieldName) { + s32 result = FALSE; + + if (FI_GET_TYPE(fieldName) == FI_FIELD_ROOM0) { + switch (fieldName) { + case FI_FIELD_ROOM_SHOP0: + case FI_FIELD_ROOM_SHOP1: + case FI_FIELD_ROOM_SHOP2: + case FI_FIELD_ROOM_SHOP3_1: + case FI_FIELD_ROOM_SHOP3_2: + result = TRUE; + break; + } + } -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80087E14_jp.s") + return result; +} -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_GetBlockXMax.s") +s32 mFI_CheckShop(void) { + s32 result = FALSE; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_GetBlockZMax.s") + if (mFI_CheckFieldData() == TRUE) { + result = mFI_CheckShopFieldName(mFI_GetFieldId()); + } + return result; +} + +u8 mFI_GetBlockXMax() { + u8 blockXMax = 0; + + if (mFI_CheckFieldData() == TRUE) { + blockXMax = g_fdinfo->blockXMax; + } + + return blockXMax; +} + +u8 mFI_GetBlockZMax() { + u8 blockZMax = 0; + + if (mFI_CheckFieldData() == TRUE) { + blockZMax = g_fdinfo->blockZMax; + } + + return blockZMax; +} #pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80087ED0_jp.s") #pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088018_jp.s") -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088160_jp.s") +s32 mFI_GetBlockNum(s32 blockX, s32 blockZ) { + s32 blockNum = blockX + blockZ * mFI_GetBlockXMax(); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_8008819C_jp.s") + return blockNum; +} + +s32 mFI_GetUtNum(s32 utX, s32 utZ) { + return utX + utZ * UT_X_NUM; +} #pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_BlockCheck.s") -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088270_jp.s") +s32 mFI_UtNumCheck(int utX, int utZ, int blockXMax, int blockZMax) { + int result = TRUE; + int maxUtX = (blockXMax * UT_X_NUM); + int maxUtZ = (blockZMax * UT_Z_NUM); + + if ((utX < 0) || (utX >= maxUtX) || (utZ < 0) || (utZ >= maxUtZ)) { + result = FALSE; + } + + return result; +} + +s32 mFI_WposCheck(xyz_t wpos) { + s32 blockX UNUSED; + s32 blockZ; + + // Passing &blockZ twice is required to match. Since only the return value + // is used and not the block numbers, there is no practical difference. + return mFI_Wpos2BlockNum(&blockZ, &blockZ, wpos); +} + +s32 mFI_WposX2UtNumX(f32 wposX) { + return (s32)(wposX / FI_UT_WORLDSIZE_X_F); +} + +s32 mFI_WposZ2UtNumZ(f32 wposZ) { + return (s32)(wposZ / FI_UT_WORLDSIZE_Z_F); +} + +s32 mFI_Wpos2UtNum(s32* utX, s32* utZ, xyz_t wpos) { + *utX = (s32)(wpos.x / FI_UT_WORLDSIZE_X_F); + *utZ = (s32)(wpos.z / FI_UT_WORLDSIZE_Z_F); + + if ((wpos.x < 0.0f) || (wpos.x > (mFI_GetBlockXMax() * FI_BK_WORLDSIZE_X_F)) || (wpos.z < 0.0f) || + (wpos.z > (mFI_GetBlockZMax() * FI_BK_WORLDSIZE_Z_F))) { + return FALSE; + } + + return TRUE; +} + +s32 mFI_UtNum2CenterWpos(xyz_t* wpos, int utX, int utZ) { + s32 pad UNUSED; + + wpos->x = (f32)utX * FI_UT_WORLDSIZE_X_F; + wpos->z = (f32)utZ * FI_UT_WORLDSIZE_Z_F; + + wpos->x += FI_UT_WORLDSIZE_HALF_X_F; + wpos->z += FI_UT_WORLDSIZE_HALF_Z_F; + + return mFI_UtNumCheck(utX, utZ, mFI_GetBlockXMax(), mFI_GetBlockZMax()); +} + +s32 mFI_Wpos2UtCenterWpos(xyz_t* wpos, xyz_t sourcePos) { + f32 x = (s32)(sourcePos.x / FI_UT_WORLDSIZE_X_F) * FI_UT_WORLDSIZE_X; + f32 z = (s32)(sourcePos.z / FI_UT_WORLDSIZE_Z_F) * FI_UT_WORLDSIZE_Z; + + wpos->x = x + FI_UT_WORLDSIZE_HALF_Z_F; + wpos->y = sourcePos.y; + wpos->z = z + FI_UT_WORLDSIZE_HALF_Z_F; + + return mFI_WposCheck(sourcePos); +} + +s32 mFI_Wpos2UtNum_inBlock(s32* utX, s32* utZ, xyz_t wpos) { + s32 result = FALSE; + + if ((wpos.x >= 0.0f) && (wpos.x < ((f32)mFI_GetBlockXMax() * FI_BK_WORLDSIZE_X_F)) && (wpos.z >= 0.0f) && + (wpos.z < ((f32)mFI_GetBlockZMax() * FI_BK_WORLDSIZE_Z_F))) { + *utX = (s32)(wpos.x / FI_UT_WORLDSIZE_X_F); + *utZ = (s32)(wpos.z / FI_UT_WORLDSIZE_Z_F); + + *utX &= 0xF; + *utZ &= 0xF; + + result = TRUE; + } else { + *utX = 0; + *utZ = 0; + } + + return result; +} + +s32 mFI_Wpos2BlockNum(s32* blockX, s32* blockZ, xyz_t wpos) { + *blockX = (s32)(wpos.x / FI_BK_WORLDSIZE_X_F); + *blockZ = (s32)(wpos.z / FI_BK_WORLDSIZE_Z_F); + + return mFI_BlockCheck(*blockX, *blockZ); +} + +s32 mFI_Wpos2BkandUtNuminBlock(s32* blockX, s32* blockZ, s32* utX, s32* utZ, xyz_t wpos) { + *blockX = (s32)(wpos.x / FI_BK_WORLDSIZE_X_F); + *blockZ = (s32)(wpos.z / FI_BK_WORLDSIZE_Z_F); + *utX = (s32)(wpos.x / FI_UT_WORLDSIZE_X_F); + *utZ = (s32)(wpos.z / FI_UT_WORLDSIZE_Z_F); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800882AC_jp.s") + *utX &= 0xF; + *utZ &= 0xF; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800882FC_jp.s") + return mFI_BlockCheck(*blockX, *blockZ); +} -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088320_jp.s") +s32 mFI_UtNum2BlockNum(s32* blockX, s32* blockZ, s32 utX, s32 utZ) { + if (utX < 0) { + utX -= (UT_X_NUM - 1); + } -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_Wpos2UtNum.s") + if (utZ < 0) { + utZ -= (UT_Z_NUM - 1); + } -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088458_jp.s") + *blockX = utX / UT_X_NUM; + *blockZ = utZ / UT_Z_NUM; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_Wpos2UtCenterWpos.s") + return mFI_BlockCheck(*blockX, *blockZ); +} -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800885A8_jp.s") +s32 mFI_GetUtNumInBK(s32* blockUtX, s32* blockUtZ, s32 utX, s32 utZ) { + s32 result = mFI_UtNumCheck(utX, utZ, mFI_GetBlockXMax(), mFI_GetBlockZMax()); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_Wpos2BlockNum.s") + if (result) { + *blockUtX = utX & 0xF; + *blockUtZ = utZ & 0xF; + } else { + *blockUtX = 0; + *blockUtZ = 0; + } -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_Wpos2BkandUtNuminBlock.s") + return result; +} -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_8008883C_jp.s") +s32 mFI_WpostoLposInBK(xyz_t* lpos, xyz_t wpos) { + s32 blockX; + s32 blockZ; + s32 result = mFI_Wpos2BlockNum(&blockX, &blockZ, wpos); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800888AC_jp.s") + lpos->x = wpos.x - ((f32)blockX * FI_BK_WORLDSIZE_X_F); + lpos->y = wpos.y; + lpos->z = wpos.z - ((f32)blockZ * FI_BK_WORLDSIZE_Z_F); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088938_jp.s") + return result; +} -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800889D8_jp.s") +s32 mFI_LposInBKtoWpos(xyz_t* wpos, xyz_t lpos, s32 blockX, s32 blockZ) { + wpos->x = lpos.x + (f32)(blockX * FI_BK_WORLDSIZE_X); + wpos->y = lpos.y; + wpos->z = lpos.z + (f32)(blockZ * FI_BK_WORLDSIZE_Z); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088A58_jp.s") + return mFI_BlockCheck(blockX, blockZ); +} + +s32 mFI_ScrollCheck(xyz_t wpos, u8 dir) { + s32 blockX; + s32 blockZ; + + if (mFI_Wpos2BlockNum(&blockX, &blockZ, wpos) == FALSE) { + return FALSE; + } + + switch (dir) { + case FI_MOVEDIR_RIGHT: + blockX++; + break; + case FI_MOVEDIR_LEFT: + blockX--; + break; + case FI_MOVEDIR_UP: + blockZ--; + break; + case FI_MOVEDIR_DOWN: + blockZ++; + break; + default: + return FALSE; + } + + return mFI_BlockCheck(blockX, blockZ); +} s32 mFI_BkNum2WposXZ(f32* worldPosX, f32* worldPosZ, s32 blockX, s32 blockZ) { s32 result; @@ -80,11 +301,31 @@ s32 mFI_BkNum2WposXZ(f32* worldPosX, f32* worldPosZ, s32 blockX, s32 blockZ) { return result; } -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_UtNum2PosXZInBk.s") +void mFI_UtNum2PosXZInBk(f32* posX, f32* posZ, s32 utX, s32 utZ) { + *posX = (f32)(utX * FI_UT_WORLDSIZE_X); + *posZ = (f32)(utZ * FI_UT_WORLDSIZE_Z); +} + +void mFI_BkandUtNum2Wpos(xyz_t* wpos, s32 blockX, s32 blockZ, s32 utX, s32 utZ) { + f32 wposX; + f32 wposZ; + f32 bposX; + f32 bposZ; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088BFC_jp.s") + mFI_BkNum2WposXZ(&wposX, &wposZ, blockX, blockZ); + mFI_UtNum2PosXZInBk(&bposX, &bposZ, utX, utZ); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_BkandUtNum2CenterWpos.s") + wpos->x = wposX + bposX; + wpos->y = 0.0f; + wpos->z = wposZ + bposZ; +} + +void mFI_BkandUtNum2CenterWpos(xyz_t* wpos, s32 blockX, s32 blockZ, s32 utX, s32 utZ) { + mFI_BkandUtNum2Wpos(wpos, blockX, blockZ, utX, utZ); + + wpos->x += FI_UT_WORLDSIZE_HALF_X_F; + wpos->z += FI_UT_WORLDSIZE_HALF_Z_F; +} #pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80088CBC_jp.s") @@ -118,37 +359,151 @@ s32 mFI_BkNum2WposXZ(f32* worldPosX, f32* worldPosZ, s32 blockX, s32 blockZ) { #pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800891AC_jp.s") -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_BkNum2BlockType.s") +u8 mFI_BkNum2BlockType(s32 blockX, s32 blockZ) { + s32 blockNum; + u8 type = 39; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_GetPuleTypeIdx.s") + if (mFI_CheckFieldData() && mFI_BlockCheck(blockX, blockZ)) { + blockNum = mFI_GetBlockNum(blockX, blockZ); + type = g_block_type_p[blockNum]; + } + + return type; +} + +s32 mFI_GetPuleTypeIdx(u8 type) { + u32 kind = mRF_Type2BlockInfo(type); + s32 idx = -1; + + if ((kind & mRF_BLOCKKIND_POOL) == mRF_BLOCKKIND_POOL) { + idx = type - 69; + } + + return idx; +} s32 mFI_GetPuleIdx(void) { - u32 mask = (1 << 15); // TODO: make an enum/define + u32 kindPool = mRF_BLOCKKIND_POOL; s32 blockX; s32 blockZ; u8 type; s32 result; - mFI_BlockKind2BkNum(&blockX, &blockZ, mask); + mFI_BlockKind2BkNum(&blockX, &blockZ, kindPool); type = mFI_BkNum2BlockType(blockX, blockZ); result = mFI_GetPuleTypeIdx(type); return result; } -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80089348_jp.s") +u32 mFI_BkNum2BlockKind(s32 blockX, s32 blockZ) { + s32 blockNum; + u32 kind = mRF_BLOCKKIND_NONE; + + if (mFI_CheckFieldData() && mFI_BlockCheck(blockX, blockZ)) { + blockNum = mFI_GetBlockNum(blockX, blockZ); + + kind = g_fdinfo->blockInfo[blockNum].bgInfo.blockKind; + } + + return kind; +} + +s32 mFI_CheckBlockKind(s32 blockX, s32 blockZ, u32 blockKind) { + s32 isBlockKind = FALSE; + u32 kind = mFI_BkNum2BlockKind(blockX, blockZ); + + kind &= blockKind; + + if (blockKind == kind) { + isBlockKind = TRUE; + } + + return isBlockKind; +} + +s32 mFI_CheckBlockKind_OR(s32 blockX, s32 blockZ, u32 blockKindOr) { + s32 result = FALSE; + u32 kind = mFI_BkNum2BlockKind(blockX, blockZ); + + kind &= blockKindOr; + + if (kind != mRF_BLOCKKIND_NONE) { + result = TRUE; + } + + return result; +} + +s32 mFI_BlockKind2BkNum(s32* blockX, s32* blockZ, u32 kind) { + s32 i; + s32 succeeded = FALSE; + u32* kindP = g_block_kind_p; + + *blockX = 0; + *blockZ = 0; + + if (kindP != NULL) { + for (i = 0; i < BLOCK_TOTAL_NUM; i++) { + if (kind == (*kindP & kind)) { + *blockX = i % 7; + *blockZ = i / 7; + succeeded = TRUE; + + break; + } else { + kindP++; + } + } + } + + return succeeded; +} + +void mFI_GetSpecialBlockNum(s32* blockPos, u32* kinds, s32 count) { + s32 i; + + for (i = 0; i < count; i++) { + mFI_BlockKind2BkNum(blockPos + 0, blockPos + 1, *kinds); + kinds++; + blockPos += 2; + } +} -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800893C8_jp.s") +mCoBG_unkStructUnion* mFI_GetBkNum2ColTop(s32 blockX, s32 blockZ) { + mCoBG_unkStructUnion* col = NULL; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_CheckBlockKind_OR.s") + if (mFI_CheckFieldData() && mFI_BlockCheck(blockX, blockZ)) { + s32 blockNum = mFI_GetBlockNum(blockX, blockZ); -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_BlockKind2BkNum.s") + col = (mCoBG_unkStructUnion*)g_fdinfo->blockInfo[blockNum].bgInfo.collision; + } -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800894D0_jp.s") + return col; +} -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/mFI_GetBkNum2ColTop.s") +mCoBG_unkStructUnion* mFI_UtNum2UtCol(s32 utX, s32 utZ) { + mCoBG_unkStructUnion* collision; + s32 blockUtX; + s32 blockUtZ; + s32 blockX; + s32 blockZ; -#pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_800895B8_jp.s") + if (mFI_UtNumCheck(utX, utZ, mFI_GetBlockXMax(), mFI_GetBlockZMax()) == FALSE) { + return &l_edge_ut; + } else if (mFI_UtNum2BlockNum(&blockX, &blockZ, utX, utZ) == FALSE) { + return &l_edge_ut; + } else { + s32 blockNum; + + mFI_GetUtNumInBK(&blockUtX, &blockUtZ, utX, utZ); + blockNum = mFI_GetBlockNum(blockX, blockZ); + collision = (mCoBG_unkStructUnion*)g_fdinfo->blockInfo[blockNum].bgInfo.collision; + collision += blockUtZ * UT_X_NUM + blockUtX; + + return collision; + } +} #pragma GLOBAL_ASM("asm/jp/nonmatchings/code/m_field_info/func_80089698_jp.s") diff --git a/src/code/m_npc_walk.c b/src/code/m_npc_walk.c index 9a0cbd6..be7bd6a 100644 --- a/src/code/m_npc_walk.c +++ b/src/code/m_npc_walk.c @@ -328,7 +328,7 @@ s32 mNpcW_GetAloneBlock(u8* goalBlockX, u8* goalBlockZ) { z = 1; selected = RANDOM(FG_BLOCK_TOTAL_NUM - count); - for (i = 1; i < BLOCK_Z_NUM - 3; i++) { + for (i = 1; i < BLOCK_Z_NUM - 1; i++) { for (j = 1; j < BLOCK_X_NUM - 1; j++) { if (((block_field[z] >> j) & 1) == 0) { if (selected <= 0) { |
