#include "global.h" #include "audio.h" #include "main.h" #include "player.h" #include "structures.h" #include "save.h" #include "textbox.h" #include "functions.h" #include "object.h" #include "manager.h" #include "npc.h" extern u8 gUnk_03003DE0; extern u8 gUnk_03000C30; extern u16* gUnk_02025EB0; extern u16* gUnk_0200B650; extern u8 gUnk_02000070; extern u8 gUnk_03003DF0[]; extern u8 gUnk_03003BE0; extern Entity* gUnk_03004040[3]; extern u8 gUnk_020342F8; extern u8 gUnk_03003DB8; extern void gUnk_030059F0(void); extern void sub_080ADD70(); extern void sub_0801C25C(); extern void sub_08016C3C(); extern void sub_08016DF8(); extern void sub_0804FF98(); extern u32 sub_0805E3B0(); extern void sub_08016FF4(); extern void sub_08070680(); extern void sub_080171F0(); extern void sub_08078FB0(); extern void sub_0800404C(); extern void sub_0807A050(); extern u32 sub_08079B24(); extern void sub_08079708(); extern void CreateSparkle(); extern void sub_080028E0(Entity*); extern void sub_08078180(void); extern void sub_0807B0C8(void); extern void sub_0807A8D8(Entity*); extern void sub_08077FEC(u32); extern void sub_080173A4(Entity*); extern void sub_080A2838(Entity*); extern u32 ReadBit(void*, u32); extern void sub_0806EC78(Entity*); typedef struct { u8 unk0; u8 unk1; u8 unk2; u8 unk3; u8 unk4; u8 unk5; u16 unk6; } ItemFrame; extern ItemFrame gUnk_08126DA8[]; extern ItemFrame* gUnk_08126ED8[3]; typedef struct { u16 unk0; u16 unk1; u16 x; u16 y; } NPCStruct; extern NPCStruct gUnk_02031EC0[100]; typedef struct { u8 unk0; u8 unk1; u8 unk2; u8 unk3; u8 freezeTime; u8 unk9; } EntityHandler; extern EntityHandler gUnk_03003DC0; typedef struct { void* last; void* first; void* node; u8 flags; } LinkedList2; extern LinkedList2 gUnk_03003C70[16]; extern LinkedList2* gUnk_02018EA0; void sub_08016DF8(void) { if (gUnk_03003DE0 != 0) { u8* buf = &gUnk_03000C30; s32 i = gUnk_03003DE0; gUnk_03003DE0 = 0; do { switch (*buf) { case 0: DmaCopy32(3, *(u32*)(buf + 4), *(u32*)(buf + 8), *(u16*)(buf + 2)); break; case 1: LZ77UnCompVram(*(void**)(buf + 4), *(u8**)(buf + 8)); break; case 2: DmaFill32(3, *(u32*)(buf + 4), *(u32*)(buf + 8), *(u16*)(buf + 2)); break; } buf += 12; i--; } while (0 < i); } } void sub_08016E78(void) { gUnk_03001000.interruptFlag = 0; VBlankIntrWait(); do { } while (gUnk_03001000.interruptFlag == 0); sub_080ADD70(); sub_0801C25C(); sub_08016C3C(); sub_08016DF8(); if (gUnk_02000070) { gUnk_02000070 = 0; if (gUnk_02025EB0 != NULL) { // sizeof(BGBuffer) = 0x800, what are we omitting? DmaCopy32(3, &gBG1Buffer, VRAM + (*gUnk_02025EB0 & 0x1f00) * 8, 0x5C0); } if (gUnk_0200B650 != NULL) { DmaCopy32(3, &gBG2Buffer, VRAM + (*gUnk_0200B650 & 0x1f00) * 8, 0x5C0); } } sub_0804FF98(); } void sub_08016F28(Entity* this) { if (gSave.stats.floorType != 0) gPlayerState.flags.all |= 0x4000; else gPlayerState.flags.all &= ~0x4000; if (sub_0805E3B0(this) == 0) { if ((gPlayerState.flags.all & 0x80000) != 0) { sub_08077B20(); if ((gPlayerState.flags.all & 0x200000) != 0) { gPlayerState.playerAction = 0x18; gPlayerState.flags.all &= 0xfff7ffff; gPlayerState.hurtBlinkSpeed = 0xf0; this->flags |= 0x80; } else { this->flags &= 0x7f; gPlayerState.field_0xa8 = 0xf; } } sub_08016FF4(this); sub_08070680(this); if ((this->height.WORD == 0) && (this->action == 1 || this->action == 9)) { sub_08008790(this, 8); } sub_080171F0(); } sub_08078FB0(this); sub_0800404C(this); sub_0807A050(); } void sub_08016FF4(Entity* this) { u32 temp; gUnk_0200AF00.filler25[10] = 0; gUnk_0200AF00.filler25[8] = 0; gUnk_0200AF00.filler25[9] = 0; if ((gPlayerEntity.bitfield & 0x80) && (gPlayerEntity.hurtBlinkTime > 0)) PlaySFX(SFX_86); gPlayerState.flags.all &= ~(0x2000000 | 0x200); if (gPlayerState.flags.all & 0x400) ResetPlayer(); if ((gPlayerState.flags.all & 0x400000) && !gPlayerState.field_0xa0[0]) sub_0807A108(); if (sub_08079B24() == 0) sub_08079708(this); gUnk_03003DF0[0] = 0; if (gPlayerState.field_0x27[0] != 0) gPlayerState.field_0x27[0]--; gPlayerState.field_0xa9 = gPlayerState.field_0xa8; gPlayerState.field_0xa8 = 0; if (gPlayerState.field_0x40[0x4a] != 0) { gPlayerState.field_0x40[0x4a]--; return; } if ((gPlayerState.field_0x8b != 0) || (gTextBox.doTextBox & 0x7f)) return; gRoomVars.unk2 = gTextBox.doTextBox & 0x7f; temp = gSave.stats.maxHealth / 4; if (temp > 24) temp = 24; if (temp < 8) temp = 8; if (gSave.stats.health <= temp) { gRoomVars.unk2 = 1; if ((gUnk_0200AF00.filler0[1] == 0) && gScreenTransition.frameCount % 90 == 0) { EnqueueSFX(SFX_LOW_HEALTH); } } if (gSave.stats.filler[2] == 0) { gSave.stats.field_0x1c = 0; } else if ((gSave.stats.field_0x1c == 0) || --gSave.stats.field_0x1c == 0) { gSave.stats.filler[2] = 0; PlaySFX(SFX_ICE_BLOCK_MELT); } if (gSave.stats.filler[3] == 0) { gSave.stats.field_0x1e = 0; } else if ((gSave.stats.field_0x1e == 0) || (--gSave.stats.field_0x1e == 0)) { gSave.stats.filler[3] = 0; PlaySFX(SFX_140); } else if ((gSave.stats.field_0x1e & 0xf) == 0) { CreateSparkle(this); } if (gSave.stats.floorType == 0) { gSave.stats.field_0x20 = 0; } else if ((gSave.stats.field_0x20 == 0) || --gSave.stats.field_0x20 == 0) { gSave.stats.floorType = 0; } else if ((gSave.stats.field_0x20 & 0x3f) == 0) { // lava or water splash FX CreateFx(this, 0x55 + gSave.stats.floorType, 0); } } void sub_080171F0(void) { if (gPlayerState.field_0x1a[0] != 0) ResetPlayer(); if (gPlayerState.field_0x14 != 0) gPlayerState.field_0x14--; if (gPlayerEntity.field_0x7a.HWORD != 0) gPlayerEntity.field_0x7a.HWORD--; gPlayerEntity.bitfield &= ~0x80; if (gPlayerEntity.action != 0x14) gPlayerState.flags.all = (gPlayerState.flags.all & ~0x10000) | (0x8000 * (gPlayerState.flags.all & 2)); gPlayerState.flags.all &= ~2; sub_080028E0(&gPlayerEntity); if (gPlayerState.flags.all & 0x400000) gUnk_0200AF00.filler25[10] = 1; sub_08078180(); gPlayerState.field_0x7 &= ~0x80; gPlayerState.field_0xa &= 0xf; gPlayerState.keepFacing &= ~0x80; gPlayerState.field_0x1a[0] = 0; gPlayerState.field_0x80 = 0; gPlayerState.field_0xaa = 0; _DmaZero(&gUnk_03003BE0, 0x8c); gPlayerEntity.spriteOffsetY = gPlayerState.field_0x3f; gPlayerState.field_0x3f = 0; sub_0807B0C8(); if (gPlayerState.flags.all & 0x400000) gUnk_03004040[0]->spriteOffsetY = gUnk_03004040[1]->spriteOffsetY = gUnk_03004040[2]->spriteOffsetY = 0; if (gPlayerEntity.action == 0x1d) gPlayerState.flags.all |= 0x20000000; else gPlayerState.flags.all &= ~0x20000000; sub_0807A8D8(&gPlayerEntity); if (gPlayerState.jumpStatus & 0xc0) gPlayerEntity.hurtBlinkTime = 0xfe; if (gPlayerEntity.action != 0x17) { sub_08077FEC(gPlayerEntity.action); } } void sub_08017338(Entity *this) { if (!(this->flags & 1) && !this->action && !this->previousActionFlag) sub_080173A4(this); if (!sub_0805E3B0(this)) { gPlayerItemFunctions[this->entityType.subtype](this); this->bitfield &= ~0x80; if (this->hurtBlinkTime != 0) { if (this->hurtBlinkTime > 0) this->hurtBlinkTime--; else this->hurtBlinkTime++; } } sub_0800404C(this); } // tiny regalloc NONMATCH("asm/non_matching/sub_080173A4.inc", void sub_080173A4(Entity* this)) { ItemFrame* entry; entry = &gUnk_08126DA8[this->entityType.subtype]; if (entry->unk0 == 0xff) { u32 temp = entry->unk2; ItemFrame* temp2 = gUnk_08126ED8[entry->unk1]; entry = &temp2[this->field_0x68.HALF.LO - temp]; } this->palette.raw = ((entry->unk0 & 0xf) << 4) | entry->unk0; this->field_0x44 = entry->unk1; this->field_0x40 = entry->unk3; this->damageType = entry->unk4; this->spriteIndex = entry->unk5; if (entry->unk6 == 0) this->spriteVramOffset = gPlayerEntity.spriteVramOffset; else this->spriteVramOffset = entry->unk6 & 0x3ff; if (this->animationState == 0) this->animationState = gPlayerEntity.animationState & 6; this->collisionLayer = gPlayerEntity.collisionLayer; this->spriteRendering.b3 = gPlayerEntity.spriteRendering.b3; this->spritePriority.b0 = gPlayerEntity.spritePriority.b0; this->spriteOrientation.flipY = gPlayerEntity.spriteOrientation.flipY; this->currentHealth = 1; this->flags |= 1; } END_NONMATCH void sub_080174A4(Entity* this) { int iVar1; if (((this->flags & 1) == 0) && (this->action == 0)) { sub_080A2838(this); } if (this->hurtBlinkTime != 0) { this->hurtBlinkTime++; } if (!sub_0805E3B0(this)) { gObjectFunctions[this->entityType.subtype](this); this->bitfield &= ~0x80; } sub_0800404C(this); } void sub_08017508(Entity* this) { if (!sub_0805E3B0(this)) gManagerFunctions[this->entityType.subtype](this); } // regalloc NONMATCH("asm/non_matching/sub_08017530.inc", void sub_08017530(Entity* this)) { if ((this->currentHealth & 0x7f) && !ReadBit(&gUnk_020342F8, this->currentHealth - 1)) { DeleteThisEntity(); } if ((this->action == 0) && ((this->flags & 1) == 0)) { sub_0806EC78(this); } if (!sub_0805E3B0(this)) { gNPCFunctions[this->entityType.subtype][0](this); } if (this->next != NULL) { if (gNPCFunctions[this->entityType.subtype][1] != NULL) { gNPCFunctions[this->entityType.subtype][1](this); } if ((this->currentHealth & 0x7f) != 0) { u32 temp = this->currentHealth & 0x7f; gUnk_02031EC0[temp * 2 - 2].x = this->x.HALF.HI - gRoomControls.roomOriginX; gUnk_02031EC0[temp * 2 - 2].y = this->y.HALF.HI - gRoomControls.roomOriginY; } sub_0800404C(this); } } END_NONMATCH void sub_080175E8(void) { gUnk_03003DB8 = 0; } void sub_080175F4(void) { u32 flags; u32 temp; void (*func)(void); temp = gUnk_03003DC0.unk0; if (gUnk_03003DC0.unk0 <= gUnk_03003DC0.unk1) temp = gUnk_03003DC0.unk1; if (temp != 0) return; func = &gUnk_030059F0; if (gPlayerState.field_0x8b != 0) { u32 temp = gPlayerEntity.flags; gPlayerEntity.flags &= 0x7f; func(); gPlayerEntity.flags = temp; } else { func(); } } void sub_08017640(void) { _DmaZero(&gUnk_03003C70,0x100); gUnk_02018EA0 = (LinkedList2*)&gUnk_03003C70[0].last; gUnk_03003C70[0].last = &gUnk_03003C70[0].last; gUnk_03003C70[0].first = &gUnk_03003C70[0].last; gUnk_03003C70[0].node = &gPlayerEntity; } // Loop declaration seems wrong NONMATCH("asm/non_matching/sub_0801766C.inc", u32 sub_0801766C(Entity* this)) { u32 uVar1; LinkedList2* puVar3; LinkedList2* puVar2; LinkedList2* pLVar2; LinkedList2* i; u8* pbVar4; if (this->spritePriority.b2 != 0) { return 1; } else { for (i = &gUnk_03003C70[0]; i < &gUnk_03003C70[16]; ++i) { if (i->node == NULL) { i->node = this; i->flags = 0; this->spritePriority.b2 = 1; pLVar2 = gUnk_02018EA0; if (gUnk_02018EA0->flags != 0) { do { pLVar2 = pLVar2->first; } while (pLVar2->flags != 0); i->first = pLVar2; puVar3 = pLVar2->last; i->last = puVar3; puVar3->first = i; pLVar2->last = i; } else { i->first = gUnk_02018EA0; puVar2 = gUnk_02018EA0->last; i->last = puVar2; puVar2->first = i; gUnk_02018EA0->last = i; gUnk_02018EA0 = i; } return 1; } } return 0; } } END_NONMATCH // same loop issue NONMATCH("asm/non_matching/sub_080176E4.inc", u32 sub_080176E4(Entity* this)) { u32 uVar1; LinkedList2* j; LinkedList2* i; u8* pbVar4; if (this->spritePriority.b2 != 0) { return 1; } else { for (i = &gUnk_03003C70[0]; i < &gUnk_03003C70[16]; ++i) { if (i->node == NULL) { i->node = this; i->flags = 1; this->spritePriority.b2 = 1; i->first = gUnk_02018EA0; j = gUnk_02018EA0->last; i->last = j; j->first = i; gUnk_02018EA0->last = i; gUnk_02018EA0 = i; return 1; } } return 0; } } END_NONMATCH // you guessed it NONMATCH("asm/non_matching/sub_08016DF8.inc", void sub_08017744(Entity* this)) { LinkedList2* i; for (i = &gUnk_03003C70[0]; i < &gUnk_03003C70[16]; ++i) { if (i->node == this) { if (this->spritePriority.b2 != 0) { this->spritePriority.b2 = 0; i->node = NULL; ((LinkedList2*)i->last)->first = i->first; ((LinkedList2*)i->first)->last = i->last; if (i != gUnk_02018EA0) return; gUnk_02018EA0 = i->first; } } } } END_NONMATCH // regalloc NONMATCH("asm/non_matching/sub_080177A0.inc", bool32 sub_080177A0(Entity* this, Entity* that)) { u32 this_d; u32 depth; if ((that->collisionLayer & this->collisionLayer) != 0) { BoundingBox* bb_this = this->boundingBox; BoundingBox* bb_that = that->boundingBox; u32 this_w = bb_this->width; u32 that_w = bb_that->width; if ((((this->x.HALF.HI - that->x.HALF.HI) + bb_this->offset_x) - bb_that->offset_x) + this_w + that_w <= (this_w + that_w) * 2) { u32 this_h = bb_this->height; u32 that_h = bb_that->height; if ((((this->y.HALF.HI - that->y.HALF.HI) + bb_this->offset_y) - bb_that->offset_y) + this_h + that_h <= (this_h + that_h) * 2) { if ((this->field_0x3c & 0x10) != 0) this_d = ((BoundingBox3D*)bb_this)->depth; else this_d = 5; if ((that->field_0x3c & 0x10) != 0) depth = this_d + ((BoundingBox3D*)bb_that)->depth; else depth = this_d + 5; if ((this->height.HALF.HI - that->height.HALF.HI) + depth <= depth * 2) return TRUE; } } } return FALSE; } END_NONMATCH bool32 sub_08017850(Entity* this) { if (sub_08079F8C()) return sub_080177A0(this, &gPlayerEntity); return FALSE; }