From be820f416bdb1a5573c098e44adb8953faef98d6 Mon Sep 17 00:00:00 2001 From: Oliver Bell Date: Sun, 21 Sep 2025 15:01:22 +0100 Subject: [PATCH] vc: import last 2 functions --- .vscode/settings.json | 4 +- ...sk_Item_Shield_Magnetic__virtual_console.s | 99 +++++++++++ asm/sub_8091CB0__virtual_console.s | 162 ++++++++++++++++++ include/game/cutscenes/final_ending_land.h | 6 + src/game/cutscenes/final_ending_fall.c | 68 +++++--- src/game/stage/item_tasks.c | 25 ++- 6 files changed, 335 insertions(+), 29 deletions(-) create mode 100644 asm/Task_Item_Shield_Magnetic__virtual_console.s create mode 100644 asm/sub_8091CB0__virtual_console.s create mode 100644 include/game/cutscenes/final_ending_land.h diff --git a/.vscode/settings.json b/.vscode/settings.json index a23a3ed41..438f1b434 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -373,7 +373,9 @@ "indicators.h": "c", "multiplayer_teleport.h": "c", "input_buffer.h": "c", - "*.inc": "c" + "*.inc": "arm", + "extra_ending_slides.h": "c", + "final_ending_land.h": "c" }, "asm-code-lens.donated": true, "editor.formatOnSave": true, diff --git a/asm/Task_Item_Shield_Magnetic__virtual_console.s b/asm/Task_Item_Shield_Magnetic__virtual_console.s new file mode 100644 index 000000000..25320b3f9 --- /dev/null +++ b/asm/Task_Item_Shield_Magnetic__virtual_console.s @@ -0,0 +1,99 @@ +.syntax unified +.text + push {r4, r5, r6, r7, lr} + ldr r0, _0802ABA4 @ =0x030026F0 + ldr r2, [r0] + ldrh r1, [r2, #6] + movs r4, #0xc0 + lsls r4, r4, #0x12 + adds r3, r4, #0 + adds r3, #0x30 + adds r0, r1, r3 + ldrb r6, [r0] + orrs r4, r1 + ldr r5, _0802ABA8 @ =0x03005960 + ldr r0, _0802ABAC @ =0x030054CC + ldrb r0, [r0] + cmp r0, #2 + bhi _0802AB7C + adds r3, r5, #0 + adds r3, #0x80 + adds r0, r3, #0 + adds r0, #0x37 + ldrb r1, [r0] + movs r0, #0xa + ands r0, r1 + cmp r0, #8 + beq _0802AB3E + adds r0, r2, #0 + bl TaskDestroy + b _0802ABC2 +_0802AB3E: + movs r0, #2 + ands r0, r1 + cmp r0, #0 + bne _0802ABC2 + ldr r0, [r3, #8] + asrs r0, r0, #8 + ldr r1, [r5] + adds r2, r3, #0 + adds r2, #0x7c + subs r0, r0, r1 + ldrh r2, [r2] + adds r0, r0, r2 + strh r0, [r4, #0x16] + ldr r0, [r3, #0xc] + asrs r0, r0, #8 + ldr r1, [r5, #4] + subs r0, r0, r1 + strh r0, [r4, #0x18] + ldr r2, [r4, #0x10] + ldr r0, _0802ABB0 @ =0xFFFFCFFF + ands r2, r0 + str r2, [r4, #0x10] + adds r0, r3, #0 + adds r0, #0x90 + ldr r0, [r0] + ldr r0, [r0, #0x1c] + movs r1, #0xc0 + lsls r1, r1, #6 + ands r0, r1 + orrs r2, r0 + str r2, [r4, #0x10] +_0802AB7C: + ldr r0, _0802ABB4 @ =0x03005590 + ldr r0, [r0] + movs r1, #6 + bl Mod + adds r7, r0, #0 + adds r0, r4, #0 + bl UpdateSpriteAnimation + lsls r0, r6, #0x18 + asrs r2, r0, #0x18 + movs r3, #1 + ands r2, r3 + movs r0, #6 + ands r0, r7 + cmp r0, #0 + bne _0802ABB8 + cmp r2, r3 + bne _0802ABBC + b _0802ABC2 + .align 2, 0 +_0802ABA4: .4byte 0x030026F0 +_0802ABA8: .4byte 0x03005960 +_0802ABAC: .4byte 0x030054CC +_0802ABB0: .4byte 0xFFFFCFFF +_0802ABB4: .4byte 0x03005590 +_0802ABB8: + cmp r2, #0 + beq _0802ABC2 +_0802ABBC: + adds r0, r4, #0 + bl DisplaySprite +_0802ABC2: + pop {r4, r5, r6, r7} + pop {r0} + bx r0 + +.syntax divided diff --git a/asm/sub_8091CB0__virtual_console.s b/asm/sub_8091CB0__virtual_console.s new file mode 100644 index 000000000..c74c771de --- /dev/null +++ b/asm/sub_8091CB0__virtual_console.s @@ -0,0 +1,162 @@ +.syntax unified +.text + push {r4, r5, lr} + ldr r0, _08091C64 @ =0x030026F0 + ldr r0, [r0] + ldrh r5, [r0, #6] + movs r0, #0xc0 + lsls r0, r0, #0x12 + adds r4, r5, r0 + adds r0, r4, #0 + bl sub_8091F68 + adds r0, r4, #0 + bl sub_809205C + adds r0, r4, #0 + bl sub_80920E4 + adds r0, r4, #0 + bl sub_8092804 + adds r0, r4, #0 + bl sub_80921E8 + adds r0, r4, #0 + bl sub_8092850 + adds r0, r4, #0 + bl sub_80923AC + ldr r0, _08091C68 @ =0x0300036E + adds r1, r5, r0 + ldrh r0, [r1] + cmp r0, #0 + beq _08091C6C + subs r0, #1 + strh r0, [r1] + b _08091D32 + .align 2, 0 +_08091C64: .4byte 0x030026F0 +_08091C68: .4byte 0x0300036E +_08091C6C: + ldr r3, _08091D38 @ =0x0300035C + adds r5, r5, r3 + ldrb r1, [r5] + cmp r1, #9 + bhi _08091CCE + ldr r2, _08091D3C @ =0x03002840 + ldrh r0, [r2] + movs r3, #0x80 + lsls r3, r3, #6 + adds r1, r3, #0 + orrs r0, r1 + strh r0, [r2] + ldr r1, _08091D40 @ =gWinRegs + movs r0, #0xa0 + strh r0, [r1] + movs r0, #0xf0 + strh r0, [r1, #4] + ldrh r2, [r1, #8] + movs r0, #0x3f + orrs r0, r2 + strh r0, [r1, #8] + ldrh r2, [r1, #0xa] + movs r0, #0x1f + orrs r0, r2 + strh r0, [r1, #0xa] + ldr r2, _08091D44 @ =0x030018E8 + ldr r0, _08091D48 @ =0x00003FBF + strh r0, [r2] + ldr r3, _08091D4C @ =0x080E1030 + ldrb r0, [r5] + adds r3, r3, r0 + movs r1, #1 + ands r1, r0 + cmp r1, #0 + bne _08091CC0 + ldrb r1, [r3] + ldrh r0, [r2, #4] + adds r0, r0, r1 + strh r0, [r2, #4] + cmp r0, #0xf + bhi _08091D1C + b _08091D32 +_08091CC0: + ldrb r1, [r3] + ldrh r0, [r2, #4] + subs r0, r0, r1 + strh r0, [r2, #4] + cmp r0, r1 + bls _08091D1C + b _08091D32 +_08091CCE: + movs r0, #0xd7 + lsls r0, r0, #2 + adds r5, r4, r0 + ldrb r0, [r5] + cmp r0, #0xa + bne _08091D2A + adds r0, r4, #0 + bl sub_80928C8 + ldr r2, _08091D3C @ =0x03002840 + ldrh r0, [r2] + movs r3, #0x80 + lsls r3, r3, #6 + adds r1, r3, #0 + orrs r0, r1 + strh r0, [r2] + ldr r1, _08091D40 @ =gWinRegs + movs r0, #0xa0 + strh r0, [r1] + movs r0, #0xf0 + strh r0, [r1, #4] + ldrh r2, [r1, #8] + movs r0, #0x3f + orrs r0, r2 + strh r0, [r1, #8] + ldrh r2, [r1, #0xa] + movs r0, #0x1f + orrs r0, r2 + strh r0, [r1, #0xa] + ldr r1, _08091D44 @ =0x030018E8 + ldr r0, _08091D48 @ =0x00003FBF + strh r0, [r1] + ldrh r0, [r1, #4] + subs r0, #1 + strh r0, [r1, #4] + lsls r0, r0, #0x10 + lsrs r0, r0, #0x10 + cmp r0, #1 + bhi _08091D32 +_08091D1C: + ldrb r0, [r5] + adds r0, #1 + cmp r0, #2 + bne _08091D26 + adds r0, #4 +_08091D26: + strb r0, [r5] + b _08091D32 +_08091D2A: + ldr r0, _08091D50 @ =0x030026F0 + ldr r1, [r0] + ldr r0, _08091D54 @ =sub_8091E60 + str r0, [r1, #8] +_08091D32: + pop {r4, r5} + pop {r0} + bx r0 + .align 2, 0 +_08091D38: .4byte 0x0300035C +_08091D3C: .4byte 0x03002840 +_08091D40: .4byte gWinRegs +_08091D44: .4byte 0x030018E8 +_08091D48: .4byte 0x00003FBF +_08091D4C: .4byte 0x080E1030 +_08091D50: .4byte 0x030026F0 +_08091D54: .4byte sub_8091E60 +_08091D58: + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + +.syntax divided diff --git a/include/game/cutscenes/final_ending_land.h b/include/game/cutscenes/final_ending_land.h new file mode 100644 index 000000000..12c017f1f --- /dev/null +++ b/include/game/cutscenes/final_ending_land.h @@ -0,0 +1,6 @@ +#ifndef GUARD_COURSE_CUT_SCENES_FINAL_ENDING_LAND_H +#define GUARD_COURSE_CUT_SCENES_FINAL_ENDING_LAND_H + +void CreateFinalEndingLandingCutScene(void); + +#endif diff --git a/src/game/cutscenes/final_ending_fall.c b/src/game/cutscenes/final_ending_fall.c index 17e3d9774..33800c86e 100644 --- a/src/game/cutscenes/final_ending_fall.c +++ b/src/game/cutscenes/final_ending_fall.c @@ -1,6 +1,7 @@ #include "global.h" #include "game/cutscenes/endings.h" #include "game/cutscenes/extra_ending_slides.h" +#include "game/cutscenes/final_ending_land.h" #include "core.h" #include "sprite.h" #include "game/stage/screen_fade.h" @@ -72,6 +73,18 @@ struct FinalEndingFallCutScene { void sub_8092690(void); void sub_8092800(struct Task *); +void sub_8091F68(struct FinalEndingFallCutScene *); +void sub_809205C(struct FinalEndingFallCutScene *); +void sub_80920E4(struct FinalEndingFallCutScene *); +void sub_8092804(struct FinalEndingFallCutScene *); +void sub_80921E8(struct FinalEndingFallCutScene *); +void sub_8092850(struct FinalEndingFallCutScene *); +void sub_80923AC(struct FinalEndingFallCutScene *); +u32 sub_80928C8(struct FinalEndingFallCutScene *); +void sub_80927E8(void); +void sub_809289C(struct FinalEndingFallCutScene *); +void sub_8091E60(void); +void sub_8092780(void); static const u16 gUnknown_080E1648[4] = { TM_CUTSCENE_FINAL_ENDING_FALL_BG, @@ -391,18 +404,11 @@ void CreateFinalEndingFallCutScene(void) DrawBackground(background); } -void sub_8091F68(struct FinalEndingFallCutScene *); -void sub_809205C(struct FinalEndingFallCutScene *); -void sub_80920E4(struct FinalEndingFallCutScene *); -void sub_8092804(struct FinalEndingFallCutScene *); -void sub_80921E8(struct FinalEndingFallCutScene *); -void sub_8092850(struct FinalEndingFallCutScene *); -void sub_80923AC(struct FinalEndingFallCutScene *); - -u32 sub_80928C8(struct FinalEndingFallCutScene *); - -void sub_8091E60(void); - +// Very likely this function was hand patched for the virtual console +// release. The source is not matchable in C: https://decomp.me/scratch/yWtRm +#if !defined(NON_MATCHING) && defined(VIRTUAL_CONSOLE) && defined(JAPAN) +ASM_FUNC("asm/sub_8091CB0__virtual_console.s", void sub_8091CB0(void)) +#else void sub_8091CB0(void) { struct FinalEndingFallCutScene *scene = TASK_DATA(gCurTask); @@ -419,6 +425,7 @@ void sub_8091CB0(void) return; } +#ifndef VITUAL_CONSOLE if ((scene->unk35C & 1) == 0 && scene->unk35C < 10) { gDispCnt |= 0x2000; gWinRegs[0] = DISPLAY_HEIGHT; @@ -432,18 +439,32 @@ void sub_8091CB0(void) if (gBldRegs.bldY >= 0x10) { scene->unk35C++; } - } else if (scene->unk35C < 10) { + } else +#endif + if (scene->unk35C < 10) { gDispCnt |= 0x2000; gWinRegs[0] = DISPLAY_HEIGHT; gWinRegs[2] = DISPLAY_WIDTH; gWinRegs[4] |= 0x3F; gWinRegs[5] |= 0x1F; gBldRegs.bldCnt = 0x3FBF; +#ifdef VIRTUAL_CONSOLE + if ((!(scene->unk35C & 1) && // format + (gBldRegs.bldY = gUnknown_080E1738[scene->unk35C] + gBldRegs.bldY) > 0xF) + || ((scene->unk35C & 1) + && (gBldRegs.bldY = -gUnknown_080E1738[scene->unk35C] + gBldRegs.bldY) <= gUnknown_080E1738[scene->unk35C])) { + if ((scene->unk35C + 1) == 2) { + scene->unk35C += 4; + } else { + scene->unk35C++; + } + } +#else gBldRegs.bldY -= gUnknown_080E1738[scene->unk35C]; - if (gBldRegs.bldY <= gUnknown_080E1738[scene->unk35C]) { scene->unk35C++; } +#endif } else if (scene->unk35C == 10) { sub_80928C8(scene); gDispCnt |= 0x2000; @@ -455,16 +476,21 @@ void sub_8091CB0(void) gBldRegs.bldY--; if (gBldRegs.bldY <= 1) { +#ifdef VIRTUAL_CONSOLE + if ((scene->unk35C + 1) == 2) { + scene->unk35C += 4; + } else { + scene->unk35C++; + } +#else scene->unk35C++; +#endif } } else { gCurTask->main = sub_8091E60; } } - -void sub_80927E8(void); - -void sub_809289C(struct FinalEndingFallCutScene *); +#endif void sub_8091E60(void) { @@ -752,8 +778,6 @@ void sub_80923AC(struct FinalEndingFallCutScene *scene) } } -void sub_8092780(void); - void sub_8092690(void) { struct FinalEndingFallCutScene *scene = TASK_DATA(gCurTask); @@ -814,10 +838,6 @@ void sub_8092780(void) } } -// Non matching onwards - -void CreateFinalEndingLandingCutScene(void); - void sub_80927E8(void) { struct Task UNUSED *t = gCurTask; diff --git a/src/game/stage/item_tasks.c b/src/game/stage/item_tasks.c index 7606146fe..096ebca44 100644 --- a/src/game/stage/item_tasks.c +++ b/src/game/stage/item_tasks.c @@ -201,13 +201,19 @@ void Task_Item_Shield_Normal(void) #ifndef NON_MATCHING // Looks like they may have manually edited the rom for the virtual console -// to keep all the functions in the same alignment as the original rom. -// Maybe they couldn't reexport the anims? +// so they needed to keep all functions aligned #ifdef VIRTUAL_CONSOLE asm(".byte 0x00, 0x00, 0x00, 0x00"); #endif #endif +// The virtual console version of this is probably manually edited +// so much that it is not matchable with C, however the logic was +// easy to replicate in C so it's documented below +// https://decomp.me/scratch/LzKYd +#if !defined(NON_MATCHING) && defined(VIRTUAL_CONSOLE) && defined(JAPAN) +ASM_FUNC("asm/Task_Item_Shield_Magnetic__virtual_console.s", void Task_Item_Shield_Magnetic(void)) +#else void Task_Item_Shield_Magnetic(void) { s8 param = ITEMTASK_GET_PLAYER_NUM(); @@ -216,6 +222,9 @@ void Task_Item_Shield_Magnetic(void) struct Camera *cam = &gCamera; bool32 b; +#ifdef VIRTUAL_CONSOLE + u32 m; +#endif if (IS_SINGLE_PLAYER) { u32 itemEffect = (gPlayer.itemEffect & (PLAYER_ITEM_EFFECT__SHIELD_MAGNETIC | PLAYER_ITEM_EFFECT__INVINCIBILITY)); @@ -241,6 +250,10 @@ void Task_Item_Shield_Magnetic(void) } } +#ifdef VIRTUAL_CONSOLE + m = Mod(gStageTime, 6); +#endif + UpdateSpriteAnimation(&item->s); b = (param); @@ -251,14 +264,18 @@ void Task_Item_Shield_Magnetic(void) u32 one = 1; #endif b &= one; +#ifdef VIRTUAL_CONSOLE + if ((!(m & 6) && (b != one)) || ((m & 6) && (b != 0))) { +#else if (((gStageTime & 0x2) && (b != one)) || (!(gStageTime & 0x2) && (b != 0))) { +#endif DisplaySprite(&item->s); } } } +#endif -// Unused? -void Task_802ABC8(void) +UNUSED void Task_802ABC8(void) { ItemTask *item = TASK_DATA(gCurTask); struct Camera *cam = &gCamera;