From 756e57544253911fe9ab6ec6f56471e52f14b2a4 Mon Sep 17 00:00:00 2001 From: mrshigure Date: Mon, 5 Feb 2024 15:01:04 -0800 Subject: [PATCH] Matched board/com_path --- configure.py | 2 +- include/game/board/com_path.h | 11 + src/game/board/com_path.c | 545 ++++++++++++++++++++++++++++++++++ 3 files changed, 557 insertions(+), 1 deletion(-) create mode 100755 include/game/board/com_path.h create mode 100755 src/game/board/com_path.c diff --git a/configure.py b/configure.py index 05ee7986..09648156 100644 --- a/configure.py +++ b/configure.py @@ -387,7 +387,7 @@ config.libs = [ Object(NonMatching, "game/board/start.c"), Object(NonMatching, "game/board/last5.c"), Object(NonMatching, "game/board/pause.c"), - Object(NonMatching, "game/board/com_path.c"), + Object(Matching, "game/board/com_path.c"), Object(NonMatching, "game/board/tutorial.c"), Object(NonMatching, "game/kerent.c"), ], diff --git a/include/game/board/com_path.h b/include/game/board/com_path.h new file mode 100755 index 00000000..2fa6e313 --- /dev/null +++ b/include/game/board/com_path.h @@ -0,0 +1,11 @@ +#ifndef _BOARD_COM_PATH_H +#define _BOARD_COM_PATH_H + +#include "dolphin/types.h" + +s16 BoardComPathReachCheck(s16 arg0, u32 arg1, s32 arg2); +s16 BoardComPathBestGet(s16 arg0); +s16 BoardComPathLenGet(s16 arg0, s16 arg1); +s16 BoardComPathW20BestGet(s16 arg0, u32 arg1, s16 arg2); + +#endif diff --git a/src/game/board/com_path.c b/src/game/board/com_path.c new file mode 100755 index 00000000..c6b480a1 --- /dev/null +++ b/src/game/board/com_path.c @@ -0,0 +1,545 @@ +#include "game/board/com_path.h" +#include "game/board/space.h" + +#define NODE_INDEX(x) ((x) ? ((x) - pathNodeData) : -1) + +typedef struct { + /* 0x00 */ struct { + u8 unk00_field0 : 1; + u8 unk00_field1 : 1; + s8 unk00_field2 : 1; + s8 unk00_field3 : 1; + u8 unk00_field4 : 1; + u8 unk00_field5 : 1; + }; + /* 0x01 */ s8 unk01; + /* 0x02 */ s8 unk02; + /* 0x03 */ s8 unk03; + /* 0x04 */ s16 unk04; + /* 0x06 */ s16 unk06[2]; // array size unknown + /* 0x0A */ char unk0A[0x3C]; + /* 0x46 */ s16 unk46[5]; +} PathNode; // Size 0x50 + +static PathNode *SearchPathNodeSpace(s16 arg0); +static s16 InitPathNode(PathNode *arg0); +static PathNode *FindChildNode(s16 arg0, PathNode *arg1); +static s32 GetNumValidLinks(BoardSpace *arg0, PathNode *arg1); +static void AddValidLinks(BoardSpace *arg0, PathNode *arg1); +static BOOL CheckPathSpace(BoardSpace *arg0); +static s16 FindValidLink(BoardSpace *arg0); +static BOOL CheckEndSpace(BoardSpace *arg0, PathNode *arg1); +static BOOL CheckPath(PathNode *arg0); +static BOOL CheckW20Path(PathNode *arg0, u32 arg1); + +static PathNode pathNodeData[16]; +static PathNode *candidateNodes[16]; +static s16 startPathSpaceSearch[16]; +static s16 startPathSpace[16]; + +static s16 numCandidates; +static s16 childNodeCnt; + +static PathNode *SearchPathNodeSpace(s16 arg0) { + PathNode *var_r31; + s32 i; + + for (var_r31 = pathNodeData, i = 0; i < 16; i++, var_r31++) { + if (var_r31->unk04 == arg0) { + break; + } + } + if (i == 16) { + var_r31 = NULL; + } + return var_r31; +} + +static s16 InitPathNode(PathNode *arg0) { + BoardSpace *temp_r30; + PathNode *var_r23; + s32 var_r29; + s16 i; + s16 var_r27; + s16 var_r26; + s16 var_r25; + s16 var_r24; + + var_r24 = arg0->unk04; + var_r29 = 0; + arg0->unk02 = var_r25 = 0; + do { + var_r27 = var_r24; + temp_r30 = BoardSpaceGet(0, var_r27); + arg0->unk06[arg0->unk02] = var_r27; + var_r23 = FindChildNode(var_r27, arg0); + if (var_r23) { + AddValidLinks(temp_r30, arg0); + arg0->unk01 = 1; + arg0->unk46[0] = var_r27; + for (i = 1; i < 5; i++) { + arg0->unk46[i] = 0; + } + return 0; + } + if (temp_r30->link_cnt == 0) { + var_r26 = 0; + var_r29 = 1; + } else { + var_r26 = GetNumValidLinks(temp_r30, arg0); + if (var_r26 == 1) { + var_r24 = FindValidLink(temp_r30); + } else { + var_r29 = 1; + } + } + if (CheckEndSpace(temp_r30, arg0)) { + var_r25++; + if (var_r25 >= arg0->unk03) { + var_r26 = 0; + var_r29 = 1; + } + } + arg0->unk02++; + } while (var_r29 == 0); + AddValidLinks(temp_r30, arg0); + arg0->unk01 = var_r26; + return arg0->unk03 - var_r25; +} + +static PathNode *FindChildNode(s16 arg0, PathNode *arg1) { + PathNode *temp_r31; + s32 var_r28; + s32 i; + s32 j; + + var_r28 = NODE_INDEX(arg1); + if (var_r28 == -1) { + return NULL; + } + for (i = 0; i < childNodeCnt; i++) { + temp_r31 = &pathNodeData[i]; + if (temp_r31 != arg1) { + for (j = 0; j < temp_r31->unk02; j++) { + if (arg0 == temp_r31->unk06[j]) { + return temp_r31; + } + } + } + } + return NULL; +} + +static s32 GetNumValidLinks(BoardSpace *arg0, PathNode *arg1) { + BoardSpace *var_r28; + s16 i; + s16 var_r29; + + for (var_r29 = i = 0; i < arg0->link_cnt; i++) { + var_r28 = BoardSpaceGet(0, arg0->link[i]); + if (!CheckPathSpace(var_r28)) { + var_r29++; + } + } + if (var_r29 >= arg0->link_cnt) { + return 0; + } + return arg0->link_cnt - var_r29; +} + +static void AddValidLinks(BoardSpace *arg0, PathNode *arg1) { + BoardSpace *var_r27; + s16 var_r30; + s16 var_r31; + + for (var_r31 = var_r30 = 0; var_r30 < arg0->link_cnt; var_r30++) { + var_r27 = BoardSpaceGet(0, arg0->link[var_r30]); + if (CheckPathSpace(var_r27)) { + arg1->unk46[var_r31] = arg0->link[var_r30]; + var_r31++; + } + } + for (; var_r31 < 5; var_r31++) { + arg1->unk46[var_r31] = 0; + } +} + +static BOOL CheckPathSpace(BoardSpace *arg0) { + if ((arg0->flag & 0x02000000) || (arg0->flag & 0x04000000)) { + return FALSE; + } else { + return TRUE; + } +} + +static s16 FindValidLink(BoardSpace *arg0) { + s16 var_r29; + s16 i; + BoardSpace *temp_r30; + + for (var_r29 = i = 0; i < arg0->link_cnt; i++) { + var_r29 = arg0->link[i]; + temp_r30 = BoardSpaceGet(0, var_r29); + if (CheckPathSpace(temp_r30)) { + break; + } + } + return var_r29; +} + +static BOOL CheckEndSpace(BoardSpace *arg0, PathNode *arg1) { + if (arg0->flag & 0x80000000) { + } + if (arg0->flag & 0x4000000) { + } + if (arg0->flag & 0x2000000) { + } + if (arg0->flag & 0x180000) { + arg1->unk00_field3 = 1; + } + if (arg0->flag & 0x48000000) { + arg1->unk00_field4 = 1; + } + if (arg0->flag & 0x20000000) { + arg1->unk00_field2 = 1; + } + if (arg0->flag & 0x10000000) { + arg1->unk00_field5 = 1; + } + switch (arg0->type) { + case 8: + arg1->unk00_field1 = 1; + return FALSE; + case 10: + return FALSE; + case 0: + return FALSE; + } + return TRUE; +} + +static inline void ComPathInlineFunc02(PathNode *arg0) { + if (numCandidates < 16) { + candidateNodes[numCandidates] = arg0; + numCandidates++; + } +} + +static inline PathNode *ComPathInlineFunc03(void) { + PathNode *ret; + + numCandidates--; + if (numCandidates < 0) { + return NULL; + } else { + ret = candidateNodes[numCandidates]; + candidateNodes[numCandidates] = NULL; + return ret; + } +} + +static inline PathNode *ComPathInlineFunc04(s16 arg0, s16 arg1) { + PathNode *var_r26; + s32 i; + + var_r26 = pathNodeData; + for (i = 0; i < 16; i++, var_r26++) { + if (var_r26->unk00_field0 == 0) { + break; + } + } + if (i == 16) { + return NULL; + } else { + var_r26->unk00_field0 = 1; + var_r26->unk04 = arg0; + var_r26->unk03 = arg1; + childNodeCnt++; + return var_r26; + } +} + +static inline void ComPathInlineFunc05(s16 arg0, s16 arg1) { + PathNode *var_r28; + s32 var_r24; + s32 temp_r17; + s32 i; + PathNode *var_r23; + + memset(pathNodeData, 0, sizeof(pathNodeData)); + memset(candidateNodes, 0, sizeof(candidateNodes)); + numCandidates = 0; + childNodeCnt = 0; + var_r23 = ComPathInlineFunc04(arg0, arg1); + ComPathInlineFunc02(var_r23); + var_r24 = 1; + temp_r17 = arg1; + while (1) { + if (var_r24 <= 0) { + break; + } + var_r28 = ComPathInlineFunc03(); + if (!var_r28) { + break; + } + var_r24--; + temp_r17 = InitPathNode(var_r28); + if (temp_r17 != 0) { + if (var_r28->unk01 <= 1) { + break; + } + for (i = 0; i < var_r28->unk01; var_r24++, i++) { + var_r23 = ComPathInlineFunc04(var_r28->unk46[i], temp_r17); + if (!var_r23) { + break; + } + ComPathInlineFunc02(var_r23); + } + } + } +} + +s16 BoardComPathReachCheck(s16 arg0, u32 arg1, s32 arg2) { + s16 sp80[10]; + s16 sp6C[10]; + PathNode *sp68; + PathNode *var_r29; + s16 sp1C; + s16 sp1A; + s16 temp_r20; + s16 var_r22; + s16 var_r28; + s16 i; + s32 var_r19; + + if (_CheckFlag(0x1000B)) { + return 0; + } + ComPathInlineFunc05(arg0, 0x1E); + memset(startPathSpaceSearch, 0, sizeof(startPathSpaceSearch)); + memset(sp80, 0, sizeof(sp80)); + memset(candidateNodes, 0, sizeof(candidateNodes)); + numCandidates = 0; + var_r29 = SearchPathNodeSpace(arg0); + sp1A = NODE_INDEX(var_r29); + ComPathInlineFunc02(var_r29); + var_r28 = 0; + var_r22 = 0; + startPathSpaceSearch[sp1A] = var_r28; + var_r19 = 0; + while (1) { + var_r29 = ComPathInlineFunc03(); + sp1C = NODE_INDEX(var_r29); + if (sp1C == -1) { + if (var_r22 != 0) { + break; + } + } else { + var_r19 = 0; + var_r28 = startPathSpaceSearch[sp1C]; + for (i = 0; i < var_r29->unk02; i++) { + if (arg2 == 0 && (BoardSpaceFlagGet(0, var_r29->unk06[i]) & 0x20000000)) { + break; + } + if (arg1 == BoardSpaceTypeGet(0, var_r29->unk06[i])) { + sp80[var_r22] = var_r28; + sp6C[var_r22] = sp1C; + if (++var_r22 < 0xA) { + var_r19 = 1; + break; + } else { + goto return_r28; + } + } + if (var_r28++ >= 0x1E) { + var_r19 = 1; + break; + } + } + if (var_r19 == 0) { + for (i = 0; i < var_r29->unk01; i++) { + sp68 = SearchPathNodeSpace(var_r29->unk46[i]); + temp_r20 = NODE_INDEX(sp68); + if (temp_r20 != -1 && temp_r20 >= 0 && temp_r20 < 16) { + startPathSpaceSearch[temp_r20] = var_r28; + ComPathInlineFunc02(sp68); + } + } + } + continue; + } + return 0; + } +return_r28: + var_r28 = 10000; + for (i = 0; i < 10; i++) { + if (var_r28 > sp80[i] && sp80[i] != 0) { + var_r28 = sp80[i]; + } + } + return var_r28; +} + +s16 BoardComPathBestGet(s16 arg0) { + PathNode *sp30; + PathNode *sp2C; + s32 i; + + ComPathInlineFunc05(arg0, 0x1E); + sp2C = SearchPathNodeSpace(arg0); + if (sp2C->unk00_field1 != 0) { + return -1; + } + if (sp2C->unk01 <= 1) { + return -1; + } + for (i = 0; i < sp2C->unk01; i++) { + sp30 = SearchPathNodeSpace(sp2C->unk46[i]); + if (sp30 && CheckPath(sp30)) { + return sp2C->unk46[i]; + } + } + return -1; +} + +s16 BoardComPathLenGet(s16 arg0, s16 arg1) { + PathNode *var_r30; + s16 temp_r21; + s16 var_r25; + s16 sp16; + s16 sp14; + s16 sp12; + s16 i; + s32 sp5C; + PathNode *sp58; + + ComPathInlineFunc05(arg0, 0x1E); + memset(startPathSpace, 0, sizeof(startPathSpace)); + memset(candidateNodes, 0, sizeof(candidateNodes)); + numCandidates = 0; + var_r30 = SearchPathNodeSpace(arg0); + sp12 = NODE_INDEX(var_r30); + ComPathInlineFunc02(var_r30); + var_r25 = 0; + sp16 = 0; + startPathSpace[sp12] = var_r25; + sp5C = 0; + while (1) { + var_r30 = ComPathInlineFunc03(); + sp14 = NODE_INDEX(var_r30); + if (sp14 == -1) { + if (sp16 != 0) { + break; + } + } else { + sp5C = 0; + var_r25 = startPathSpace[sp14]; + for (i = 0; i < var_r30->unk02; i++) { + if (BoardSpaceFlagGet(0, var_r30->unk06[i]) & 0x20000000) { + break; + } + if (var_r30->unk06[i] == arg1) { + goto return_r25; + } + if (var_r25++ >= 0x1E) { + sp5C = 1; + break; + } + } + if (sp5C == 0) { + for (i = 0; i < var_r30->unk01; i++) { + sp58 = SearchPathNodeSpace(var_r30->unk46[i]); + temp_r21 = NODE_INDEX(sp58); + if (temp_r21 != -1 && temp_r21 >= 0 && temp_r21 < 16) { + startPathSpace[temp_r21] = var_r25; + ComPathInlineFunc02(sp58); + } + } + } + continue; + } + return 0; + } +return_r25: + return var_r25; +} + +static BOOL CheckPath(PathNode *arg0) { + s32 i; + PathNode *sp1C; + + if (arg0->unk00_field1 != 0) { + return TRUE; + } + if (arg0->unk01 <= 1) { + return FALSE; + } + for (i = 0; i < arg0->unk01; i++) { + sp1C = SearchPathNodeSpace(arg0->unk46[i]); + if (sp1C && CheckPath(sp1C)) { + return TRUE; + } + } + return FALSE; +} + +s16 BoardComPathW20BestGet(s16 arg0, u32 arg1, s16 arg2) { + PathNode *var_r31; + PathNode *sp38; + s32 i; + + ComPathInlineFunc05(arg0, arg2); + var_r31 = SearchPathNodeSpace(arg0); + if (arg1 & 0x180000) { + if (var_r31->unk00_field1 != 0) { + return -1; + } + } else if (arg1 & 0x08000000) { + if (var_r31->unk00_field4 != 0) { + return -1; + } + } else if (arg1 & 0x10000000) { + if (var_r31->unk00_field5 != 0) { + return -1; + } + } + if (var_r31->unk01 <= 1) { + return -1; + } + for (i = 0; i < var_r31->unk01; i++) { + sp38 = SearchPathNodeSpace(var_r31->unk46[i]); + if (sp38 && CheckW20Path(sp38, arg1)) { + return var_r31->unk46[i]; + } + } + return -1; +} + +static BOOL CheckW20Path(PathNode *arg0, u32 arg1) { + s32 i; + PathNode *sp1C; + + if (arg1 & 0x180000) { + if (arg0->unk00_field1 != 0) { + return TRUE; + } + } else if (arg1 & 0x08000000) { + if (arg0->unk00_field4 != 0) { + return TRUE; + } + } else if (arg1 & 0x10000000) { + if (arg0->unk00_field5 != 0) { + return TRUE; + } + } + if (arg0->unk01 <= 1) { + return FALSE; + } + for (i = 0; i < arg0->unk01; i++) { + sp1C = SearchPathNodeSpace(arg0->unk46[i]); + if (sp1C && CheckW20Path(sp1C, arg1)) { + return TRUE; + } + } + return FALSE; +}