From 60579a4260965c1de2e8a8f320fe9f8c3f5d2dde Mon Sep 17 00:00:00 2001 From: kuchenmitsahne <25233413+kuchenmitsahne@users.noreply.github.com> Date: Fri, 13 Dec 2024 11:54:39 -0500 Subject: m_field_info 37 additional functions OK (40/188 total) (#230) * 25 functions OK * 10 functions OK * Add block type and block kind enums/defines * Formatting/style pass * Move `FieldMakeBlockType` to `m_field_make` * Remove unused/duplicate defines --- src/code/m_field_info.c | 435 +++++++++++++++++++++++++++++++++++++++++++----- src/code/m_npc_walk.c | 2 +- 2 files changed, 396 insertions(+), 41 deletions(-) (limited to 'src/code') 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) { -- cgit v1.2.3