diff options
| author | notyourav <65437533+notyourav@users.noreply.github.com> | 2023-04-24 22:48:42 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-04-24 22:48:42 -0700 |
| commit | b83cb034e16a1d2a9b033aa17ef339480ae996ed (patch) | |
| tree | 0b391c0383dba3af5430b1ae414d23e0519da98e /src | |
| parent | bc550a87931f4899dfaedf4ecf81c3cb7e4157dc (diff) | |
| parent | 2d20f33494927e59dca1eeb662622be28fbb7e9d (diff) | |
Merge pull request #604 from Elmyr-de-Hory/sub_08068318
Diffstat (limited to 'src')
| -rw-r--r-- | src/npc/zeldaFollower.c | 141 |
1 files changed, 125 insertions, 16 deletions
diff --git a/src/npc/zeldaFollower.c b/src/npc/zeldaFollower.c index ae67fcba..24d9c30c 100644 --- a/src/npc/zeldaFollower.c +++ b/src/npc/zeldaFollower.c @@ -3,16 +3,36 @@ #include "functions.h" #include "common.h" -typedef struct { - u16 x; - u16 y; - u16 z; - u8 framestate; - u8 animationState : 6; - u8 collisionLayer : 2; +extern s32 sub_080041E8(s32 x1, s32 y1, s32 x2, s32 y2); + +typedef union { + struct { + u16 x; + u16 y; + u16 z; + u8 framestate; + u8 animationState : 6; + u8 collisionLayer : 2; + } FIELDS; + u64 DWORD; } ZeldaFollowerItem; -typedef ZeldaFollowerItem ZeldaFollowerHeap[20]; +#define ZELDA_FOLLOWER_HEAP_LEN 20 + +#define ZELDA_FOLLOWER_HEAP ((ZeldaFollowerItem *)this->myHeap) +#define ZELDA_FOLLOWER_HEAP_END ((ZeldaFollowerItem *)this->myHeap + (ZELDA_FOLLOWER_HEAP_LEN - 1)) + +#define ZELDA_FOLLOWER_HEAP_SHIFT_RIGHT(this, heapPtr) \ + do { \ + int i; \ + heapPtr = ((ZeldaFollowerItem*)this->myHeap); \ + heapPtr += (ZELDA_FOLLOWER_HEAP_LEN - 2); \ + for ( i = 0; i < (ZELDA_FOLLOWER_HEAP_LEN - 1); i++) { \ + heapPtr[1] = heapPtr[0]; \ + heapPtr--; \ + } \ + } while (0) + void sub_08068318(Entity*); void sub_0806854C(Entity*, u32*); @@ -36,10 +56,99 @@ void ZeldaFollower(Entity* this) { } } -ASM_FUNC("asm/non_matching/zeldaFollower/sub_08068318.inc", void sub_08068318(Entity* this)) +void sub_08068318(Entity* this) { + s32 dist; + s16 z; + + u32 animIndex; + u32 animIndexTmp; + + ZeldaFollowerItem* heapPtr; + ZeldaFollowerItem item; + + item.FIELDS.x = gPlayerEntity.x.HALF_U.HI; + item.FIELDS.y = gPlayerEntity.y.HALF_U.HI; + item.FIELDS.z = gPlayerEntity.z.HALF_U.HI; + item.FIELDS.framestate = gPlayerState.framestate; + item.FIELDS.animationState = gPlayerEntity.animationState; + item.FIELDS.collisionLayer = gPlayerEntity.collisionLayer; + + heapPtr = this->myHeap; + + if ( (heapPtr->FIELDS.framestate == 0xa && item.FIELDS.framestate != 0xa) || + (heapPtr->FIELDS.framestate == 0x16 && item.FIELDS.framestate != 0x16)) { + this->x.HALF.HI = gPlayerEntity.x.HALF.HI; + this->y.HALF.HI = gPlayerEntity.y.HALF.HI; + this->spriteSettings.draw = 1; + sub_08068578(this); + } + + animIndex = 0; + if (item.DWORD != heapPtr->DWORD || item.FIELDS.framestate == 0x16 || item.FIELDS.framestate == 0xa ) { + ZELDA_FOLLOWER_HEAP_SHIFT_RIGHT(this, heapPtr); + heapPtr = ZELDA_FOLLOWER_HEAP; + heapPtr[0] = item; + animIndex = 0x4; + + if ((s8)this->field_0x68.HALF.HI > 0) { + this->field_0x68.HALF.HI = this->field_0x68.HALF.HI - 1; + } + } else { + heapPtr += ZELDA_FOLLOWER_HEAP_LEN - 1; + z = heapPtr->FIELDS.z; + + if (z < 0) { + ZELDA_FOLLOWER_HEAP_SHIFT_RIGHT(this, heapPtr); + animIndex = 0x4; + } else { + dist = sub_080041E8( + gPlayerEntity.x.HALF.HI, + gPlayerEntity.y.HALF.HI, + (u16) heapPtr->FIELDS.x, + (u16) heapPtr->FIELDS.y + ); + dist = ((u32)dist) >> 0x4; + if (dist > 0x18) { + ZELDA_FOLLOWER_HEAP_SHIFT_RIGHT(this, heapPtr); + animIndex = 0x4; + } + } + } + + heapPtr = ZELDA_FOLLOWER_HEAP; + heapPtr += ZELDA_FOLLOWER_HEAP_LEN - 1; + this->x.HALF.HI = heapPtr->FIELDS.x; + this->y.HALF.HI = heapPtr->FIELDS.y; + this->z.HALF.HI = heapPtr->FIELDS.z; + this->animationState = heapPtr->FIELDS.animationState; + this->collisionLayer = heapPtr->FIELDS.collisionLayer; + + if (heapPtr->FIELDS.framestate == 0x16 || heapPtr->FIELDS.framestate == 0xa) { + this->spriteSettings.draw = 0; + } + + if (((s8)this->field_0x68.HALF.HI) > 0) { + this->field_0x68.HALF.HI = this->field_0x68.HALF.HI - 1; + } + + animIndexTmp = animIndex; + animIndex += this->animationState >> 1; + + if (!(animIndex == this->animIndex || (animIndexTmp == 0 && ((s8)this->field_0x68.HALF.HI) > 0))) { + InitAnimationForceUpdate(this, animIndex); + this->field_0x68.HALF.HI = 0x1e; + } else { + UpdateAnimationSingleFrame(this); + } + + sub_0800451C(this); + if (this->z.HALF.HI < 0) { + sub_0806F854(this, 0x0, -0xc); + } +} void sub_0806854C(Entity* this, u32* none) { - this->myHeap = zMalloc(sizeof(ZeldaFollowerHeap)); + this->myHeap = zMalloc(sizeof(ZeldaFollowerItem[ZELDA_FOLLOWER_HEAP_LEN])); if (this->myHeap != NULL) { this->field_0x68.HALF.LO = 1; sub_080788E0(this); @@ -157,12 +266,12 @@ void sub_08068578(Entity* this) { // Down here the u32 are suddendly accessed correctly as u16 and bitfields? // How are the results of above u32 calculations used? for (index = 0x13; index >= 0; index--) { - item->x = r5 - (x >> 8); - item->y = (r5 >> 0x10) - (y >> 8); - item->z = r6; - item->framestate = r6 >> 0x10; - item->animationState = this->animationState & 0x3f; - item->collisionLayer = this->collisionLayer; + item->FIELDS.x = r5 - (x >> 8); + item->FIELDS.y = (r5 >> 0x10) - (y >> 8); + item->FIELDS.z = r6; + item->FIELDS.framestate = r6 >> 0x10; + item->FIELDS.animationState = this->animationState & 0x3f; + item->FIELDS.collisionLayer = this->collisionLayer; item++; y = y + r8; x = x + r10; |
