diff options
| author | notyourav <65437533+notyourav@users.noreply.github.com> | 2022-11-06 10:45:10 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-06 10:45:10 -0800 |
| commit | 1ceeac3c8498a84db73f9441d8aae4d3f84d4885 (patch) | |
| tree | 25af23b18664b7e815dbf0c8aa08a60acfc03361 /src | |
| parent | 5209d6af3ae4697c36c1d2ab557b80dcb00b7653 (diff) | |
| parent | 6531b8828535d6cb347a6d008feb7b1fcfdd4f9a (diff) | |
Merge pull request #583 from nonmatch/patch-61
Diffstat (limited to 'src')
| -rw-r--r-- | src/beanstalkSubtask.c | 449 | ||||
| -rw-r--r-- | src/common.c | 64 | ||||
| -rw-r--r-- | src/enemy/armos.c | 38 | ||||
| -rw-r--r-- | src/enemy/gleerok.c | 30 | ||||
| -rw-r--r-- | src/enemy/octorokBoss.c | 48 | ||||
| -rw-r--r-- | src/enemy/stalfos.c | 23 | ||||
| -rw-r--r-- | src/npc/npc23.c | 7 | ||||
| -rw-r--r-- | src/object/frozenOctorok.c | 85 | ||||
| -rw-r--r-- | src/object/octorokBossObject.c | 8 | ||||
| -rw-r--r-- | src/objectUtils.c | 43 | ||||
| -rw-r--r-- | src/scroll.c | 11 | ||||
| -rw-r--r-- | src/ui.c | 22 |
12 files changed, 750 insertions, 78 deletions
diff --git a/src/beanstalkSubtask.c b/src/beanstalkSubtask.c index ceb5a7c3..d09ea3cd 100644 --- a/src/beanstalkSubtask.c +++ b/src/beanstalkSubtask.c @@ -57,6 +57,25 @@ void sub_0801AB08(u16*, LayerStruct*); u32 sub_0801AC68(u32 position, u32 data); +extern u32 sub_0807BDB8(Entity* this, u32 param_2); +extern void sub_0804B388(u32 a1, u32 a2); +extern u32 sub_080A7CFC(u32 a1, u32 tmp); // TODO does this really have a second param? +extern void OpenSmallChest(u32 pos, u32 layer); +extern bool32 sub_08079778(); +extern Transition* sub_08080734(u32, u32); + +extern const s16 gUnk_080B4490[]; +extern const s16 gUnk_080B4468[]; +extern const s16 gUnk_080B4478[]; + +bool32 sub_0801A2B0(LayerStruct* layer, u32 position, u32 collisionType); +bool32 sub_0801A9F0(u32 param_1, u32 param_2, u32 param_3); +u32 sub_0801A570(Entity*, u32); +bool32 sub_0801A458(LayerStruct* layer, u32 position, u32 collisionType); +bool32 sub_0801A370(LayerStruct* layer, u32 position); +u32 sub_0801A8D0(Entity* this, u32 param_2); +extern void sub_080001D0(u32, u32, u32); + void sub_0801967C(void) { gUnk_080B4458[gMenu.overlayType](); } @@ -140,7 +159,433 @@ void sub_080197D4(struct_08109194* param_1) { } // Has ifdefs for other variants -ASM_FUNC("asm/non_matching/beanstalkSubtask/UpdatePlayerCollision.inc", void UpdatePlayerCollision()) +u32 UpdatePlayerCollision(void) { + u32 direction; + u32 tileType; + LayerStruct* layer; + Transition* transition; + Entity* pushedBlock; + Entity* player; + u32 position; + u32 index; + const s16* ptr1; + const s16* ptr2; + s32 tmp1; + u32 tmp2; + u32 tmp3; + // There are some weird assignment necessary to access gPlayerEntity.animationState correctly. + u32 animationState1; + u32 animationState2; + u32 animationState3; + + if (gPlayerState.framestate == 0) { + tmp1 = gPlayerState.framestate_last; + } else { + tmp1 = gPlayerState.framestate; + } + + switch (tmp1) { + case 3: + return 0; + case 0x12: + return 0; + case 0x16: + return 0; + } + + if (gPlayerState.dash_state != 0 || gPlayerEntity.action == PLAYER_CLIMB) { + direction = gPlayerEntity.direction; + } else { + direction = gPlayerState.direction; + } + if (((direction & 0x83) == 0) && (gPlayerState.field_0xa == 0)) { + index = sub_0807BDB8(&gPlayerEntity, direction >> 2); + if (index != 0xff && (gRoomControls.scroll_flags & 4) == 0) { + ptr1 = &gUnk_080B4490[index * 2]; + if (sub_080B1B44(COORD_TO_TILE_OFFSET(&gPlayerEntity, -ptr1[0], -ptr1[1]), gPlayerEntity.collisionLayer) == + 0xff) { + if ((((gPlayerState.flags & 0x10002) != 0) || ((gPlayerState.sword_state & 0x10) != 0)) || + ((sub_080806BC(gPlayerEntity.x.HALF.HI - gRoomControls.origin_x, + gPlayerEntity.y.HALF.HI - gRoomControls.origin_y, index, 5) == 0 && + (((gPlayerState.heldObject != 0 || ((gPlayerState.field_0x1c & 0xf) != 0)) || + (sub_0807BD14(&gPlayerEntity, index) == 0)))))) { + return 3; + } + gPlayerEntity.direction = (index << 3); + return 0xf; + } + } + } + layer = GetLayerByIndex(gPlayerEntity.collisionLayer); + ptr1 = &gUnk_080B4468[gPlayerEntity.animationState & 6]; + position = COORD_TO_TILE_OFFSET(&gPlayerEntity, -ptr1[0], -ptr1[1]); + tileType = GetTileType(position, gPlayerEntity.collisionLayer); + if (tileType < 0x4000) { + direction = sub_080B1B54(tileType); + } else { + direction = tileType; + } + animationState1 = gPlayerEntity.animationState; + animationState2 = animationState1 & 0xff; + + switch (direction) { + case 0x4000: + if (sub_0801A458(layer, position, 2) == 0) { + return 0; + } + layer->mapData[position] = 0x4001 + (gPlayerEntity.animationState >> 1); + if ((gPlayerState.flags & 0x80) != 0) { + gPlayerState.pushedObject = 0xc0; + } else { + gPlayerState.pushedObject = 0xa0; + } + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x28: + if ((gPlayerState.flags & 0x80) != 0) { + return 0; + } + gPlayerEntity.action = gPlayerEntity.action; + if (gPlayerState.field_0xa != 0) { + return 0; + } + if ((Direction8FromAnimationState(gPlayerEntity.animationState)) - gPlayerState.direction != 0) { + return 0; + } + if ((gPlayerEntity.direction & 0x80) != 0) { + return 0; + } + if (sub_080B1B44(position, gPlayerEntity.collisionLayer) != 0xf) { + return 0; + } + if (sub_08079778() == 0) { + return 0; + } + + ptr1 = &gUnk_080B4478[gPlayerEntity.animationState & 6]; + transition = sub_08080734((gPlayerEntity.x.HALF.HI - gRoomControls.origin_x) + ptr1[0], + (gPlayerEntity.y.HALF.HI - gRoomControls.origin_y) + ptr1[1]); + if (transition == NULL) { + return 0; + } + if ((gPlayerEntity.animationState & 2) != 0) { + gPlayerEntity.y.HALF.HI = gRoomControls.origin_y + transition->startY + 6; + } else { + gPlayerEntity.x.HALF.HI = gRoomControls.origin_x + transition->startX; + } + sub_08078AC0(4, 0, 1); + return 0; + case 0x401b: + if (sub_0801A2B0(layer, position, 0xb) == 0) { + return 0; + } + layer->mapData[position] = 0x401c + (gPlayerEntity.animationState >> 1); + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + gPlayerEntity.type = 1; + return 1; + case 0x70: + if ((gPlayerState.field_0x35 & 0x80) == 0) { + if ((gPlayerEntity.frame & 1) != 0) { + if (sub_0801A9F0(gPlayerState.field_0x35 << 2, tileType, position) != 0) { + return 1; + } + } + } + return 0; + case 0x3a: + case 0x5b: + case 0x4051: + if ((gPlayerState.flags & 0x80) != 0) { + return 0; + } + if (gPlayerEntity.animationState != 0) { + return 0; + } + gUnk_0200AF00.unk_2d = 4; + if ((gPlayerState.playerInput.newInput & (PLAYER_INPUT_80 | PLAYER_INPUT_40)) == 0) { + return 0; + } + gPlayerState.mobility = 1; + sub_080A7CFC(position, gPlayerEntity.collisionLayer); + return 1; + case 0x1a: + if ((animationState1 & 0xff) != 0) { + return 0; + } + if ((gPlayerState.flags & 0x4080) != 0) { + return 0; + } + gUnk_0200AF00.unk_2d = 6; + if ((gPlayerState.playerInput.newInput & (PLAYER_INPUT_80 | PLAYER_INPUT_8)) == 0) { + return 0; + } + gPlayerState.mobility = 1; + OpenSmallChest(position, gPlayerEntity.collisionLayer); + return 2; + case 0x71: + if (HasDungeonMap() == 0) { + return 0; + } + gUnk_0200AF00.unk_2d = 6; + if ((gPlayerState.playerInput.newInput & (PLAYER_INPUT_80 | PLAYER_INPUT_8)) == 0) { + return 0; + } + gPlayerState.mobility = 1; + sub_0804B388(position, gPlayerEntity.collisionLayer); + return 2; + case 0x3d: + case 0x4040 ... 0x4048: + if ((gPlayerState.flags & 0x4000) != 0) { + return 0; + } + if (sub_08079778() == 0) { + return 0; + } +#if !(defined(EU) || defined(JP)) + if (gPlayerState.field_0xa != 0) { + return 0; + } +#endif + if ((Direction8FromAnimationState(gPlayerEntity.animationState)) - gPlayerState.direction != 0) { + return 0; + } + if ((gPlayerEntity.direction & 0x80) != 0) { + return 0; + } + if (gPlayerEntity.subtimer < 6) { + return 0; + } + gPlayerState.jump_status = 0x81; + gPlayerState.flags |= 0x20; + gPlayerState.queued_action = PLAYER_USEPORTAL; + gPlayerEntity.zVelocity = 0x20000; + COLLISION_OFF(&gPlayerEntity); + return 1; + case 0x400b: + if (sub_0801A2B0(layer, position, 8) == 0) { + return 0; + } + if ((gPlayerEntity.collisionLayer == 3) && (gMapTop.mapData[position] == 0x400b)) { + gMapTop.mapData[position] = 0x400c + (gPlayerEntity.animationState >> 1); + } else { + layer->mapData[position] = 0x400c + (gPlayerEntity.animationState >> 1); + } + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x405a: + if (sub_0801A2B0(layer, position, 2) == 0) { + return 0; + } + layer->mapData[position] = 0x405b + (gPlayerEntity.animationState >> 1); + gPlayerState.pushedObject = 0x98; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x4036: + if (sub_0801A2B0(layer, position, 0xb) == 0) { + return 0; + } + layer->mapData[position] = 0x4037 + (gPlayerEntity.animationState >> 1); + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x403e: + if ((animationState1 & 0xff) != 0) { + return 0; + } + if (((gPlayerState.field_0x35 | gPlayerState.direction) & 0x80) != 0) { + return 0; + } + if ((gPlayerEntity.frame & 2) == 0) { + return 0; + } + layer->mapData[position] = 0x403f; + gPlayerState.pushedObject = 0x82; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x72: + if ((gPlayerState.field_0x35 & 0x80) != 0) { + return 0; + } + if ((gPlayerEntity.frame & 1) == 0) { + return 0; + } + position = sub_0801A570(&gPlayerEntity, 1); + if (position == 0xffff) { + return 0; + } + tmp2 = (position >> 0xc) - 1; + position &= 0xfff; + // TODO convert to for loop? + index = 0; + tmp3 = 0; + while (index < 3) { + if ((((*(u32*)(&(gPlayerClones[0])->field_0x6c)) & (1 << index)) != 0) && + (sub_0801A570(gPlayerClones[index], 0) == position)) { + tmp3++; + } + index++; + } + if (tmp3 < tmp2) { + return 0; + } + pushedBlock = CreateObject(PUSHED_BLOCK, tmp2, 0); + if (pushedBlock == NULL) { + return 0; + } + pushedBlock->direction = Direction8FromAnimationState(gPlayerEntity.animationState); + pushedBlock->x.HALF.HI = ((position & 0xfff & 0x3f) << 4) + 8 + gRoomControls.origin_x; + pushedBlock->y.HALF.HI = ((position & 0xfc0) >> 2) + 8 + gRoomControls.origin_y; + pushedBlock->collisionLayer = gPlayerEntity.collisionLayer; + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = pushedBlock->direction; + return 1; + case 0x402b ... 0x402d: + if (sub_0801A370(layer, position) != 0) { + layer->mapData[position] = 0x4030 + ((gPlayerEntity.animationState & 4) >> 2); + if ((gPlayerState.flags & 0x80) != 0) { + gPlayerState.pushedObject = 0xa0; + } else { + gPlayerState.pushedObject = 0x90; + } + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + } else { + return 0; + } + case 0x404a: + if (sub_0801A458(layer, position, 8) == 0) { + return 0; + } + layer->mapData[position] = 0x404b + (gPlayerEntity.animationState >> 1); + if ((gPlayerState.flags & 0x80) != 0) { + gPlayerState.pushedObject = 0xc0; + } else { + gPlayerState.pushedObject = 0xa0; + } + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x4052: + if (gPlayerState.field_0x35 != 0) { + return 0; + } + SetTile(0x4054, position, gPlayerEntity.collisionLayer); + return 4; + case 0x4053: + if (gPlayerState.field_0x35 != 6) { + return 0; + } + SetTile(0x4054, position, gPlayerEntity.collisionLayer); + return 4; + case 0x4055: + position--; + // fallthrough + case 0x4056: + if (gPlayerState.field_0x35 != 0) { + return 0; + } + if ((gPlayerEntity.y.HALF.HI & 0xf) < 10) { + return 0; + } + for (index = 0; index < 3; index++) { + if (sub_0801A8D0(gPlayerClones[index], 0) == position) { + SetTile(0x4059, position, gPlayerEntity.collisionLayer); + return 4; + } + } + return 0; + case 0x4057: + position -= 0x40; + // fallthrough + case 0x4058: + if (gPlayerState.field_0x35 != 6) { + return 0; + } + if ((gPlayerEntity.x.HALF.HI & 0xf) < 10) { + return 0; + } + for (index = 0; index < 3; index++) { + if (sub_0801A8D0(gPlayerClones[index], 6) == position) { + SetTile(0x4059, position, gPlayerEntity.collisionLayer); + return 4; + } + } + return 0; + case 0x405f: + animationState3 = 2; + animationState3 &= animationState1; + if (animationState3 == 0) { + return 0; + } + if (((gPlayerState.field_0x35 | gPlayerState.direction) & 0x80) != 0) { + return 0; + } + if ((gPlayerEntity.frame & 1) == 0) { + return 0; + } + SetTile(0x4074, position, gPlayerEntity.collisionLayer); + gPlayerState.pushedObject = 0xa0; + gPlayerState.queued_action = PLAYER_PUSH; + gPlayerState.flags |= 1; + gPlayerEntity.x.HALF.LO = 0; + gPlayerEntity.y.HALF.LO = 0; + gPlayerEntity.direction = Direction8FromAnimationState(gPlayerEntity.animationState); + return 1; + case 0x407d: + animationState3 = gPlayerEntity.animationState; + if ((animationState2) != 4) { + return 0; + } + if (((gPlayerState.field_0x35 | gPlayerState.direction) & 0x80) != 0) { + return 0; + } + if ((gPlayerEntity.frame & 1) == 0) { + return 0; + } + SetTile(0x4074, position, gPlayerEntity.collisionLayer); + sub_080001D0(0xd, position, gPlayerEntity.collisionLayer); + return 1; + default: + return 0; + } +} bool32 sub_0801A2B0(LayerStruct* layer, u32 position, u32 collisionType) { u16 uVar1; @@ -287,7 +732,7 @@ bool32 sub_0801A4F8(void) { return TRUE; } -ASM_FUNC("asm/non_matching/beanstalkSubtask/sub_0801A570.inc", void sub_0801A570()) +ASM_FUNC("asm/non_matching/beanstalkSubtask/sub_0801A570.inc", u32 sub_0801A570(Entity* a, u32 b)) u32 sub_0801A8D0(Entity* this, u32 param_2) { u16* mapData; diff --git a/src/common.c b/src/common.c index 8cbddd2b..0ad58ee5 100644 --- a/src/common.c +++ b/src/common.c @@ -824,7 +824,69 @@ bool32 sub_0801E810(u32 kinstoneId) { return ReadBit(&gSave.unk24E, kinstoneId); } -ASM_FUNC("asm/non_matching/common/sub_0801E82C.inc", void sub_0801E82C(void)); +void sub_0801E82C(void) { +#ifdef NON_MATCHING + u32 r5; + + for (r5 = 0; r5 < 0x13; r5++) { + if (gSave.unk12B[r5] == 0) { + gSave.unk118[r5] = gSave.unk12B[r5]; + } + } + + gSave.unk118[0x12] = 0; + gSave.unk12B[0x12] = 0; + + for (r5 = 0; r5 < 0x12; r5++) { + if ((gSave.unk118[r5] - 0x65) > 0x10) { + MemCopy(&gSave.unk118[r5 + 1], &gSave.unk118[r5], 0x12 - r5); + MemCopy(&gSave.unk12B[r5 + 1], &gSave.unk12B[r5], 0x12 - r5); + } + } +#else + u32 r0, r4, r5; + u32 new_var; + u8 *r1, *r2, *r3, *r6, *r7, *r8, *r9, *r10; + + new_var = 4; + r1 = &gSave.inventory[34]; + r5 = 0; + r2 = gSave.unk118; +code0_0: + r0 = r2[0x13]; + r3 = &r1[4]; + r10 = r3; + if (r0 == 0) { + *r2 = r0; + } + r2++; + r5++; + if (r5 <= 0x12) + goto code0_0; + + r1[0x16] = 0; + r1[0x29] = 0; + r5 = 0; + r9 = &r1[0x17]; + r3 = &r1[0x18]; + r8 = r3; + r7 = &r1[new_var]; + r6 = &r1[5]; +code0_2: + r0 = r10[r5] - 0x65; + if (r0 > 0x10) { + MemCopy(r6, r7, 0x12 - r5); + MemCopy(r8, r9, 0x12 - r5); + } + r9++; + r8++; + r7++; + r6++; + r5++; + if (r5 <= 0x11) + goto code0_2; +#endif +} s32 sub_0801E8B0(u32 idx) { u32 i; diff --git a/src/enemy/armos.c b/src/enemy/armos.c index 7e0c3b7a..38a30371 100644 --- a/src/enemy/armos.c +++ b/src/enemy/armos.c @@ -413,7 +413,43 @@ void sub_08030834(ArmosEntity* this) { SetTile(this->unk_78, COORD_TO_TILE(super), super->collisionLayer); } -ASM_FUNC("asm/non_matching/armos/sub_0803086C.inc", bool32 sub_0803086C(ArmosEntity* this)) +bool32 sub_0803086C(ArmosEntity* this) { + u32 uVar2; + u32 pos; + u32 pos2; + u16 centerY; + u16 centerX; + FORCE_REGISTER(u32 r2, r2); + + if (this->unk_7c != NULL) { + if ((gPlayerState.flags & 0x80) != 0) { + centerX = super->x.HALF_U.HI - gRoomControls.origin_x; + centerY = super->y.HALF_U.HI - gRoomControls.origin_y; + // TODO for some reason the 0x3f of COORD_TO_TILE(super) needs to be forced to r2 here. + pos = ((((((super)->x.HALF.HI) - gRoomControls.origin_x) >> 4) & (r2 = 0x3f)) | + (((((super)->y.HALF.HI) - gRoomControls.origin_y) >> 4) & r2) << 6); + + if (GetTileType(pos, super->collisionLayer) == 0x4049) { + if (CheckPlayerInRegion(centerX, centerY, 2, 0xc) != 0) { + if (CheckPlayerInRegion(centerX, centerY - 4, 2, 4) != 0) { + gPlayerEntity.spritePriority.b0 = 3; + DoExitTransition(this->unk_7c); + gRoomTransition.armos_data.field_0xae = this->unk_80; + return TRUE; + } + } else { + SetTile(0x4022, pos, super->collisionLayer); + } + } else { + if (CheckPlayerInRegion(centerX, centerY + 6, 2, 5) != 0) { + SetTile(0x4049, COORD_TO_TILE(super), super->collisionLayer); + } + } + } + super->spritePriority.b0 = 4; + } + return FALSE; +} void sub_080309A8(ArmosEntity* this) { GetNextFrame(super); diff --git a/src/enemy/gleerok.c b/src/enemy/gleerok.c index c7391702..3921b18f 100644 --- a/src/enemy/gleerok.c +++ b/src/enemy/gleerok.c @@ -78,7 +78,7 @@ extern void sub_0802EA48(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, extern void sub_0802EA68(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, u32 param_4); extern bool32 sub_0802E7CC(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, u32 param_4); extern bool32 sub_0802EA88(Gleerok_HeapStruct* param_1); -extern bool32 sub_0802E768(Gleerok_HeapStruct* param_1); +extern void sub_0802E768(Gleerok_HeapStruct* param_1); void Gleerok_OnTick(GleerokEntity* this); void Gleerok_OnDeath(GleerokEntity* this); @@ -548,7 +548,7 @@ void sub_0802D7B4(GleerokEntity* this) { sub_0802E518(this); } -NONMATCH("asm/non_matching/gleerok/sub_0802D86C.inc", void sub_0802D86C(GleerokEntity* this)) { +void sub_0802D86C(GleerokEntity* this) { Entity* enemy; Entity* enemy2; switch (super->type) { @@ -692,14 +692,12 @@ NONMATCH("asm/non_matching/gleerok/sub_0802D86C.inc", void sub_0802D86C(GleerokE if (super->zVelocity > 0) return; - enemy = CreateEnemy(GLEEROK, 4); - super->child = enemy; - if (enemy) { - enemy->parent = super->parent; + super->child = CreateEnemy(GLEEROK, 4); + if (super->child) { + super->child->parent = super->parent; this->unk_84->ent = super->child; ((GleerokEntity*)super->child)->unk_84 = this->unk_84; - // Making super in super->child volatile solves this but ugly - CopyPosition(super, super->child); + CopyPosition(super, ((volatile Entity*)super)->child); DeleteThisEntity(); } @@ -710,7 +708,6 @@ NONMATCH("asm/non_matching/gleerok/sub_0802D86C.inc", void sub_0802D86C(GleerokE break; } } -END_NONMATCH void sub_0802DB84(GleerokEntity* this) { u32 timer; @@ -1319,13 +1316,11 @@ NONMATCH("asm/non_matching/gleerok/sub_0802E518.inc", void sub_0802E518(GleerokE } END_NONMATCH -NONMATCH("asm/non_matching/gleerok/sub_0802E768.inc", bool32 sub_0802E768(Gleerok_HeapStruct* param_1)) { +void sub_0802E768(Gleerok_HeapStruct* param_1) { + u32 cVar1; s32 bVar2; s32 bVar2a; - u32 bVar3; - - // solves regalloc - // register u32 bVar3 asm("r1"); + FORCE_REGISTER(u32 bVar3, r1); u32 bVar3a; u32 uVar4; s32 iVar5; @@ -1343,8 +1338,8 @@ NONMATCH("asm/non_matching/gleerok/sub_0802E768.inc", bool32 sub_0802E768(Gleero } param_1->filler[uVar4].unk0.HALF.HI = bVar3; - bVar3 = param_1->filler2[uVar4].unk0.HALF.HI; - bVar2 = (bVar3 - param_1->filler2[uVar4 + 1].unk0.HALF.HI) & 0x1f; + bVar3 = param_1->filler2[(uVar4)].unk0.HALF.HI; + bVar2 = (bVar3 - param_1->filler2[(uVar4 + 1)].unk0.HALF.HI) & 0x1f; if (bVar2 > 0x10) { if (bVar2 <= 0x1d) { @@ -1354,10 +1349,9 @@ NONMATCH("asm/non_matching/gleerok/sub_0802E768.inc", bool32 sub_0802E768(Gleero bVar3 = (bVar3 - 1) & 0x1f; } - param_1->filler2[uVar4].unk0.HALF.HI = bVar3; + param_1->filler2[(uVar4)].unk0.HALF.HI = bVar3; } } -END_NONMATCH u32 sub_0802E7CC(Gleerok_HeapStruct* param_1, u32 param_2, u32 param_3, u32 param_4) { param_1->entities[(u8)param_2]->animationState = param_1->filler[(u8)param_2].unk0.HALF.HI; diff --git a/src/enemy/octorokBoss.c b/src/enemy/octorokBoss.c index 8b248fa4..e4a9ca68 100644 --- a/src/enemy/octorokBoss.c +++ b/src/enemy/octorokBoss.c @@ -1048,8 +1048,52 @@ void sub_080369D0(OctorokBossEntity* this, s32 radius, s32 angleSpeed) { } /** Calculate tail angles frozen sub_08036AF0 */ -ASM_FUNC("asm/non_matching/octorokBoss/sub_08036AF0.inc", - void sub_08036AF0(OctorokBossEntity* this, s32 radius, s32 angleSpeed)) +void sub_08036AF0(OctorokBossEntity* this, s32 radius, s32 angleSpeed) { + s16 tmp; + OctorokBossHeap* heap; + u32 index; + heap = this->heap; + for (index = heap->tailCount - 1; index != 0; index--) { + if (angleSpeed == 0) { + if (radius >= sub_080041DC(&heap->tailObjects[index]->base, heap->tailObjects[index - 1]->base.x.HALF.HI, + heap->tailObjects[index - 1]->base.y.HALF.HI)) { + continue; + } else { + heap->tailObjects[index - 1]->angle.HALF.HI = + sub_080045DA(heap->tailObjects[index - 1]->base.x.WORD - heap->tailObjects[index]->base.x.WORD, + heap->tailObjects[index - 1]->base.y.WORD - heap->tailObjects[index]->base.y.WORD); + tmp = FixedMul(gSineTable[heap->tailObjects[index - 1]->angle.HALF.HI], radius << 4); + tmp = FixedDiv(tmp, 0x100); + heap->tailObjects[index - 1]->base.x.WORD = heap->tailObjects[index]->base.x.WORD + ((s32)tmp << 8); + tmp = FixedMul(gSineTable[heap->tailObjects[index - 1]->angle.HALF.HI + 0x40], radius << 4); + heap->tailObjects[index - 1]->base.y.WORD = + heap->tailObjects[index]->base.y.WORD - (FixedDiv(tmp, 0x100) << 8); + } + } else { + if (heap->tailObjects[index - 1]->angle.HALF.HI != heap->tailObjects[index]->angle.HALF.HI) { + if ((s8)(heap->tailObjects[index]->angle.HALF.HI - heap->tailObjects[index - 1]->angle.HALF.HI) >= 1) { + if ((s8)(heap->tailObjects[index]->angle.HALF.HI - heap->tailObjects[index - 1]->angle.HALF.HI) > + (u8)angleSpeed) { + heap->tailObjects[index - 1]->angle.HALF.HI = + heap->tailObjects[index]->angle.HALF.HI - angleSpeed; + } + } else { + if ((s8)(heap->tailObjects[index]->angle.HALF.HI - heap->tailObjects[index - 1]->angle.HALF.HI) < + (s8)-angleSpeed) { + heap->tailObjects[index - 1]->angle.HALF.HI = + heap->tailObjects[index]->angle.HALF.HI + angleSpeed; + } + } + } + tmp = FixedMul(gSineTable[heap->tailObjects[index - 1]->angle.HALF.HI], radius << 4); + heap->tailObjects[index - 1]->base.x.WORD = + heap->tailObjects[index]->base.x.WORD + (FixedDiv(tmp, 0x100) << 8); + tmp = FixedMul(gSineTable[heap->tailObjects[index - 1]->angle.HALF.HI + 0x40], radius << 4); + heap->tailObjects[index - 1]->base.y.WORD = + heap->tailObjects[index]->base.y.WORD - (FixedDiv(tmp, 0x100) << 8); + } + } +} void OctorokBoss_SetAttackTimer(OctorokBossEntity* this) { // These attack timers are only used if the boss isn't frozen and gRoomVars.field_0xc != 0x100 diff --git a/src/enemy/stalfos.c b/src/enemy/stalfos.c index c966d468..91ca9530 100644 --- a/src/enemy/stalfos.c +++ b/src/enemy/stalfos.c @@ -73,7 +73,10 @@ void Stalfos_OnTick(StalfosEntity* this) { } } -NONMATCH("asm/non_matching/stalfos/sub_0803933C.inc", void sub_0803933C(StalfosEntity* this)) { +void sub_0803933C(StalfosEntity* this) { + Entity* r0; + Entity* r1; + u32 r2; if (super->hitType == 0x44) { switch (super->contactFlags & 0x7f) { case 4 ... 6: @@ -87,20 +90,23 @@ NONMATCH("asm/non_matching/stalfos/sub_0803933C.inc", void sub_0803933C(StalfosE break; } } - if (super->contactFlags == 0x9d) { - if (super->child == NULL) { + r2 = super->contactFlags; + if (r2 == 0x9d) { + r1 = super->child; + if (r1 == NULL) { if (super->action < 9) { - Entity* projectile = CreateProjectileWithParent(super, STALFOS_PROJECTILE, 1); - if (projectile != NULL) { - projectile->frameIndex = super->animationState << 1; - projectile->type2 = 2; + r1 = CreateProjectileWithParent(super, STALFOS_PROJECTILE, 1); + if (r1 != NULL) { + r1->frameIndex = super->animationState << 1; + r1->type2 = 2; EnqueueSFX(SFX_186); } sub_08039A48(this); this->unk_78 += 0x5a; } } else { - super->child->contactFlags = 0x9d; + r0 = r1; + r0->contactFlags = r2; EnqueueSFX(SFX_186); super->child = NULL; sub_08039A48(this); @@ -113,7 +119,6 @@ NONMATCH("asm/non_matching/stalfos/sub_0803933C.inc", void sub_0803933C(StalfosE } EnemyFunctionHandlerAfterCollision(super, Stalfos_Functions); } -END_NONMATCH void sub_08039418(StalfosEntity* this) { if (super->type == 0) { diff --git a/src/npc/npc23.c b/src/npc/npc23.c index 6879c6a9..eccd933c 100644 --- a/src/npc/npc23.c +++ b/src/npc/npc23.c @@ -174,8 +174,9 @@ bool32 sub_0806650C(Entity* this) { return 1; } -NONMATCH("asm/non_matching/npc23/sub_08066570.inc", void sub_08066570(Entity* this)) { +void sub_08066570(Entity* this) { u32 direction; + s32 tmp; u32 dir1, dir2; bool32 cond; if ((this->frame & ANIM_DONE) == 0) { @@ -191,6 +192,7 @@ NONMATCH("asm/non_matching/npc23/sub_08066570.inc", void sub_08066570(Entity* th dir2 = (direction & 0x18); dir1 = (this->direction & 0x18); + tmp = 0x18; if (dir1 == dir2) { dir1 = (direction + 5) & 7; dir2 = (this->direction + 5) & 7; @@ -201,9 +203,8 @@ NONMATCH("asm/non_matching/npc23/sub_08066570.inc", void sub_08066570(Entity* th if (cond) { this->direction = direction; direction += 4; - direction &= 0x18; + direction &= tmp; direction >>= 3; InitializeAnimation(this, direction); } } -END_NONMATCH diff --git a/src/object/frozenOctorok.c b/src/object/frozenOctorok.c index fe537c4b..7805839c 100644 --- a/src/object/frozenOctorok.c +++ b/src/object/frozenOctorok.c @@ -40,6 +40,8 @@ void FrozenOctorok_ChangeObjPaletteOfChildren(FrozenOctorokEntity*, u32); void sub_0809CBE4(FrozenOctorokEntity*); void sub_0809CB70(FrozenOctorokEntity*, s32, s32); +extern const u8 gUnk_08123E1C[]; + void FrozenOctorok(FrozenOctorokEntity* this) { static void (*const FrozenOctorok_Actions[])(FrozenOctorokEntity*) = { FrozenOctorok_Init, @@ -162,8 +164,87 @@ const u8 gUnk_08123E1C[] = { 128, }; -ASM_FUNC("asm/non_matching/frozenOctorok/FrozenOctorok_Action1.inc", - void FrozenOctorok_Action1(FrozenOctorokEntity* this)) +void FrozenOctorok_Action1(FrozenOctorokEntity* this) { + u32 tmp1; + u32 tmp2; + + switch (super->type) { + case 1: + case 2: + case 3: + case 4: + SortEntityBelow(super->parent, super); + if (super->parent->subAction == 6) { + if ((s8)super->subtimer < 0) { + super->subtimer = -this->heap->unk_0; + } else { + super->subtimer = this->heap->unk_0; + } + sub_0809CBE4(this); + } + tmp1 = 0x10000 / (((FrozenOctorokEntity*)super->parent)->unk_76); + tmp1 = ((tmp1 << 0xd) >> 8); + tmp1 -= 0x2000; + if (this->heap->mouthObject->base.health == 1) { + tmp1 = 0x2200 + tmp1; + } else { + tmp1 = (tmp1 >> 1) + 0x2200; + } + tmp2 = (u8) - (((FrozenOctorokEntity*)super->parent)->unk_7b + gUnk_08123E18[super->type - 1]); + sub_0809CB70(this, tmp2, tmp1); + this->unk_7b = + ((FrozenOctorokEntity*)super->parent)->unk_7b + gUnk_08123E1C[super->type - 1] + this->unk_79; + SetAffineInfo(super, this->unk_76, this->unk_74, *(u16*)&this->unk_7a); + break; + case 5: + SortEntityBelow(super->parent, super); + if ((super->parent->subAction != 4) && (super->health != 1)) { + if (0x1c < this->unk_79) { + this->unk_79--; + } + if (this->unk_76 > 0x100) { + this->unk_76--; + } else { + this->unk_76 = 0x100; + } + } + tmp1 = (0x10000 / ((FrozenOctorokEntity*)super->parent)->unk_74); + tmp1 = ((this->unk_79 << 8) * tmp1 >> 8); + tmp2 = (u8) - (((FrozenOctorokEntity*)super->parent)->unk_7b + 0x80); + sub_0809CB70(this, tmp2, tmp1); + this->unk_7b = ((FrozenOctorokEntity*)super->parent)->unk_7b; + SetAffineInfo(super, this->unk_76, this->unk_74, *(u16*)&this->unk_7a); + return; + case 0: + if (CheckFlags(OUGONTEKI_G)) { + RequestPriorityDuration(super, 0x1e); + } + FrozenOctorok_Action1SubActions[super->subAction](this); + if (super->subtimer != 0) { + if ((gRoomTransition.frameCount & 7) == 0) { + CreateSparkle(super->child); + } + if (this->unk_7e != 0) { + super->child->zVelocity = super->child->zVelocity - (s16)this->unk_7e; + super->child->z.WORD += super->child->zVelocity; + if (((super->child)->zVelocity == 0x3000) || ((super->child)->zVelocity == -0x3000)) { + this->unk_7e = -this->unk_7e; + } + } + } + SetAffineInfo(super, this->unk_76, this->unk_74, *(u16*)&this->unk_7a); + break; + case 6: + CopyPosition(super->parent, super); + SetAffineInfo(super, this->unk_76, this->unk_74, *(u16*)&this->unk_7a); + break; + case 7: + if (gRoomControls.camera_target != super) { + DeleteThisEntity(); + } + break; + } +} void FrozenOctorok_Action1SubAction0(FrozenOctorokEntity* this) { Entity* child; diff --git a/src/object/octorokBossObject.c b/src/object/octorokBossObject.c index eb1a2f1e..22e3561e 100644 --- a/src/object/octorokBossObject.c +++ b/src/object/octorokBossObject.c @@ -146,8 +146,7 @@ void OctorokBossObject_Init(Entity* this) { } } -NONMATCH("asm/non_matching/octorokBossObject/OctorokBossObject_Action1.inc", - void OctorokBossObject_Action1(Entity* this)) { +void OctorokBossObject_Action1(Entity* this) { s32 tmp_c; u32 loop_var; @@ -184,7 +183,7 @@ NONMATCH("asm/non_matching/octorokBossObject/OctorokBossObject_Action1.inc", if ((u32)this->timer == GET_HELPER(this)->tailCount - 1) { this->action = 2; this->timer = 240; - this->direction = gUnk_0812384C[(this->type2 & 0xf) * 2] + ((u8)Random() & 0xf); + this->direction = gUnk_0812384C[(u8)((this->type2 & 0xf) * 2)] + ((u8)Random() & 0xf); this->speed = gUnk_0812384C[(this->type2 & 0xf) * 2 + 1] + ((u16)Random() & 0x1ff); if (this->type != 0) { return; @@ -233,6 +232,7 @@ NONMATCH("asm/non_matching/octorokBossObject/OctorokBossObject_Action1.inc", *(int*)&this->field_0x78 += -1; return; } + GET_HELPER(this)->tailObjects[this->timer]->x = GET_HELPER(this)->tailObjects[this->timer]->x; DeleteThisEntity(); break; case 5: @@ -245,6 +245,7 @@ NONMATCH("asm/non_matching/octorokBossObject/OctorokBossObject_Action1.inc", this->field_0x76.HWORD -= 0x20; this->field_0x74.HWORD -= 0x20; } + SetAffineInfo(this, (u32)this->field_0x76.HWORD, (u32)(u16)this->field_0x74.HWORD, (u32)(u16)this->field_0x7a.HWORD); } else { @@ -313,7 +314,6 @@ NONMATCH("asm/non_matching/octorokBossObject/OctorokBossObject_Action1.inc", break; } } -END_NONMATCH void OctorokBossObject_Action2(Entity* this) { s32 tmp; diff --git a/src/objectUtils.c b/src/objectUtils.c index 1c78c451..a97cdbfb 100644 --- a/src/objectUtils.c +++ b/src/objectUtils.c @@ -266,52 +266,53 @@ void CreateSparkle(Entity* entity) { } } -NONMATCH("asm/non_matching/objectUtils/SyncPlayerToPlatform.inc", - void SyncPlayerToPlatform(Entity* this, bool32 param_2)) { +void SyncPlayerToPlatform(Entity* this, bool32 param_2) { s16 oldValue; s32 diff; u16 newValue; + FORCE_REGISTER(Entity * that, r4) = this; + FORCE_REGISTER(bool32 p2, r6) = param_2; + u16 dir = that->direction; - if ((this->direction & 0x80) == 0) { - switch (this->direction >> 3) { + if ((dir & 0x80) == 0) { + switch (dir >> 3) { case 0: - oldValue = this->y.HALF_U.HI; - LinearMoveUpdate(this); - newValue = this->y.HALF_U.HI; + oldValue = that->y.HALF_U.HI; + LinearMoveUpdate(that); + newValue = that->y.HALF_U.HI; diff = ((oldValue - newValue) << 0x10) >> 0x10; - if ((diff != 0) && (param_2 != 0)) { + if ((diff != 0) && (p2 != 0)) { sub_080044AE(&gPlayerEntity, diff << 8, 0); } break; case 1: - oldValue = this->x.HALF_U.HI; - LinearMoveUpdate(this); - diff = ((this->x.HALF_U.HI - oldValue) * 0x10000) >> 0x10; - if ((diff != 0) && (param_2 != 0)) { + oldValue = that->x.HALF_U.HI; + LinearMoveUpdate(that); + diff = ((that->x.HALF_U.HI - oldValue) * 0x10000) >> 0x10; + if ((diff != 0) && (p2 != 0)) { sub_080044AE(&gPlayerEntity, diff << 8, 8); } break; case 2: - oldValue = this->y.HALF_U.HI; - LinearMoveUpdate(this); - diff = ((this->y.HALF_U.HI - oldValue) * 0x10000) >> 0x10; - if ((diff != 0) && (param_2 != 0)) { + oldValue = that->y.HALF_U.HI; + LinearMoveUpdate(that); + diff = ((that->y.HALF_U.HI - oldValue) * 0x10000) >> 0x10; + if ((diff != 0) && (p2 != 0)) { sub_080044AE(&gPlayerEntity, diff << 8, 0x10); } break; case 3: - oldValue = this->x.HALF_U.HI; - LinearMoveUpdate(this); - newValue = this->x.HALF_U.HI; + oldValue = that->x.HALF_U.HI; + LinearMoveUpdate(that); + newValue = that->x.HALF_U.HI; diff = ((oldValue - newValue) << 0x10) >> 0x10; - if ((diff != 0) && (param_2 != 0)) { + if ((diff != 0) && (p2 != 0)) { sub_080044AE(&gPlayerEntity, diff << 8, 0x18); } break; } } } -END_NONMATCH void UpdateRailMovement(Entity* this, u16** param_2, u16* param_3) { u16* ptr = *param_2; diff --git a/src/scroll.c b/src/scroll.c index c4c73049..2d9c85bd 100644 --- a/src/scroll.c +++ b/src/scroll.c @@ -813,20 +813,22 @@ void sub_08080C80(u32* param_1) { sub_0807C8B0(gMapTop.mapData, gRoomControls.width >> 4, gRoomControls.height >> 4); } -NONMATCH("asm/non_matching/scroll/sub_08080CB4.inc", void sub_08080CB4(Entity* this)) { +void sub_08080CB4(Entity* this) { Entity* effect; u32 tmp; u32 tmp2; + u32 tmp3; + u32 mask; if (this->type != this->animIndex) { InitAnimationForceUpdate(this, this->type); if (this->type == 0x5c) { const KinstoneWorldEvent* ptr = &gKinstoneWorldEvents[this->type2]; - this->palette.raw = ((ptr->objPalette & 0xf) << 4) | ptr->objPalette; + tmp = ptr->objPalette; + tmp2 = tmp & 0xf; + this->palette.raw = (tmp << 4) | tmp2; } - } else { - UpdateAnimationSingleFrame(this); if (this->spriteSettings.draw != 0) { switch (this->type) { @@ -857,4 +859,3 @@ NONMATCH("asm/non_matching/scroll/sub_08080CB4.inc", void sub_08080CB4(Entity* t } } } -END_NONMATCH @@ -592,27 +592,29 @@ void DrawKeys(void) { } } -NONMATCH("asm/non_matching/ui/CreateUIElement.inc", void CreateUIElement(u32 type, u32 type2)) { - u8 bVar1; +void CreateUIElement(u32 type, u32 type2) { u32 index; + UIElement* new_var; UIElement* element; - UIElementDefinition* definition; for (index = 0; index < MAX_UI_ELEMENTS; index++) { - element = &gUnk_0200AF00.elements[index]; - if (element->used == 0) { - definition = &gUIElementDefinitions[type]; - element->type = (u8)type; + + element = gUnk_0200AF00.elements; + element += index; + + if (!element->used) { + element->type = type; element->type2 = type2; element->frameIndex = 0xff; element->used = 1; - element->unk_1a = definition->unk_4; - element->buttonElementId = definition->buttonElementId; + element->unk_1a = gUIElementDefinitions[type].unk_4; + // Permuter trickery. TODO find something more senseful? + index = type; + element->buttonElementId = gUIElementDefinitions[index].buttonElementId; return; } } } -END_NONMATCH void sub_0801CAB8(UIElement* element, Frame* frame) { element->framePtr = frame; |
