diff --git a/data/file_list.yml b/data/file_list.yml index e11c970a..ce38b772 100644 --- a/data/file_list.yml +++ b/data/file_list.yml @@ -273514,7 +273514,7 @@ Library/Player/PlayerUtil.o: - offset: 0x9a4d1c size: 200 label: _ZN2al20calcAlivePlayerActorEPKNS_9LiveActorEPS2_j - status: NonMatchingMajor + status: Matching - offset: 0x9a4de4 size: 96 label: _ZN2al34tryFindNearestPlayerActorConditionEPKNS_9LiveActorEPFbS2_E diff --git a/lib/al/Library/Player/PlayerUtil.cpp b/lib/al/Library/Player/PlayerUtil.cpp index 6b906083..2ad65846 100644 --- a/lib/al/Library/Player/PlayerUtil.cpp +++ b/lib/al/Library/Player/PlayerUtil.cpp @@ -310,20 +310,42 @@ u32 calcPlayerListOrderByDistance(const LiveActor* actor, const LiveActor** acto return size; } -// NON_MATCHING: major mismatch, it's doing something weird with flags -// (https://decomp.me/scratch/c1lVL) +// TODO: flag-loop issue, this shouldn't be written like this +static s32 blackBox(s32 value) { + __asm__("" : "+r"(value)); + return value; +} + u32 calcAlivePlayerActor(const LiveActor* actor, const LiveActor** actorList, u32 size) { u32 playerNum = getPlayerNumMax(actor); + s32 flag = 2; + u32 result; u32 resultNum = 0; - for (u32 i = 0; i != playerNum; i++) { - LiveActor* player = getPlayerActor(actor, i); - if (!isDead(player)) { - actorList[resultNum] = player; - resultNum++; - if (resultNum >= size) - return size; + + if (playerNum != 0) { + for (u32 i = 0; i < playerNum; i++) { + LiveActor* player = getPlayerActor(actor, i); + if (!isDead(player)) { + actorList[resultNum] = player; + resultNum++; + if (resultNum >= size) { + result = size; + flag = 1; + } else { + flag = 0; + } + } else { + flag = 4; + } + + if ((blackBox(flag | 4) & 7) != 4) + goto end; } + flag = 2; } +end: + if (flag != 2) + resultNum = result; return resultNum; }