summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authornotyourav <65437533+notyourav@users.noreply.github.com>2023-04-24 22:48:42 -0700
committerGitHub <noreply@github.com>2023-04-24 22:48:42 -0700
commitb83cb034e16a1d2a9b033aa17ef339480ae996ed (patch)
tree0b391c0383dba3af5430b1ae414d23e0519da98e /src
parentbc550a87931f4899dfaedf4ecf81c3cb7e4157dc (diff)
parent2d20f33494927e59dca1eeb662622be28fbb7e9d (diff)
Merge pull request #604 from Elmyr-de-Hory/sub_08068318
Diffstat (limited to 'src')
-rw-r--r--src/npc/zeldaFollower.c141
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;