Decompile TT_002 func_us_80177380 (#1885)

While this is a pretty straight forward function, `unkA4` appears to be
either a pointer to a `s16[3]` or a struct. It's more self-documenting
for it to be a struct, but there is one case where it behaves like an
array. A cast resolves the match.
This commit is contained in:
Jonathan Hohle 2024-11-10 02:40:41 -07:00 committed by GitHub
parent c1eec14a1a
commit b48d12ac5a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 184 additions and 15 deletions

View File

@ -46,7 +46,6 @@ segments:
- [0x2600, .data, faerie_animation_data]
- [0x2B2C, data]
- [0x2C24, .data, faerie_data_2C24]
- [0x2C74, data]
- [0x2D2C, .data, servant_events]
- [0x3678, .rodata, 3678]
- [0x3994, c, 3678]

View File

@ -610,6 +610,12 @@ typedef struct {
/* 0x7C */ struct Entity* unk7C;
} ET_FaerieUnk0;
typedef struct {
/* 0x0 */ s16 unk0; // a toggle that is either 0 or -1
/* 0x2 */ s16 animIndex;
/* 0x4 */ s16 params;
} FaerieUnkA4;
typedef struct {
/* 0x7C */ s16 unk7c;
/* 0x7E */ s16 unk7E;
@ -625,10 +631,11 @@ typedef struct {
/* 0x92 */ s16 unk92;
/* 0x94 */ s16 unk94;
/* 0x96 */ s16 timer;
/* 0x98 */ s16 pad98[4];
/* 0x98 */ s32 left;
/* 0x9C */ s32 top;
/* 0xA0 */ s16 unkCounterA0;
/* 0xA2 */ s16 : 16;
/* 0xA4 */ s16* unkA4;
/* 0xA4 */ FaerieUnkA4* unkA4;
/* 0xA8 */ s16 unkA8;
/* 0xAA */ s16 padAA[5];
/* 0xB4 */ s16 unkB4;

View File

@ -48,8 +48,8 @@ extern Unkstruct_801724CC D_us_801724CC[];
extern s32 D_us_80172BD4;
extern s32 D_us_80172BDC;
extern u16 D_us_80172D28;
extern u16 D_us_80172D2A;
extern u16 g_FaerieFrameCount1;
extern u16 g_FaerieFrameCount2;
extern u32 D_us_801792D0;
extern s32 D_us_801792EC;
@ -1346,7 +1346,7 @@ void func_us_80176504(Entity* arg0) {
}
}
}
arg0->ext.faerie.unkA8 = arg0->ext.faerie.unkA4[0];
arg0->ext.faerie.unkA8 = ((s16*)arg0->ext.faerie.unkA4)[0];
g_PauseAllowed = false;
arg0->step++;
@ -1359,7 +1359,7 @@ void func_us_80176504(Entity* arg0) {
}
if (arg0->ext.faerie.unkA8 < 0) {
if (g_PlaySfxStep > 4) {
SetAnimationFrame(arg0, arg0->ext.faerie.unkA4[1]);
SetAnimationFrame(arg0, arg0->ext.faerie.unkA4->animIndex);
arg0->step++;
}
} else {
@ -1367,14 +1367,14 @@ void func_us_80176504(Entity* arg0) {
arg0->ext.faerie.unkA8--;
}
if (arg0->ext.faerie.unkA8 < 0) {
SetAnimationFrame(arg0, arg0->ext.faerie.unkA4[1]);
if ((s32*)arg0->ext.faerie.unkA4[2] &&
SetAnimationFrame(arg0, arg0->ext.faerie.unkA4->animIndex);
if (arg0->ext.faerie.unkA4->params &&
(SearchForEntityInRange(0, 0xDE) == NULL)) {
CreateEventEntity_Dupe(
arg0, 0xDE, (s32)arg0->ext.faerie.unkA4[2]);
arg0, 0xDE, arg0->ext.faerie.unkA4->params);
}
arg0->ext.faerie.unkA4 += 3;
arg0->ext.faerie.unkA8 = arg0->ext.faerie.unkA4[0];
arg0->ext.faerie.unkA4++;
arg0->ext.faerie.unkA8 = arg0->ext.faerie.unkA4->unk0;
}
}
break;
@ -1536,9 +1536,9 @@ void func_us_80176C98(Entity* self) {
} else {
self->ext.faerie.unkB4 = 0;
if (PLAYER.step_s == 4) {
self->ext.faerie.frameCounter = D_us_80172D2A;
self->ext.faerie.frameCounter = g_FaerieFrameCount2;
} else {
self->ext.faerie.frameCounter = D_us_80172D28;
self->ext.faerie.frameCounter = g_FaerieFrameCount1;
}
self->step++;
}
@ -1641,7 +1641,139 @@ void func_us_80176C98(Entity* self) {
D_us_801792D0 = ServantUpdateAnim(self, NULL, g_FaerieAnimationFrames);
}
INCLUDE_ASM("servant/tt_002/nonmatchings/3678", func_us_80177380);
extern s32 D_us_801792D4;
extern s32 D_us_801792D8;
extern Unk2CB0 D_us_80172CB0[];
void func_us_80177380(Entity* self) {
char pad[2];
self->ext.faerie.left = (g_Tilemap.left << 8) + g_Tilemap.scrollX.i.hi;
self->ext.faerie.top = (g_Tilemap.top << 8) + g_Tilemap.scrollY.i.hi;
if (D_us_80179320) {
self->zPriority = PLAYER.zPriority - 2;
s_zPriority = self->zPriority;
}
if ((D_us_80172CB0[self->params].left == -1) || (self->step == 0)) {
s_TargetLocOffset_calc = -24;
if (!PLAYER.facingLeft) {
s_TargetLocOffset_calc = -s_TargetLocOffset_calc;
}
s_TargetLocationX_calc = PLAYER.posX.i.hi + s_TargetLocOffset_calc;
s_TargetLocationY_calc = PLAYER.posY.i.hi - 32;
} else {
s_TargetLocationX_calc = D_us_801792D4 - self->ext.faerie.left;
s_TargetLocationY_calc = D_us_801792D8 - self->ext.faerie.top;
}
s_AngleToTarget = self->ext.faerie.randomMovementAngle;
self->ext.faerie.randomMovementAngle =
(self->ext.faerie.randomMovementAngle + 0x10) & 0xFFF;
s_DistToTargetLocation = self->ext.faerie.unk88;
s_TargetLocationX =
((rcos(s_AngleToTarget / 2) * s_DistToTargetLocation) >> 12) +
s_TargetLocationX_calc;
s_TargetLocationY =
s_TargetLocationY_calc -
((rsin(s_AngleToTarget) * (s_DistToTargetLocation / 2)) >> 12);
s_AngleToTarget =
CalculateAngleToEntity(self, s_TargetLocationX, s_TargetLocationY);
s_AllowedAngle = GetTargetPositionWithDistanceBuffer(
s_AngleToTarget, self->ext.faerie.targetAngle,
self->ext.faerie.maxAngle);
self->ext.faerie.targetAngle = s_AllowedAngle;
s_DistToTargetLocation =
CalculateDistance(self, s_TargetLocationX, s_TargetLocationY);
if (s_DistToTargetLocation < 60) {
self->velocityY = -(rsin(s_AllowedAngle) * 8);
self->velocityX = rcos(s_AllowedAngle) * 8;
self->ext.faerie.maxAngle = 64;
} else if (s_DistToTargetLocation < 100) {
self->velocityY = -(rsin(s_AllowedAngle) * 16);
self->velocityX = rcos(s_AllowedAngle) * 16;
self->ext.faerie.maxAngle = 96;
} else {
self->velocityY = -(rsin(s_AllowedAngle) * 32);
self->velocityX = rcos(s_AllowedAngle) * 32;
self->ext.faerie.maxAngle = 128;
}
self->posX.val += self->velocityX;
self->posY.val += self->velocityY;
switch (self->step) {
case 0:
func_us_801739D0(self);
D_us_801792D4 =
D_us_80172CB0[self->params].left + self->ext.faerie.left;
D_us_801792D8 = D_us_80172CB0[self->params].top + self->ext.faerie.top;
self->ext.faerie.timer = -1;
break;
case 1:
func_us_80173BD0(self);
s_DistToTargetLocation =
CalculateDistance(self, s_TargetLocationX, s_TargetLocationY);
if (s_DistToTargetLocation < 32) {
self->facingLeft = PLAYER.facingLeft;
self->step++;
}
break;
case 2:
self->ext.faerie.unkA4 = D_us_80172CB0[self->params].unk8;
self->ext.faerie.unkA8 = *((s16*)self->ext.faerie.unkA4);
g_PauseAllowed = 0;
self->step++;
break;
case 3:
if (PLAYER.posX.i.hi >= self->posX.i.hi) {
self->facingLeft = true;
} else {
self->facingLeft = false;
}
if (self->ext.faerie.unkA8 < 0) {
if (g_PlaySfxStep > 4) {
SetAnimationFrame(self, self->ext.faerie.unkA4->animIndex);
self->step++;
}
} else {
if ((g_PlaySfxStep == 4) || (g_PlaySfxStep >= 99)) {
self->ext.faerie.unkA8--;
}
if (self->ext.faerie.unkA8 < 0) {
SetAnimationFrame(self, self->ext.faerie.unkA4->animIndex);
if ((self->ext.faerie.unkA4->params != 0) &&
(SearchForEntityInRange(0, 0xDE) == NULL)) {
CreateEventEntity_Dupe(
self, 0xDE, self->ext.faerie.unkA4->params);
}
self->ext.faerie.unkA4++;
self->ext.faerie.unkA8 = self->ext.faerie.unkA4->unk0;
}
}
break;
case 4:
SetAnimationFrame(self, 14);
g_PauseAllowed = 1;
self->entityId = 0xD1;
self->step = 0;
break;
}
unused_39C8(self);
ServantUpdateAnim(self, NULL, &g_FaerieAnimationFrames);
}
void func_us_80177958(Entity* self) {
Entity* entity;

View File

@ -18,3 +18,9 @@ typedef struct {
s16 unk5;
s16 unk6;
} FaerieAbilityStats;
typedef struct {
s32 left;
s32 top;
FaerieUnkA4* unk8;
} Unk2CB0;

View File

@ -16,3 +16,28 @@ s16 D_us_80172C58[] = {0x0000, 0x0026, 0x0479, 0xFFFF, 0x000E, 0x0000};
// This is a ranked lookup table. First column is selected from a rand() %
// 0x100 to select the data at the pointer in column 2
s32 D_us_80172C64[] = {0x0000007F, D_us_80172C4C, 0x000000FF, D_us_80172C58};
// position data with a flag field
// clang-format off
FaerieUnkA4 D_us_80172C74[2] = { { 0, 14, 0x0492,} , { -1, 14, 0 } };
FaerieUnkA4 D_us_80172C80[2] = { { 0, 14, 0x048E,} , { -1, 14, 0 } };
FaerieUnkA4 D_us_80172C8C[2] = { { 0, 37, 0x047A,} , { -1, 14, 0 } };
FaerieUnkA4 D_us_80172C98[2] = { { 0, 36, 0x048A,} , { -1, 14, 0 } };
FaerieUnkA4 D_us_80172CA4[2] = { { 0, 36, 0x047A,} , { -1, 14, 0 } };
Unk2CB0 D_us_80172CB0[] = {
{ .left = -1, .top = -1, .unk8 = D_us_80172C74 },
{ .left = -1, .top = -1, .unk8 = D_us_80172C80 },
{ .left = 88, .top = 184, .unk8 = D_us_80172C8C },
{ .left = 32, .top = 128, .unk8 = D_us_80172C98 },
{ .left = 56, .top = 128, .unk8 = D_us_80172CA4 },
{ .left = 128, .top = 208, .unk8 = D_us_80172C8C },
{ .left = 208, .top = 112, .unk8 = D_us_80172CA4 },
{ .left = 160, .top = 128, .unk8 = D_us_80172C98 },
{ .left = 208, .top = 120, .unk8 = D_us_80172CA4 },
{ .left = 48, .top = 128, .unk8 = D_us_80172C98 },
};
// clang-format on
s16 g_FaerieFrameCount1 = 0x1518;
s16 g_FaerieFrameCount2 = 0x0960;