From caa281efea8d693206ad3adca9602fbfa29eea24 Mon Sep 17 00:00:00 2001 From: Kuruyia Date: Wed, 5 Feb 2025 22:25:07 +0100 Subject: [PATCH] Document BDHC util This documents the `bdhc_util.c` file, which mainly contains the function used to calculated an object's height based on its 2D position and the BDHC of the map its currently on. Signed-off-by: Kuruyia --- include/overlay005/bdhc.h | 17 +- include/overlay005/bdhc_loader.h | 18 - include/overlay005/ov5_021EEC68.h | 8 - include/overlay005/struct_ov5_021EED20.h | 10 - platinum.us/main.lsf | 3 +- src/meson.build | 3 +- src/overlay005/bdhc.c | 462 +++++++++++++++++++++++ src/overlay005/bdhc_loader.c | 269 ------------- src/overlay005/ov5_021E779C.c | 17 +- src/overlay005/ov5_021EEC68.c | 195 ---------- src/unk_02054D00.c | 3 +- 11 files changed, 489 insertions(+), 516 deletions(-) delete mode 100644 include/overlay005/bdhc_loader.h delete mode 100644 include/overlay005/ov5_021EEC68.h delete mode 100644 include/overlay005/struct_ov5_021EED20.h create mode 100644 src/overlay005/bdhc.c delete mode 100644 src/overlay005/bdhc_loader.c delete mode 100644 src/overlay005/ov5_021EEC68.c diff --git a/include/overlay005/bdhc.h b/include/overlay005/bdhc.h index 85a87f5c09..724b575425 100644 --- a/include/overlay005/bdhc.h +++ b/include/overlay005/bdhc.h @@ -2,11 +2,15 @@ #define POKEPLATINUM_OV5_BDHC_H #include +#include + +#include "narc.h" +#include "sys_task_manager.h" typedef struct BDHCPlate { u16 firstPointIndex; u16 secondPointIndex; - u16 normalIndex; + u16 slopeIndex; u16 heightIndex; } BDHCPlate; @@ -32,4 +36,15 @@ typedef struct BDHC { int stripsSize; } BDHC; +BOOL CalculateObjectHeight(const fx32 objectHeight, const fx32 objectX, const fx32 objectZ, const BDHC *bdhc, fx32 *newObjectHeight); + +void BDHC_Load(NARC *narc, const int bdhcSize, BDHC *bdhc, u8 *buffer); +SysTask *BDHC_LazyLoad(NARC *landDataNARC, const int unused1, BDHC *bdhc, int *param3, u8 **buffer, int *param5); +void BDHC_KillLoad(SysTask *sysTask); +void BDHC_MarkNotLoaded(BDHC *bdhc); + +BDHC *BDHC_New(void); +void BDHC_Free(BDHC *bdhc); +void BDHC_Reset(BDHC *bdhc); + #endif // POKEPLATINUM_OV5_BDHC_H diff --git a/include/overlay005/bdhc_loader.h b/include/overlay005/bdhc_loader.h deleted file mode 100644 index a03da6a2d9..0000000000 --- a/include/overlay005/bdhc_loader.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef POKEPLATINUM_OV5_BDHC_LOADER_H -#define POKEPLATINUM_OV5_BDHC_LOADER_H - -#include "overlay005/bdhc.h" - -#include "narc.h" -#include "sys_task_manager.h" - -void BDHCLoader_Load(NARC *narc, const int bdhcSize, BDHC *bdhc, u8 *buffer); -SysTask *BDHCLoader_StartTask(NARC *landDataNARC, const int param1, BDHC *bdhc, int *param3, u8 **buffer, int *param5); -void BDHCLoader_ForceExitTask(SysTask *sysTask); -void BDHCLoader_MarkBDHCNotLoaded(BDHC *bdhc); - -BDHC *BDHC_New(void); -void BDHC_Free(BDHC *bdhc); -void BDHC_Reset(BDHC *bdhc); - -#endif // POKEPLATINUM_OV5_BDHC_LOADER_H diff --git a/include/overlay005/ov5_021EEC68.h b/include/overlay005/ov5_021EEC68.h deleted file mode 100644 index abb484e15b..0000000000 --- a/include/overlay005/ov5_021EEC68.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef POKEPLATINUM_OV5_021EEC68_H -#define POKEPLATINUM_OV5_021EEC68_H - -#include "overlay005/bdhc.h" - -BOOL ov5_021EED9C(const fx32 param0, const fx32 param1, const fx32 param2, const BDHC *param3, fx32 *param4); - -#endif // POKEPLATINUM_OV5_021EEC68_H diff --git a/include/overlay005/struct_ov5_021EED20.h b/include/overlay005/struct_ov5_021EED20.h deleted file mode 100644 index 1deb10dbad..0000000000 --- a/include/overlay005/struct_ov5_021EED20.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef POKEPLATINUM_STRUCT_OV5_021EED20_H -#define POKEPLATINUM_STRUCT_OV5_021EED20_H - -typedef struct UnkStruct_ov5_021EED20_t { - fx32 unk_00; - int unk_04; - int unk_08; -} UnkStruct_ov5_021EED20; - -#endif // POKEPLATINUM_STRUCT_OV5_021EED20_H diff --git a/platinum.us/main.lsf b/platinum.us/main.lsf index 7c8a27410b..ba8aa59e70 100644 --- a/platinum.us/main.lsf +++ b/platinum.us/main.lsf @@ -508,8 +508,7 @@ Overlay overlay5 Object main.nef.p/src_overlay005_ov5_021EE75C.c.o Object main.nef.p/src_overlay005_ov5_021EE7D4.c.o Object main.nef.p/src_overlay005_ov5_021EEAC8.c.o - Object main.nef.p/src_overlay005_ov5_021EEC68.c.o - Object main.nef.p/src_overlay005_bdhc_loader.c.o + Object main.nef.p/src_overlay005_bdhc.c.o Object main.nef.p/src_overlay005_ov5_021EF250.c.o Object main.nef.p/src_overlay005_hblank_system.c.o Object main.nef.p/src_overlay005_ov5_021EF4BC.c.o diff --git a/src/meson.build b/src/meson.build index 7a56f1267f..98716c21ea 100644 --- a/src/meson.build +++ b/src/meson.build @@ -401,8 +401,7 @@ pokeplatinum_c = files( 'overlay005/ov5_021EE75C.c', 'overlay005/ov5_021EE7D4.c', 'overlay005/ov5_021EEAC8.c', - 'overlay005/ov5_021EEC68.c', - 'overlay005/bdhc_loader.c', + 'overlay005/bdhc.c', 'overlay005/ov5_021EF250.c', 'overlay005/hblank_system.c', 'overlay005/ov5_021EF4BC.c', diff --git a/src/overlay005/bdhc.c b/src/overlay005/bdhc.c new file mode 100644 index 0000000000..4c0aaab394 --- /dev/null +++ b/src/overlay005/bdhc.c @@ -0,0 +1,462 @@ +#include "overlay005/bdhc.h" + +#include +#include + +#include "constants/bdhc.h" +#include "constants/heap.h" + +#include "fx_util.h" +#include "heap.h" +#include "narc.h" +#include "sys_task.h" +#include "sys_task_manager.h" + +#define BDHC_NEW_OBJECT_HEIGHT_CANDIDATES_ARRAY_SIZE 10 + +enum BDHCSubTask { + BDHC_LOADER_SUBTASK_PREPARE_FILE_LOAD = 0, + BDHC_LOADER_SUBTASK_LOAD_FILE, + BDHC_LOADER_SUBTASK_END_TASK, +}; + +typedef struct { + int pointsSize; + int slopesSize; + int heightsSize; + int platesSize; + int stripsSize; + int accessListSize; +} BDHCHeader; + +typedef struct { + FSFile dummy00; + int dummyAC; + BDHCHeader bdhcHeader; + BOOL dummyC8; + u8 currentSubTask; + u8 *buffer; + BDHC *bdhc; + BOOL killLoadTask; + int *unk_DC; + NARC *landDataNARC; + int dummyE4; + int *unk_E8; +} BDHCLoaderTaskContext; + +typedef struct { + fx32 val; + int dummy04; + int dummy08; +} BDHCCandidateObjectHeight; + +static BOOL BDHC_FindStripIndexByLowerBound(const BDHCStrip *strips, const u16 stripsSize, const fx32 targetLowerBound, u16 *stripIndex); + +static void BDHC_PrepareBuffers(const BDHCHeader *bdhcHeader, BDHC *bdhc, void **buffer); +static void BDHC_LoadPoints(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); +static void BDHC_LoadSlopes(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); +static void BDHC_LoadHeights(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); +static void BDHC_LoadPlates(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); +static void BDHC_LoadStrips(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); +static void BDHC_LoadAccessList(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); + +static BOOL BDHC_IsPointInBoundingBox(const BDHCPoint *boundingBoxFirstPoint, const BDHCPoint *boundingBoxSecondPoint, const BDHCPoint *point) +{ + const fx32 *boundingBoxLeft, *boundingBoxRight, *boundingBoxUp, *boundingBoxDown; + + if (boundingBoxFirstPoint->x <= boundingBoxSecondPoint->x) { + boundingBoxLeft = &boundingBoxFirstPoint->x; + boundingBoxRight = &boundingBoxSecondPoint->x; + } else { + boundingBoxLeft = &boundingBoxSecondPoint->x; + boundingBoxRight = &boundingBoxFirstPoint->x; + } + + if (boundingBoxFirstPoint->y <= boundingBoxSecondPoint->y) { + boundingBoxUp = &boundingBoxFirstPoint->y; + boundingBoxDown = &boundingBoxSecondPoint->y; + } else { + boundingBoxUp = &boundingBoxSecondPoint->y; + boundingBoxDown = &boundingBoxFirstPoint->y; + } + + if (((*boundingBoxLeft <= point->x) && (point->x <= *boundingBoxRight)) && ((*boundingBoxUp <= point->y) && (point->y <= *boundingBoxDown))) { + return TRUE; + } + + return FALSE; +} + +static void BDHC_GetPointsFromPlate(const BDHC *bdhc, u16 plateIndex, BDHCPoint *platePoints) +{ + platePoints[0] = bdhc->points[bdhc->plates[plateIndex].firstPointIndex]; + platePoints[1] = bdhc->points[bdhc->plates[plateIndex].secondPointIndex]; +} + +static void BDHC_GetSlopeFromPlate(const BDHC *bdhc, u16 plateIndex, VecFx32 *slope) +{ + *slope = bdhc->slopes[bdhc->plates[plateIndex].slopeIndex]; +} + +static void BDHC_GetHeightFromPlate(const BDHC *bdhc, u16 plateIndex, fx32 *height) +{ + *height = bdhc->heights[bdhc->plates[plateIndex].heightIndex]; +} + +static void BDHC_InitCandidateObjectHeightsArray(BDHCCandidateObjectHeight *candidateObjectHeights) +{ + for (int i = 0; i < BDHC_NEW_OBJECT_HEIGHT_CANDIDATES_ARRAY_SIZE; i++) { + candidateObjectHeights[i].val = 0; + candidateObjectHeights[i].dummy04 = -1; + candidateObjectHeights[i].dummy08 = -1; + } +} + +static BOOL BDHC_FindStripIndexByLowerBound(const BDHCStrip *strips, const u16 stripsSize, const fx32 targetLowerBound, u16 *stripIndex) +{ + int low, high; + u32 mid; + + if (stripsSize == 0) { + return FALSE; + } else if (stripsSize == 1) { + *stripIndex = 0; + return TRUE; + } + + // Simple binary search. + low = 0; + high = stripsSize - 1; + mid = high / 2; + + do { + if (strips[mid].lowerBound > targetLowerBound) { + if (high - 1 > low) { + high = mid; + mid = (low + high) / 2; + } else { + *stripIndex = mid; + return TRUE; + } + } else { + if (low + 1 < high) { + low = mid; + mid = (low + high) / 2; + } else { + *stripIndex = mid + 1; + return TRUE; + } + } + } while (TRUE); + + return FALSE; +} + +BOOL CalculateObjectHeight(const fx32 objectHeight, const fx32 objectX, const fx32 objectZ, const BDHC *bdhc, fx32 *newObjectHeight) +{ + BDHCPoint platePoints[2]; + BDHCPoint objectPosition; + VecFx32 slope; + fx32 minObjectHeightDiff, objectHeightDiff; + BOOL isPointInBoundingBox; + u16 i, plateIndex; + fx32 height, calculatedObjectHeight; + int newObjectHeightCandidateCount; + u32 stripsSize; + BDHCCandidateObjectHeight newObjectHeightCandidates[BDHC_NEW_OBJECT_HEIGHT_CANDIDATES_ARRAY_SIZE]; + u32 accessListStartIndex; + u16 stripIndex; + u16 accessListElementCount; + const BDHCStrip *strips; + + if (bdhc->loaded == FALSE) { + return FALSE; + } + + isPointInBoundingBox = FALSE; + + objectPosition.x = objectX; + objectPosition.y = objectZ; + + newObjectHeightCandidateCount = 0; + BDHC_InitCandidateObjectHeightsArray(newObjectHeightCandidates); + + stripsSize = bdhc->stripsSize; + strips = bdhc->strips; + + if (BDHC_FindStripIndexByLowerBound(strips, stripsSize, objectPosition.y, &stripIndex) == FALSE) { + return FALSE; + } + + accessListElementCount = strips[stripIndex].accessListElementCount; + accessListStartIndex = strips[stripIndex].accessListStartIndex; + + for (i = 0; i < accessListElementCount; i++) { + plateIndex = bdhc->accessList[accessListStartIndex + i]; + BDHC_GetPointsFromPlate(bdhc, plateIndex, platePoints); + isPointInBoundingBox = BDHC_IsPointInBoundingBox(&platePoints[0], &platePoints[1], &objectPosition); + + if (isPointInBoundingBox == TRUE) { + BDHC_GetSlopeFromPlate(bdhc, plateIndex, &slope); + BDHC_GetHeightFromPlate(bdhc, plateIndex, &height); + + // On the next line, `slope.z` and `objectPosition.y` represent the same axis. + // Remember that `objectPosition.y` is, in fact, `objectZ`. + // Also, remember that `slope` is a normal vector, pointing upwards for a flat surface. + calculatedObjectHeight = -(FX_Mul(slope.x, objectPosition.x) + FX_Mul(slope.z, objectPosition.y) + height); + calculatedObjectHeight = FX_Div(calculatedObjectHeight, slope.y); + + newObjectHeightCandidates[newObjectHeightCandidateCount].val = calculatedObjectHeight; + newObjectHeightCandidateCount++; + + if (newObjectHeightCandidateCount >= BDHC_NEW_OBJECT_HEIGHT_CANDIDATES_ARRAY_SIZE) { + break; + } + } + } + + if (newObjectHeightCandidateCount > 1) { + // Find the candidate with the smallest difference between the object's current height and the calculated height. + plateIndex = 0; + minObjectHeightDiff = FX_Max(objectHeight, newObjectHeightCandidates[0].val) - FX_Min(objectHeight, newObjectHeightCandidates[0].val); + + for (i = 1; i < newObjectHeightCandidateCount; i++) { + objectHeightDiff = FX_Max(objectHeight, newObjectHeightCandidates[i].val) - FX_Min(objectHeight, newObjectHeightCandidates[i].val); + + if (minObjectHeightDiff > objectHeightDiff) { + minObjectHeightDiff = objectHeightDiff; + plateIndex = i; + } + } + + *newObjectHeight = newObjectHeightCandidates[plateIndex].val; + return TRUE; + } else if (newObjectHeightCandidateCount == 1) { + *newObjectHeight = newObjectHeightCandidates[0].val; + return TRUE; + } + + if (newObjectHeightCandidateCount != 0) { + *newObjectHeight = newObjectHeightCandidates[0].val; + return TRUE; + } + + return FALSE; +} + +static void BDHC_LoadHeader(NARC *narc, BDHCHeader *bdhcHeader) +{ + u16 magic[BDHC_MAGIC_LENGTH]; + + MI_CpuClear32(bdhcHeader, sizeof(BDHCHeader)); + + NARC_ReadFile(narc, BDHC_MAGIC_LENGTH, magic); + NARC_ReadFile(narc, 2, &bdhcHeader->pointsSize); + NARC_ReadFile(narc, 2, &bdhcHeader->slopesSize); + NARC_ReadFile(narc, 2, &bdhcHeader->heightsSize); + NARC_ReadFile(narc, 2, &bdhcHeader->platesSize); + NARC_ReadFile(narc, 2, &bdhcHeader->stripsSize); + NARC_ReadFile(narc, 2, &bdhcHeader->accessListSize); +} + +static void BDHC_PrepareBuffers(const BDHCHeader *bdhcHeader, BDHC *bdhc, void **buffer) +{ + void *ptr; + int offset = 0; + + ptr = (u8 *)*buffer; + bdhc->points = ptr; + offset += (sizeof(BDHCPoint) * bdhcHeader->pointsSize); + + ptr = (u8 *)*buffer + offset; + bdhc->slopes = ptr; + offset += (sizeof(VecFx32) * bdhcHeader->slopesSize); + + ptr = (u8 *)*buffer + offset; + bdhc->heights = ptr; + offset += (sizeof(fx32) * bdhcHeader->heightsSize); + + ptr = (u8 *)*buffer + offset; + bdhc->plates = ptr; + offset += (sizeof(BDHCPlate) * bdhcHeader->platesSize); + + ptr = (u8 *)*buffer + offset; + bdhc->strips = ptr; + offset += sizeof(BDHCStrip) * bdhcHeader->stripsSize; + + ptr = (u8 *)*buffer + offset; + bdhc->accessList = ptr; + offset += sizeof(u16) * bdhcHeader->accessListSize; + + GF_ASSERT(offset <= BDHC_BUFFER_SIZE); +} + +static void BDHC_LoadPoints(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) +{ + NARC_ReadFile(narc, sizeof(BDHCPoint) * bdhcHeader->pointsSize, bdhc->points); +} + +static void BDHC_LoadSlopes(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) +{ + NARC_ReadFile(narc, sizeof(VecFx32) * bdhcHeader->slopesSize, bdhc->slopes); +} + +static void BDHC_LoadHeights(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) +{ + NARC_ReadFile(narc, sizeof(fx32) * bdhcHeader->heightsSize, bdhc->heights); +} + +static void BDHC_LoadPlates(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) +{ + NARC_ReadFile(narc, sizeof(BDHCPlate) * bdhcHeader->platesSize, bdhc->plates); +} + +static void BDHC_LoadStrips(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) +{ + NARC_ReadFile(narc, sizeof(BDHCStrip) * bdhcHeader->stripsSize, bdhc->strips); +} + +static void BDHC_LoadAccessList(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) +{ + NARC_ReadFile(narc, sizeof(u16) * bdhcHeader->accessListSize, bdhc->accessList); +} + +static void BDHC_LazyLoadTask(SysTask *sysTask, void *sysTaskParam) +{ + BOOL subTaskCompleted; + BDHCLoaderTaskContext *ctx = (BDHCLoaderTaskContext *)sysTaskParam; + + if (ctx->killLoadTask == TRUE) { + ctx->currentSubTask = BDHC_LOADER_SUBTASK_END_TASK; + } + + switch (ctx->currentSubTask) { + case BDHC_LOADER_SUBTASK_PREPARE_FILE_LOAD: + if (*ctx->unk_E8) { + subTaskCompleted = FALSE; + break; + } + + BDHC_LoadHeader(ctx->landDataNARC, &ctx->bdhcHeader); + ctx->bdhc->stripsSize = ctx->bdhcHeader.stripsSize; + BDHC_PrepareBuffers(&ctx->bdhcHeader, ctx->bdhc, (void **)&ctx->buffer); + + subTaskCompleted = TRUE; + break; + + case BDHC_LOADER_SUBTASK_LOAD_FILE: + BDHC_LoadPoints(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); + BDHC_LoadSlopes(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); + BDHC_LoadHeights(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); + BDHC_LoadPlates(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); + BDHC_LoadStrips(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); + BDHC_LoadAccessList(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); + + subTaskCompleted = TRUE; + break; + + case BDHC_LOADER_SUBTASK_END_TASK: + *ctx->unk_DC = 0; + + Heap_FreeToHeap((void *)sysTaskParam); + SysTask_Done(sysTask); + + return; + } + + if (subTaskCompleted == TRUE) { + ctx->currentSubTask++; + + if (ctx->currentSubTask == BDHC_LOADER_SUBTASK_END_TASK) { + ctx->bdhc->loaded = TRUE; + } + } +} + +BDHC *BDHC_New(void) +{ + BDHC *bdhc = Heap_AllocFromHeap(HEAP_ID_FIELD, sizeof(BDHC)); + + bdhc->points = NULL; + bdhc->slopes = NULL; + bdhc->plates = NULL; + bdhc->strips = NULL; + bdhc->accessList = NULL; + bdhc->accessList = NULL; + bdhc->loaded = FALSE; + bdhc->stripsSize = 0; + + return bdhc; +} + +void BDHC_Load(NARC *narc, const int bdhcSize, BDHC *bdhc, u8 *buffer) +{ + BDHCHeader *bdhcHeader = Heap_AllocFromHeapAtEnd(HEAP_ID_FIELD, sizeof(BDHCHeader)); + + BDHC_LoadHeader(narc, bdhcHeader); + bdhc->stripsSize = bdhcHeader->stripsSize; + BDHC_PrepareBuffers(bdhcHeader, bdhc, (void **)&buffer); + + BDHC_LoadPoints(narc, bdhc, bdhcHeader); + BDHC_LoadSlopes(narc, bdhc, bdhcHeader); + BDHC_LoadHeights(narc, bdhc, bdhcHeader); + BDHC_LoadPlates(narc, bdhc, bdhcHeader); + BDHC_LoadStrips(narc, bdhc, bdhcHeader); + BDHC_LoadAccessList(narc, bdhc, bdhcHeader); + + Heap_FreeToHeap(bdhcHeader); + bdhc->loaded = TRUE; +} + +void BDHC_Free(BDHC *bdhc) +{ + if (bdhc == NULL) { + return; + } + + Heap_FreeToHeap(bdhc); + bdhc = NULL; +} + +void BDHC_Reset(BDHC *bdhc) +{ + if (bdhc == NULL) { + return; + } + + bdhc->loaded = FALSE; + bdhc->points = NULL; + bdhc->slopes = NULL; + bdhc->plates = NULL; + bdhc->strips = NULL; + bdhc->accessList = NULL; +} + +SysTask *BDHC_LazyLoad(NARC *landDataNARC, const int unused1, BDHC *bdhc, int *param3, u8 **buffer, int *param5) +{ + BDHCLoaderTaskContext *ctx = Heap_AllocFromHeapAtEnd(HEAP_ID_FIELD, sizeof(BDHCLoaderTaskContext)); + + ctx->currentSubTask = BDHC_LOADER_SUBTASK_PREPARE_FILE_LOAD; + ctx->landDataNARC = landDataNARC; + ctx->dummyE4 = unused1; + ctx->bdhc = bdhc; + ctx->unk_DC = param3; + ctx->killLoadTask = FALSE; + ctx->dummyC8 = FALSE; + ctx->dummyAC = 0; + ctx->buffer = *buffer; + ctx->unk_E8 = param5; + + return SysTask_Start(BDHC_LazyLoadTask, (void *)ctx, 1); +} + +void BDHC_KillLoad(SysTask *sysTask) +{ + BDHCLoaderTaskContext *ctx = SysTask_GetParam(sysTask); + ctx->killLoadTask = TRUE; +} + +void BDHC_MarkNotLoaded(BDHC *bdhc) +{ + bdhc->loaded = FALSE; +} diff --git a/src/overlay005/bdhc_loader.c b/src/overlay005/bdhc_loader.c deleted file mode 100644 index a79d9e00c7..0000000000 --- a/src/overlay005/bdhc_loader.c +++ /dev/null @@ -1,269 +0,0 @@ -#include "overlay005/bdhc_loader.h" - -#include -#include - -#include "constants/bdhc.h" -#include "constants/heap.h" - -#include "overlay005/bdhc.h" - -#include "heap.h" -#include "narc.h" -#include "sys_task.h" -#include "sys_task_manager.h" - -enum BDHCSubTask { - BDHC_LOADER_SUBTASK_PREPARE_FILE_LOAD = 0, - BDHC_LOADER_SUBTASK_LOAD_FILE, - BDHC_LOADER_SUBTASK_END_TASK, -}; - -typedef struct { - int pointsSize; - int slopesSize; - int heightsSize; - int platesSize; - int stripsSize; - int accessListSize; -} BDHCHeader; - -typedef struct { - FSFile unk_00; - int unk_AC; - BDHCHeader bdhcHeader; - BOOL unk_C8; - u8 currentSubTask; - u8 *buffer; - BDHC *bdhc; - BOOL forceExit; - int *unk_DC; - NARC *landDataNARC; - int unk_E4; - int *unk_E8; -} BDHCLoaderTaskContext; - -static void BDHCLoader_PrepareBuffers(const BDHCHeader *bdhcHeader, BDHC *bdhc, void **buffer); -static void BDHCLoader_LoadPoints(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); -static void BDHCLoader_LoadSlopes(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); -static void BDHCLoader_LoadHeights(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); -static void BDHCLoader_LoadPlates(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); -static void BDHCLoader_LoadStrips(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); -static void BDHCLoader_LoadAccessList(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader); - -static void BDHCLoader_LoadHeader(NARC *narc, BDHCHeader *bdhcHeader) -{ - u16 magic[BDHC_MAGIC_LENGTH]; - - MI_CpuClear32(bdhcHeader, sizeof(BDHCHeader)); - - NARC_ReadFile(narc, BDHC_MAGIC_LENGTH, magic); - NARC_ReadFile(narc, 2, &bdhcHeader->pointsSize); - NARC_ReadFile(narc, 2, &bdhcHeader->slopesSize); - NARC_ReadFile(narc, 2, &bdhcHeader->heightsSize); - NARC_ReadFile(narc, 2, &bdhcHeader->platesSize); - NARC_ReadFile(narc, 2, &bdhcHeader->stripsSize); - NARC_ReadFile(narc, 2, &bdhcHeader->accessListSize); -} - -static void BDHCLoader_PrepareBuffers(const BDHCHeader *bdhcHeader, BDHC *bdhc, void **buffer) -{ - void *ptr; - int offset = 0; - - ptr = (u8 *)*buffer; - bdhc->points = ptr; - offset += (sizeof(BDHCPoint) * bdhcHeader->pointsSize); - - ptr = (u8 *)*buffer + offset; - bdhc->slopes = ptr; - offset += (sizeof(VecFx32) * bdhcHeader->slopesSize); - - ptr = (u8 *)*buffer + offset; - bdhc->heights = ptr; - offset += (sizeof(fx32) * bdhcHeader->heightsSize); - - ptr = (u8 *)*buffer + offset; - bdhc->plates = ptr; - offset += (sizeof(BDHCPlate) * bdhcHeader->platesSize); - - ptr = (u8 *)*buffer + offset; - bdhc->strips = ptr; - offset += sizeof(BDHCStrip) * bdhcHeader->stripsSize; - - ptr = (u8 *)*buffer + offset; - bdhc->accessList = ptr; - offset += sizeof(u16) * bdhcHeader->accessListSize; - - GF_ASSERT(offset <= BDHC_BUFFER_SIZE); -} - -static void BDHCLoader_LoadPoints(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) -{ - NARC_ReadFile(narc, sizeof(BDHCPoint) * bdhcHeader->pointsSize, bdhc->points); -} - -static void BDHCLoader_LoadSlopes(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) -{ - NARC_ReadFile(narc, sizeof(VecFx32) * bdhcHeader->slopesSize, bdhc->slopes); -} - -static void BDHCLoader_LoadHeights(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) -{ - NARC_ReadFile(narc, sizeof(fx32) * bdhcHeader->heightsSize, bdhc->heights); -} - -static void BDHCLoader_LoadPlates(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) -{ - NARC_ReadFile(narc, sizeof(BDHCPlate) * bdhcHeader->platesSize, bdhc->plates); -} - -static void BDHCLoader_LoadStrips(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) -{ - NARC_ReadFile(narc, sizeof(BDHCStrip) * bdhcHeader->stripsSize, bdhc->strips); -} - -static void BDHCLoader_LoadAccessList(NARC *narc, BDHC *bdhc, const BDHCHeader *bdhcHeader) -{ - NARC_ReadFile(narc, sizeof(u16) * bdhcHeader->accessListSize, bdhc->accessList); -} - -static void BDHCLoader_RunTask(SysTask *sysTask, void *sysTaskParam) -{ - BOOL subTaskCompleted; - BDHCLoaderTaskContext *ctx = (BDHCLoaderTaskContext *)sysTaskParam; - - if (ctx->forceExit == TRUE) { - ctx->currentSubTask = BDHC_LOADER_SUBTASK_END_TASK; - } - - switch (ctx->currentSubTask) { - case BDHC_LOADER_SUBTASK_PREPARE_FILE_LOAD: - if (*ctx->unk_E8) { - subTaskCompleted = FALSE; - break; - } - - BDHCLoader_LoadHeader(ctx->landDataNARC, &ctx->bdhcHeader); - ctx->bdhc->stripsSize = ctx->bdhcHeader.stripsSize; - BDHCLoader_PrepareBuffers(&ctx->bdhcHeader, ctx->bdhc, (void **)&ctx->buffer); - - subTaskCompleted = TRUE; - break; - - case BDHC_LOADER_SUBTASK_LOAD_FILE: - BDHCLoader_LoadPoints(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); - BDHCLoader_LoadSlopes(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); - BDHCLoader_LoadHeights(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); - BDHCLoader_LoadPlates(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); - BDHCLoader_LoadStrips(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); - BDHCLoader_LoadAccessList(ctx->landDataNARC, ctx->bdhc, &ctx->bdhcHeader); - - subTaskCompleted = TRUE; - break; - - case BDHC_LOADER_SUBTASK_END_TASK: - *ctx->unk_DC = 0; - - Heap_FreeToHeap((void *)sysTaskParam); - SysTask_Done(sysTask); - - return; - } - - if (subTaskCompleted == TRUE) { - ctx->currentSubTask++; - - if (ctx->currentSubTask == BDHC_LOADER_SUBTASK_END_TASK) { - ctx->bdhc->loaded = TRUE; - } - } -} - -BDHC *BDHC_New(void) -{ - BDHC *bdhc = Heap_AllocFromHeap(HEAP_ID_FIELD, sizeof(BDHC)); - - bdhc->points = NULL; - bdhc->slopes = NULL; - bdhc->plates = NULL; - bdhc->strips = NULL; - bdhc->accessList = NULL; - bdhc->accessList = NULL; - bdhc->loaded = FALSE; - bdhc->stripsSize = 0; - - return bdhc; -} - -void BDHCLoader_Load(NARC *narc, const int bdhcSize, BDHC *bdhc, u8 *buffer) -{ - BDHCHeader *bdhcHeader = Heap_AllocFromHeapAtEnd(HEAP_ID_FIELD, sizeof(BDHCHeader)); - - BDHCLoader_LoadHeader(narc, bdhcHeader); - bdhc->stripsSize = bdhcHeader->stripsSize; - BDHCLoader_PrepareBuffers(bdhcHeader, bdhc, (void **)&buffer); - - BDHCLoader_LoadPoints(narc, bdhc, bdhcHeader); - BDHCLoader_LoadSlopes(narc, bdhc, bdhcHeader); - BDHCLoader_LoadHeights(narc, bdhc, bdhcHeader); - BDHCLoader_LoadPlates(narc, bdhc, bdhcHeader); - BDHCLoader_LoadStrips(narc, bdhc, bdhcHeader); - BDHCLoader_LoadAccessList(narc, bdhc, bdhcHeader); - - Heap_FreeToHeap(bdhcHeader); - bdhc->loaded = TRUE; -} - -void BDHC_Free(BDHC *bdhc) -{ - if (bdhc == NULL) { - return; - } - - Heap_FreeToHeap(bdhc); - bdhc = NULL; -} - -void BDHC_Reset(BDHC *bdhc) -{ - if (bdhc == NULL) { - return; - } - - bdhc->loaded = FALSE; - bdhc->points = NULL; - bdhc->slopes = NULL; - bdhc->plates = NULL; - bdhc->strips = NULL; - bdhc->accessList = NULL; -} - -SysTask *BDHCLoader_StartTask(NARC *landDataNARC, const int param1, BDHC *bdhc, int *param3, u8 **buffer, int *param5) -{ - BDHCLoaderTaskContext *ctx = Heap_AllocFromHeapAtEnd(HEAP_ID_FIELD, sizeof(BDHCLoaderTaskContext)); - - ctx->currentSubTask = BDHC_LOADER_SUBTASK_PREPARE_FILE_LOAD; - ctx->landDataNARC = landDataNARC; - ctx->unk_E4 = param1; - ctx->bdhc = bdhc; - ctx->unk_DC = param3; - ctx->forceExit = FALSE; - ctx->unk_C8 = FALSE; - ctx->unk_AC = 0; - ctx->buffer = *buffer; - ctx->unk_E8 = param5; - - return SysTask_Start(BDHCLoader_RunTask, (void *)ctx, 1); -} - -void BDHCLoader_ForceExitTask(SysTask *sysTask) -{ - BDHCLoaderTaskContext *ctx = SysTask_GetParam(sysTask); - ctx->forceExit = TRUE; -} - -void BDHCLoader_MarkBDHCNotLoaded(BDHC *bdhc) -{ - bdhc->loaded = FALSE; -} diff --git a/src/overlay005/ov5_021E779C.c b/src/overlay005/ov5_021E779C.c index 1578dce951..69f8f120cf 100644 --- a/src/overlay005/ov5_021E779C.c +++ b/src/overlay005/ov5_021E779C.c @@ -5,7 +5,6 @@ #include "field/field_system.h" #include "overlay005/bdhc.h" -#include "overlay005/bdhc_loader.h" #include "overlay005/funcptr_ov5_021E9630.h" #include "overlay005/ov5_021D521C.h" #include "overlay005/ov5_021E15F4.h" @@ -215,7 +214,7 @@ static void ov5_021E77E4(UnkStruct_ov5_021E8F60 *param0, const u8 param1) } if (param0->unk_04[param1].unk_00.unk_10.unk_04 != 0) { - BDHCLoader_ForceExitTask(param0->unk_04[param1].unk_00.unk_0C); + BDHC_KillLoad(param0->unk_04[param1].unk_00.unk_0C); } param0->unk_04[param1].unk_00.unk_24 = 1; @@ -228,7 +227,7 @@ static void ov5_021E7814(UnkStruct_ov5_021E7814 *param0) } if (param0->unk_10.unk_04 != 0) { - BDHCLoader_ForceExitTask(param0->unk_0C); + BDHC_KillLoad(param0->unk_0C); } param0->unk_10.unk_00 = 0; @@ -500,7 +499,7 @@ static void ov5_021E7C00(const u8 param0, UnkStruct_ov5_021EF76C *const param1, { param6->unk_10.unk_04++; - param6->unk_0C = BDHCLoader_StartTask(param5->unk_EC, v3.unk_08, param6->unk_00[param0]->bdhc, ¶m6->unk_10.unk_04, ¶m6->unk_00[param0]->bdhcBuffer, ¶m6->unk_10.unk_00); + param6->unk_0C = BDHC_LazyLoad(param5->unk_EC, v3.unk_08, param6->unk_00[param0]->bdhc, ¶m6->unk_10.unk_04, ¶m6->unk_00[param0]->bdhcBuffer, ¶m6->unk_10.unk_00); } } @@ -610,7 +609,7 @@ static void ov5_021E7E28(const int param0, const u8 param1, UnkStruct_ov5_021EF7 } { - BDHCLoader_Load(param7->unk_EC, v2.unk_08, param7->unk_84[param1]->bdhc, param7->unk_84[param1]->bdhcBuffer); + BDHC_Load(param7->unk_EC, v2.unk_08, param7->unk_84[param1]->bdhc, param7->unk_84[param1]->bdhcBuffer); } param7->unk_84[param1]->unk_860 = param0; @@ -691,7 +690,7 @@ static void ov5_021E7FF0(const int param0, const u8 param1, UnkStruct_ov5_021EF7 NARC_Seek(param7->unk_EC, v1.unk_04); { - BDHCLoader_Load(param7->unk_EC, v1.unk_08, param7->unk_84[param1]->bdhc, param7->unk_84[param1]->bdhcBuffer); + BDHC_Load(param7->unk_EC, v1.unk_08, param7->unk_84[param1]->bdhc, param7->unk_84[param1]->bdhcBuffer); } param7->unk_84[param1]->unk_860 = param0; @@ -1443,7 +1442,7 @@ static void ov5_021E8E28(UnkStruct_ov5_021E8F60 *param0, const int param1, const for (v0 = 0; v0 < 4; v0++) { param0->unk_84[v0]->bdhc = BDHC_New(); - BDHCLoader_MarkBDHCNotLoaded(param0->unk_84[v0]->bdhc); + BDHC_MarkNotLoaded(param0->unk_84[v0]->bdhc); ov5_021E7E28(v1[v0], v0, param0->unk_AC, param0->unk_B0, param0->unk_B4, param0->unk_B8, ov5_021EFAC0(param0->unk_AC), param0); } } @@ -2234,7 +2233,7 @@ void ov5_021E9D3C(MapMatrix *param0, UnkStruct_ov5_021EF76C *param1, UnkStruct_o for (v0 = 0; v0 < 4; v0++) { v1[v0] = param3->unk_84[v0]->unk_860; - BDHCLoader_MarkBDHCNotLoaded(param3->unk_84[v0]->bdhc); + BDHC_MarkNotLoaded(param3->unk_84[v0]->bdhc); } for (v0 = 0; v0 < 4; v0++) { @@ -2486,7 +2485,7 @@ void ov5_021EA5E0(UnkStruct_ov5_021E8F60 *param0, int param1, int param2) MI_CpuFillFast(param0->unk_84[param1]->unk_00, 0xffffffff, 2 * 32 * 32); - BDHCLoader_MarkBDHCNotLoaded(param0->unk_84[param1]->bdhc); + BDHC_MarkNotLoaded(param0->unk_84[param1]->bdhc); ov5_021E7E28(param2, param1, param0->unk_AC, param0->unk_B0, param0->unk_B4, param0->unk_B8, ov5_021EFAC0(param0->unk_AC), param0); } diff --git a/src/overlay005/ov5_021EEC68.c b/src/overlay005/ov5_021EEC68.c deleted file mode 100644 index f77e75e24c..0000000000 --- a/src/overlay005/ov5_021EEC68.c +++ /dev/null @@ -1,195 +0,0 @@ -#include "overlay005/ov5_021EEC68.h" - -#include -#include - -#include "overlay005/bdhc.h" -#include "overlay005/struct_ov5_021EED20.h" - -#include "fx_util.h" - -static BOOL ov5_021EED38(const BDHCStrip *param0, const u16 param1, const fx32 param2, u16 *param3); - -static BOOL ov5_021EEC68(const BDHCPoint *param0, const BDHCPoint *param1, const BDHCPoint *param2) -{ - const fx32 *v0, *v1, *v2, *v3; - - if (param0->x <= param1->x) { - v0 = ¶m0->x; - v1 = ¶m1->x; - } else { - v0 = ¶m1->x; - v1 = ¶m0->x; - } - - if (param0->y <= param1->y) { - v2 = ¶m0->y; - v3 = ¶m1->y; - } else { - v2 = ¶m1->y; - v3 = ¶m0->y; - } - - if (((*v0 <= param2->x) && (param2->x <= *v1)) && ((*v2 <= param2->y) && (param2->y <= *v3))) { - return 1; - } - - return 0; -} - -static void ov5_021EECB8(const BDHC *param0, u16 param1, BDHCPoint *param2) -{ - param2[0] = param0->points[param0->plates[param1].firstPointIndex]; - param2[1] = param0->points[param0->plates[param1].secondPointIndex]; -} - -static void ov5_021EECE8(const BDHC *param0, u16 param1, VecFx32 *param2) -{ - *param2 = param0->slopes[param0->plates[param1].normalIndex]; -} - -static void ov5_021EED08(const BDHC *param0, u16 param1, fx32 *param2) -{ - *param2 = param0->heights[param0->plates[param1].heightIndex]; -} - -static void ov5_021EED20(UnkStruct_ov5_021EED20 *param0) -{ - int v0; - - for (v0 = 0; v0 < 10; v0++) { - param0[v0].unk_00 = 0; - param0[v0].unk_04 = -1; - param0[v0].unk_08 = -1; - } -} - -static BOOL ov5_021EED38(const BDHCStrip *param0, const u16 param1, const fx32 param2, u16 *param3) -{ - int v0, v1; - u32 v2; - fx32 v3; - - if (param1 == 0) { - return 0; - } else if (param1 == 1) { - *param3 = 0; - return 1; - } - - v0 = 0; - v1 = param1 - 1; - v2 = v1 / 2; - - do { - v3 = param0[v2].lowerBound; - - if (v3 > param2) { - if (v1 - 1 > v0) { - v1 = v2; - v2 = (v0 + v1) / 2; - } else { - *param3 = v2; - return 1; - } - } else { - if (v0 + 1 < v1) { - v0 = v2; - v2 = (v0 + v1) / 2; - } else { - *param3 = v2 + 1; - return 1; - } - } - } while (TRUE); - - return 0; -} - -BOOL ov5_021EED9C(const fx32 param0, const fx32 param1, const fx32 param2, const BDHC *param3, fx32 *param4) -{ - BDHCPoint v0[2]; - BDHCPoint v1; - VecFx32 v2; - fx32 v3, v4; - BOOL v5; - u16 v6, v7; - fx32 v8, v9; - int v10; - u32 v11, v12, v13, v14; - UnkStruct_ov5_021EED20 v15[10]; - fx32 v16, v17; - u32 v18; - u16 v19; - u16 v20; - u16 v21; - const BDHCStrip *v22; - - if (param3->loaded == 0) { - return 0; - } - - v5 = 0; - - v1.x = param1; - v1.y = param2; - - v10 = 0; - ov5_021EED20(v15); - v11 = param3->stripsSize; - v22 = param3->strips; - - if (ov5_021EED38(v22, v11, v1.y, &v20) == 0) { - return 0; - } - - v21 = v22[v20].accessListElementCount; - v18 = v22[v20].accessListStartIndex; - - for (v6 = 0; v6 < v21; v6++) { - v7 = param3->accessList[v18 + v6]; - ov5_021EECB8(param3, v7, v0); - v5 = ov5_021EEC68(&v0[0], &v0[1], &v1); - - if (v5 == 1) { - ov5_021EECE8(param3, v7, &v2); - ov5_021EED08(param3, v7, &v8); - - v9 = -(FX_Mul(v2.x, v1.x) + FX_Mul(v2.z, v1.y) + v8); - v9 = FX_Div(v9, v2.y); - v15[v10].unk_00 = v9; - v10++; - - if (v10 >= 10) { - break; - } - } - } - - if (v10 > 1) { - v7 = 0; - v3 = FX_Max(param0, v15[0].unk_00) - FX_Min(param0, v15[0].unk_00); - - for (v6 = 1; v6 < v10; v6++) { - v4 = FX_Max(param0, v15[v6].unk_00) - FX_Min(param0, v15[v6].unk_00); - - if (v3 > v4) { - v3 = v4; - v7 = v6; - } - } - - *param4 = v15[v7].unk_00; - return 1; - } else if (v10 == 1) { - *param4 = v15[0].unk_00; - return 1; - } - - if (v10 != 0) { - *param4 = v15[0].unk_00; - return 1; - } - - return 0; -} diff --git a/src/unk_02054D00.c b/src/unk_02054D00.c index fee981366b..093c1113a5 100644 --- a/src/unk_02054D00.c +++ b/src/unk_02054D00.c @@ -9,7 +9,6 @@ #include "overlay005/bdhc.h" #include "overlay005/ov5_021E15F4.h" #include "overlay005/ov5_021E779C.h" -#include "overlay005/ov5_021EEC68.h" #include "overlay005/ov5_021EF250.h" #include "overlay005/struct_ov5_021E1608_decl.h" #include "overlay005/struct_ov5_021E1890_decl.h" @@ -105,7 +104,7 @@ static const fx32 sub_02054D0C(const FieldSystem *fieldSystem, const fx32 param1 } else { { const BDHC *v21 = ov5_021E9610(v18, v8); - v1 = ov5_021EED9C(v16, v11.x, v11.z, v21, &v11.y); + v1 = CalculateObjectHeight(v16, v11.x, v11.z, v21, &v11.y); } } }