From 536cdc6c8906bc40501ad6692755a6dca0137139 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Mon, 8 Feb 2021 08:08:57 +1000 Subject: [PATCH] Attempt to decompile chrAssignCoverAwayFromDanger --- src/game/chr/chr.c | 2 +- src/game/chr/chraction.c | 131 ++++++++++++++++++++++++++++--- src/game/chr/chraicommands.c | 4 +- src/game/pad.c | 10 +-- src/include/constants.h | 10 +-- src/include/game/chr/chraction.h | 2 +- src/include/game/pad.h | 4 +- 7 files changed, 138 insertions(+), 25 deletions(-) diff --git a/src/game/chr/chr.c b/src/game/chr/chr.c index 8c18e7c79..c26ff35c9 100644 --- a/src/game/chr/chr.c +++ b/src/game/chr/chr.c @@ -2713,7 +2713,7 @@ void func0f020d44(struct prop *prop, bool removechr) chrDeregister(chr->chrnum); if (chr->cover != -1) { - coverSetFlag0002(chr->cover, false); + coverSetInUse(chr->cover, false); chr->cover = -1; } diff --git a/src/game/chr/chraction.c b/src/game/chr/chraction.c index 04e668d8a..a7545bd60 100644 --- a/src/game/chr/chraction.c +++ b/src/game/chr/chraction.c @@ -2066,7 +2066,7 @@ void chrBeginDead(struct chrdata *chr) chrStopFiring(chr); if (chr->cover != -1) { - coverSetFlag0002(chr->cover, false); + coverSetInUse(chr->cover, false); chr->cover = -1; } @@ -10940,7 +10940,7 @@ s32 func0f03aca0(struct chrdata *chr, f32 arg1, u8 arg2) somefloat = 2000; } - if (func0f04bffc(chr, somefloat, arg1 + 10000) == 0) { + if (chrAssignCoverAwayFromDanger(chr, somefloat, arg1 + 10000) == 0) { func0f04ba34(g_Vars.chrdata, 0x90a, 0); } @@ -25926,7 +25926,7 @@ glabel func0f04ba34 /* f04bba4: 322a2000 */ andi $t2,$s1,0x2000 /* f04bba8: 5540000b */ bnezl $t2,.L0f04bbd8 /* f04bbac: 322c0040 */ andi $t4,$s1,0x40 -/* f04bbb0: 0fc45917 */ jal coverHasFlag0002 +/* f04bbb0: 0fc45917 */ jal coverIsInUse /* f04bbb4: 02002025 */ or $a0,$s0,$zero /* f04bbb8: 1440008b */ bnez $v0,.L0f04bde8 /* f04bbbc: 8fab0098 */ lw $t3,0x98($sp) @@ -26206,13 +26206,13 @@ glabel func0f04ba34 /* f04bf80: 8faa0084 */ lw $t2,0x84($sp) /* f04bf84: 11410004 */ beq $t2,$at,.L0f04bf98 /* f04bf88: 01402025 */ or $a0,$t2,$zero -/* f04bf8c: 0fc45929 */ jal coverSetFlag0002 +/* f04bf8c: 0fc45929 */ jal coverSetInUse /* f04bf90: afa70048 */ sw $a3,0x48($sp) /* f04bf94: 8fa70048 */ lw $a3,0x48($sp) .L0f04bf98: /* f04bf98: 86840292 */ lh $a0,0x292($s4) /* f04bf9c: afa70048 */ sw $a3,0x48($sp) -/* f04bfa0: 0fc45929 */ jal coverSetFlag0002 +/* f04bfa0: 0fc45929 */ jal coverSetInUse /* f04bfa4: 24050001 */ addiu $a1,$zero,0x1 /* f04bfa8: 8fa70048 */ lw $a3,0x48($sp) /* f04bfac: 8e4b0000 */ lw $t3,0x0($s2) @@ -26241,7 +26241,7 @@ glabel func0f04ba34 ); GLOBAL_ASM( -glabel func0f04bffc +glabel chrAssignCoverAwayFromDanger /* f04bffc: 27bdff58 */ addiu $sp,$sp,-168 /* f04c000: afbf005c */ sw $ra,0x5c($sp) /* f04c004: afbe0058 */ sw $s8,0x58($sp) @@ -26304,7 +26304,7 @@ glabel func0f04bffc /* f04c0e4: 02402825 */ or $a1,$s2,$zero /* f04c0e8: 5040003e */ beqzl $v0,.L0f04c1e4 /* f04c0ec: 26100001 */ addiu $s0,$s0,0x1 -/* f04c0f0: 0fc45917 */ jal coverHasFlag0002 +/* f04c0f0: 0fc45917 */ jal coverIsInUse /* f04c0f4: 02002025 */ or $a0,$s0,$zero /* f04c0f8: 14400039 */ bnez $v0,.L0f04c1e0 /* f04c0fc: 8fa90064 */ lw $t1,0x64($sp) @@ -26379,11 +26379,11 @@ glabel func0f04bffc /* f04c204: 8fbf005c */ lw $ra,0x5c($sp) /* f04c208: 50820004 */ beql $a0,$v0,.L0f04c21c /* f04c20c: 86240292 */ lh $a0,0x292($s1) -/* f04c210: 0fc45929 */ jal coverSetFlag0002 +/* f04c210: 0fc45929 */ jal coverSetInUse /* f04c214: 00002825 */ or $a1,$zero,$zero /* f04c218: 86240292 */ lh $a0,0x292($s1) .L0f04c21c: -/* f04c21c: 0fc45929 */ jal coverSetFlag0002 +/* f04c21c: 0fc45929 */ jal coverSetInUse /* f04c220: 24050001 */ addiu $a1,$zero,0x1 /* f04c224: 8fbf005c */ lw $ra,0x5c($sp) .L0f04c228: @@ -26405,6 +26405,119 @@ glabel func0f04bffc /* f04c264: 27bd00a8 */ addiu $sp,$sp,0xa8 ); +/** + * Find cover in the opposite direction (?) of the chr's runfrompos and assign + * it to the chr. The distance from the runfrompos to the cover must be between + * mindist and maxdist along the X/Z plane. The chr will not choose cover more + * than 170cm higher than their current elevation, but strangely there is no + * lower Y limit. + * + * Testing with this function logic results in the following, where: + * R = run from pos + * C = chr's pos + * A = available cover + * . = unavailable cover + * + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A R A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . . + * A A A A A A A A A A A A A A . . . . . A + * A A A A A A A A A A A A A A . . . A A A + * A A A A A A A A A A A A A A . A A A A A + * A A A A A A A A A A A A A C A A A A A A + * . . . . . . . . . . . A A A A A A A A A + * . . . . . . . . . A A A A A A A A A A A + * + * The block of available cover around the runfrompos might be a bug, but if + * this function is called with mindist = chr - runfrompos or higher then it + * will work as expected. + * + * Preference is given to cover which is the "most opposite", meaning ones + * which are directly behind the chr from the perspective of runfrompos. + */ +// Mismatch: Regalloc in callee-save registers +//s32 chrAssignCoverAwayFromDanger(struct chrdata *chr, s32 mindist, s32 maxdist) +//{ +// s32 i; +// f32 vecfromdanger[2]; +// f32 vectocover[2]; +// f32 y; +// f32 ymax; +// f32 bestsqdist; +// f32 sqdist; +// s32 numcovers; +// s32 prevcover; +// s32 newcover; +// f32 coversqdistfrompos; +// struct cover cover; +// +// ymax = chr->prop->pos.y + 170; +// y = 0; +// bestsqdist = 0; +// newcover = -1; +// numcovers = coverGetCount(); +// prevcover = chr->cover; +// +// mindist = mindist * mindist; +// maxdist = maxdist * maxdist; +// +// if (mindist); +// if (maxdist); +// +// vecfromdanger[0] = chr->prop->pos.x - chr->runfrompos.x; +// vecfromdanger[1] = chr->prop->pos.z - chr->runfrompos.z; +// +// guNormalize(&vecfromdanger[0], &y, &vecfromdanger[1]); +// +// for (i = 0; i < numcovers; i++) { +// if (coverLoad(i, &cover) +// && !coverIsInUse(i) +// && !(cover.pos->y > ymax) +// && !coverHasSomeFlags(&cover)) { +// coversqdistfrompos = coordGetSquaredDistanceToCoord(&chr->runfrompos, cover.pos); +// +// if (!(coversqdistfrompos < mindist) && !(coversqdistfrompos > maxdist)) { +// vectocover[0] = cover.pos->x - chr->prop->pos.x; +// vectocover[1] = cover.pos->z - chr->prop->pos.z; +// +// guNormalize(&vectocover[0], &y, &vectocover[1]); +// +// sqdist = vecfromdanger[0] * vectocover[0] + vecfromdanger[1] * vectocover[1]; +// +// if (!(sqdist < 0) && sqdist > bestsqdist) { +// bestsqdist = sqdist; +// newcover = i; +// } +// } +// } +// +// if (numcovers); +// } +// +// chr->cover = newcover; +// +// if (newcover != -1) { +// if (prevcover != -1) { +// coverSetInUse(prevcover, false); +// } +// +// coverSetInUse(chr->cover, true); +// } +// +// return newcover; +//} + s16 chrGoToCover(struct chrdata *chr, u8 speed) { struct cover cover; diff --git a/src/game/chr/chraicommands.c b/src/game/chr/chraicommands.c index 46651efa4..ef1013f55 100644 --- a/src/game/chr/chraicommands.c +++ b/src/game/chr/chraicommands.c @@ -6931,7 +6931,7 @@ bool aiIfTargetMovingAway(void) bool ai012f(void) { if (g_Vars.chrdata->cover >= 0) { - coverSetFlag0002(g_Vars.chrdata->cover, 0); + coverSetInUse(g_Vars.chrdata->cover, 0); } g_Vars.aioffset += 2; @@ -8537,7 +8537,7 @@ bool aiIfDangerousObjectNearby(void) */ bool ai013e(void) { - if (func0f03aca0(g_Vars.chrdata, 400, true) == 0 && func0f04bffc(g_Vars.chrdata, 1000, 12000) != -1) { + if (func0f03aca0(g_Vars.chrdata, 400, true) == 0 && chrAssignCoverAwayFromDanger(g_Vars.chrdata, 1000, 12000) != -1) { chrGoToCover(g_Vars.chrdata, SPEED_RUN); } diff --git a/src/game/pad.c b/src/game/pad.c index 6f9eed9cd..dfaddfa74 100644 --- a/src/game/pad.c +++ b/src/game/pad.c @@ -719,23 +719,23 @@ s32 func0f116450(s32 arg0, s32 arg1) return arg0; } -bool coverHasFlag0002(s32 covernum) +bool coverIsInUse(s32 covernum) { // @bug: Second condition should be >= if (covernum < 0 || covernum > g_PadsFile[1]) { return false; } - return g_CoverFlags[covernum] & COVERFLAG_0002; + return g_CoverFlags[covernum] & COVERFLAG_INUSE; } -void coverSetFlag0002(s32 covernum, bool enable) +void coverSetInUse(s32 covernum, bool enable) { if (covernum >= 0 && covernum < g_PadsFile[1]) { if (enable) { - g_CoverFlags[covernum] |= COVERFLAG_0002; + g_CoverFlags[covernum] |= COVERFLAG_INUSE; } else { - g_CoverFlags[covernum] &= ~COVERFLAG_0002; + g_CoverFlags[covernum] &= ~COVERFLAG_INUSE; } } } diff --git a/src/include/constants.h b/src/include/constants.h index 9c91d63c9..f741ab41d 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -573,11 +573,11 @@ #define CONTROLMODE_23 6 #define CONTROLMODE_24 7 -#define COVERFLAG_0001 0x0001 -#define COVERFLAG_0002 0x0002 // In use? -#define COVERFLAG_0020 0x0020 -#define COVERFLAG_0040 0x0040 -#define COVERFLAG_0080 0x0080 +#define COVERFLAG_0001 0x0001 +#define COVERFLAG_INUSE 0x0002 +#define COVERFLAG_0020 0x0020 +#define COVERFLAG_0040 0x0040 +#define COVERFLAG_0080 0x0080 // L/C/R = left/centered/right // big/med/sml is the font size diff --git a/src/include/game/chr/chraction.h b/src/include/game/chr/chraction.h index eb6df79b2..e7b8f63b6 100644 --- a/src/include/game/chr/chraction.h +++ b/src/include/game/chr/chraction.h @@ -199,7 +199,7 @@ bool func0f04b658(struct chrdata *chr); bool chrMoveToPos(struct chrdata *chr, struct coord *pos, s16 *room, f32 angle, bool allowonscreen); bool chrCheckCoverOutOfSight(struct chrdata *chr, s32 covernum, bool arg2); s32 func0f04ba34(struct chrdata *chr, u16 arg1, u32 arg2); -u32 func0f04bffc(struct chrdata *chr, s32 arg1, s32 arg2); +s32 chrAssignCoverAwayFromDanger(struct chrdata *chr, s32 mindist, s32 maxdist); bool chrRunFromPos(struct chrdata *chr, u32 speed, f32 distance, struct coord *frompos); f32 func0f04c784(struct chrdata *chr); bool func0f04c874(struct chrdata *chr, u32 angle360, struct coord *pos, u8 arg3, u8 arg4); diff --git a/src/include/game/pad.h b/src/include/game/pad.h index 76be1f26f..602c5f932 100644 --- a/src/include/game/pad.h +++ b/src/include/game/pad.h @@ -12,8 +12,8 @@ void padSetFlag(s32 padnum, u32 flag); void padUnsetFlag(s32 padnum, u32 flag); s32 coverGetCount(void); bool coverLoad(s32 covernum, struct cover *cover); -bool coverHasFlag0002(s32 covernum); -void coverSetFlag0002(s32 covernum, bool enable); +bool coverIsInUse(s32 covernum); +void coverSetInUse(s32 covernum, bool enable); void coverSetFlag(s32 covernum, u32 flag); void coverUnsetFlag(s32 covernum, u32 flag); void coverSetFlag0001(s32 covernum, bool enable);