From 4c99495ccb099a1b54e606d2005f1e15b73d22b1 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Fri, 12 May 2023 21:36:37 +1000 Subject: [PATCH] Optimise chr bdlist handling --- src/game/chraction.c | 40 ++++++++++++++++++++++-------------- src/game/chraicommands.c | 10 ++++----- src/include/constants.h | 7 +++++++ src/include/game/chraction.h | 2 +- src/include/types.h | 2 +- tools/ai2asm/ai2asm.py | 10 +++++---- 6 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/game/chraction.c b/src/game/chraction.c index 66789f746..52ef48060 100644 --- a/src/game/chraction.c +++ b/src/game/chraction.c @@ -14065,31 +14065,41 @@ void chrAddTargetToBdlist(struct chrdata *chr) if (target) { for (i = 0; i < g_Vars.lvupdate60; i++) { - chr->bdlist[chr->bdstart] = target->pos.x - chr->prop->pos.x; - chr->bdstart++; - chr->bdstart %= 60; + chr->bdlist[chr->bdstart + 0] = target->pos.x - chr->prop->pos.x; + chr->bdlist[chr->bdstart + 1] = target->pos.z - chr->prop->pos.z; - chr->bdlist[chr->bdstart] = target->pos.z - chr->prop->pos.z; - chr->bdstart++; - chr->bdstart %= 60; + chr->bdstart += 2; + + if (chr->bdstart >= 60) { + chr->bdstart = 0; + } } } } } -s32 chrGetDistanceLostToTargetInLastSecond(struct chrdata *chr) +f32 chrGetDistanceLostToTargetInLastSecond(struct chrdata *chr) { - s32 *bdlist = &chr->bdlist[0]; + f32 *bdlist = &chr->bdlist[0]; s32 index = chr->bdstart; - u32 stack[2]; + f32 olddist; + f32 curdist; + f32 x; + f32 z; - s32 x1 = bdlist[(index + 1) % 60]; - s32 z1 = bdlist[index]; - s32 olddist = sqrtf(x1 * x1 + z1 * z1); + x = bdlist[index + 1]; + z = bdlist[index + 0]; + olddist = sqrtf(x * x + z * z); - s32 x2 = bdlist[(index + 59) % 60]; - s32 z2 = bdlist[(index + 58) % 60]; - s32 curdist = sqrtf(x2 * x2 + z2 * z2); + index += 2; + + if (index >= 60) { + index = 0; + } + + x = bdlist[index + 1]; + z = bdlist[index + 0]; + curdist = sqrtf(x * x + z * z); return curdist - olddist; } diff --git a/src/game/chraicommands.c b/src/game/chraicommands.c index a2c9f3bff..da94ae8a5 100644 --- a/src/game/chraicommands.c +++ b/src/game/chraicommands.c @@ -2065,8 +2065,8 @@ bool aiIfTargetIsPlayer(struct chrdata *self) bool aiIfTargetMovingSlowly(struct chrdata *self) { - s32 delta = chrGetDistanceLostToTargetInLastSecond(self); - s32 absdelta = delta > 0 ? delta : -delta; + f32 delta = chrGetDistanceLostToTargetInLastSecond(self); + f32 absdelta = absf(delta); return absdelta < 50; } @@ -2722,7 +2722,7 @@ void aiSayQuip(struct chrdata *self, s32 chrref, s32 row, s32 probability, s32 s char *text; // 128 struct chrdata *chr = chrFindById(self, chrref); // 124 u32 prevplayernum = g_Vars.currentplayernum; // 120 - s32 distance; // 116 - not referenced + f32 distance; // 116 - not referenced u32 playernum; // 108 - not referenced u8 headshotted = (self->hidden2 & CHRH2FLAG_HEADSHOTTED) & 0xff; // 107 struct chrdata *loopchr; // 100 @@ -2861,7 +2861,7 @@ void aiSayQuip(struct chrdata *self, s32 chrref, s32 row, s32 probability, s32 s // Audio is "Stop moving", "Stop dodging" or "Stand still" distance = chrGetDistanceLostToTargetInLastSecond(self); - if (ABS(distance) > 50) { + if (absf(distance) > 50) { func0f0926bc(self->prop, 9, 0xffff); // 840 propsnd0f0939f8(0, self->prop, audioid, -1, @@ -2926,7 +2926,7 @@ void aiSayQuip(struct chrdata *self, s32 chrref, s32 row, s32 probability, s32 s // a90 distance = chrGetDistanceLostToTargetInLastSecond(self); - if (ABS(distance) > 50) { + if (absf(distance) > 50) { func0f0926bc(self->prop, 9, 0xffff); // b28 propsnd0f0939f8(0, self->prop, audioid, -1, diff --git a/src/include/constants.h b/src/include/constants.h index 122a6e209..62dcfb752 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -43,6 +43,13 @@ #define FRAMEBUFFER_SIZE (320 * 220 * sizeof(u16)) #define UNCACHED(x) ((void *)((u32)(x)|0xa0000000)) +static inline float absf(float value) +{ + float ret; + __asm__ ("abs.s %0, %1" : "=f"(ret) : "f"(value)); + return ret; +} + static inline float sqrtf(float value) { float ret; diff --git a/src/include/game/chraction.h b/src/include/game/chraction.h index 88507265d..1b75362af 100644 --- a/src/include/game/chraction.h +++ b/src/include/game/chraction.h @@ -180,7 +180,7 @@ struct prop *chrSpawnAtPad(struct chrdata *chr, s32 body, s32 head, s32 pad, u8 struct prop *chrSpawnAtChr(struct chrdata *basechr, s32 body, s32 head, u32 chrnum, u8 *ailist, u32 spawnflags); s16 chrGoToCover(struct chrdata *chr, u8 speed); void chrAddTargetToBdlist(struct chrdata *chr); -s32 chrGetDistanceLostToTargetInLastSecond(struct chrdata *chr); +f32 chrGetDistanceLostToTargetInLastSecond(struct chrdata *chr); bool chrIsTargetNearlyInSight(struct chrdata *chr, u32 distance); bool chrIsNearlyInTargetsSight(struct chrdata *chr, u32 distance); s16 *teamGetChrIds(s32 team_id); diff --git a/src/include/types.h b/src/include/types.h index 8f554db09..c51c8d88d 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -1251,7 +1251,7 @@ struct chrdata { #else /*0x19c*/ s32 magicanim; #endif - /*0x1a0*/ s32 bdlist[60]; + /*0x1a0*/ f32 bdlist[60]; /*0x290*/ u8 bdstart; /*0x291*/ u8 goposhitcount; /*0x292*/ s16 cover; diff --git a/tools/ai2asm/ai2asm.py b/tools/ai2asm/ai2asm.py index 2d3b075bf..edc747252 100755 --- a/tools/ai2asm/ai2asm.py +++ b/tools/ai2asm/ai2asm.py @@ -1361,15 +1361,17 @@ class App(): # follow label if return value > 50 self.emit('move', ['$a0', '$s0']) self.emit('jal', ['chrGetDistanceLostToTargetInLastSecond']) - self.emit('slti', ['$v0', '$v0', 51]) - self.emit_beqz_label(params[0]) + self.emit('li.s', ['$f2', 50]) + self.emit('c.lt.s', ['$f2', '$f0']) + self.emit('bc1t', [self.label_name(params[0])]) def ai_if_target_moving_closer(self, params): # follow label if return value < -50 self.emit('move', ['$a0', '$s0']) self.emit('jal', ['chrGetDistanceLostToTargetInLastSecond']) - self.emit('slti', ['$v0', '$v0', -50]) - self.emit_bnez_label(params[0]) + self.emit('li.s', ['$f2', -50]) + self.emit('c.lt.s', ['$f0', '$f2']) + self.emit('bc1t', [self.label_name(params[0])]) def ai_if_target_moving_slowly(self, params): self.emit('move', ['$a0', '$s0'])