From 12c5c2862dc9c50a6a37ec964ea4c4196e6545a1 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 28 Dec 2025 23:34:04 +0100 Subject: [PATCH] d_a_b_lastboss WIP --- .../SOUE01/rels/d_a_b_lastbossNP/symbols.txt | 107 +++-- config/SOUE01/splits.txt | 20 +- config/SOUE01/symbols.txt | 58 +-- configure.py | 7 +- include/d/a/b/d_a_b_lastboss.h | 172 ++++++- include/d/a/obj/d_a_obj_base.h | 18 +- include/d/col/cc/d_cc_d.h | 1 + include/d/d_cc.h | 18 +- include/d/d_sc_game.h | 4 + include/toBeSorted/d_enemy_sword_mdl.h | 59 +++ include/toBeSorted/d_sword_swing_effect.h | 65 +++ include/toBeSorted/d_sword_swing_effect_mgr.h | 43 ++ src/REL/d/a/b/d_a_b_lastboss.cpp | 446 ++++++++++++++++++ src/d/col/c/c_m3d_g_cps.cpp | 2 +- src/toBeSorted/d_enemy_sword_mdl.cpp | 131 +++++ src/toBeSorted/d_sword_swing_effect.cpp | 218 +++++++++ src/toBeSorted/d_sword_swing_effect_mgr.cpp | 196 ++++++++ src/toBeSorted/dowsing_target.cpp | 1 + 18 files changed, 1464 insertions(+), 102 deletions(-) create mode 100644 include/toBeSorted/d_enemy_sword_mdl.h create mode 100644 include/toBeSorted/d_sword_swing_effect.h create mode 100644 include/toBeSorted/d_sword_swing_effect_mgr.h create mode 100644 src/toBeSorted/d_enemy_sword_mdl.cpp create mode 100644 src/toBeSorted/d_sword_swing_effect.cpp create mode 100644 src/toBeSorted/d_sword_swing_effect_mgr.cpp diff --git a/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt b/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt index e86f3fc1..71f6c186 100644 --- a/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt +++ b/config/SOUE01/rels/d_a_b_lastbossNP/symbols.txt @@ -3,36 +3,36 @@ _epilog = .text:0x00000030; // type:function size:0x2C scope:global _unresolved = .text:0x00000060; // type:function size:0x4 scope:global __register_global_object = .text:0x00000070; // type:function size:0x1C scope:global __destroy_global_chain = .text:0x00000090; // type:function size:0x54 scope:global -fn_143_F0 = .text:0x000000F0; // type:function size:0x40 +__dt__7mVec3_cFv = .text:0x000000F0; // type:function size:0x40 dAcBlastboss_c_classInit__Fv = .text:0x00000130; // type:function size:0x39C -fn_143_4D0 = .text:0x000004D0; // type:function size:0x58 -fn_143_530 = .text:0x00000530; // type:function size:0x90 -fn_143_5C0 = .text:0x000005C0; // type:function size:0x90 -fn_143_650 = .text:0x00000650; // type:function size:0x40 +__dt__Q214dAcBlastboss_c10callback_cFv = .text:0x000004D0; // type:function size:0x58 +__dt__15dCcD_Linked_CylFv = .text:0x00000530; // type:function size:0x90 +__dt__15dCcD_Linked_SphFv = .text:0x000005C0; // type:function size:0x90 +__dt__14dScnCallback_cFv = .text:0x00000650; // type:function size:0x40 __dt__27sFState_c<14dAcBlastboss_c>Fv = .text:0x00000690; // type:function size:0x58 __dt__30sFStateFct_c<14dAcBlastboss_c>Fv = .text:0x000006F0; // type:function size:0x6C __dt__83sStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00000760; // type:function size:0xA0 __dt__53sFStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c>Fv = .text:0x00000800; // type:function size:0xA4 -fn_143_8B0 = .text:0x000008B0; // type:function size:0x4 -fn_143_8C0 = .text:0x000008C0; // type:function size:0x84 -fn_143_950 = .text:0x00000950; // type:function size:0x58 -fn_143_9B0 = .text:0x000009B0; // type:function size:0x90 -fn_143_A40 = .text:0x00000A40; // type:function size:0xCC -fn_143_B10 = .text:0x00000B10; // type:function size:0xC0 -fn_143_BD0 = .text:0x00000BD0; // type:function size:0xDC -fn_143_CB0 = .text:0x00000CB0; // type:function size:0xC0 -fn_143_D70 = .text:0x00000D70; // type:function size:0xDC -fn_143_E50 = .text:0x00000E50; // type:function size:0x324 -fn_143_1180 = .text:0x00001180; // type:function size:0x3F8 -fn_143_1580 = .text:0x00001580; // type:function size:0x8 +__ct__7mVec3_cFv = .text:0x000008B0; // type:function size:0x4 +__dt__26dSwordSwingEffectProcMgr_cFv = .text:0x000008C0; // type:function size:0x84 +__ct__15dCcD_Linked_CpsFv = .text:0x00000950; // type:function size:0x58 +__dt__15dCcD_Linked_CpsFv = .text:0x000009B0; // type:function size:0x90 +__dt__16dEnemySwordMdl_cFv = .text:0x00000A40; // type:function size:0xCC +__ct__17UnkLastBossCcSph2Fv = .text:0x00000B10; // type:function size:0xC0 +__dt__17UnkLastBossCcSph2Fv = .text:0x00000BD0; // type:function size:0xDC +__ct__17UnkLastBossCcSph1Fv = .text:0x00000CB0; // type:function size:0xC0 +__dt__17UnkLastBossCcSph1Fv = .text:0x00000D70; // type:function size:0xDC +createHeap__14dAcBlastboss_cFv = .text:0x00000E50; // type:function size:0x324 +create__14dAcBlastboss_cFv = .text:0x00001180; // type:function size:0x3F8 +checkInBossRush__15MinigameManagerFv = .text:0x00001580; // type:function size:0x8 changeState__83sStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>FRC12sStateIDIf_c = .text:0x00001590; // type:function size:0x10 -fn_143_15A0 = .text:0x000015A0; // type:function size:0x34 -fn_143_15E0 = .text:0x000015E0; // type:function size:0x17A8 +doDelete__14dAcBlastboss_cFv = .text:0x000015A0; // type:function size:0x34 +actorExecute__14dAcBlastboss_cFv = .text:0x000015E0; // type:function size:0x17A8 executeState__83sStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>Fv = .text:0x00002D90; // type:function size:0x10 getStateID__83sStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c>CFv = .text:0x00002DA0; // type:function size:0x10 fn_143_2DB0 = .text:0x00002DB0; // type:function size:0x48 fn_143_2E00 = .text:0x00002E00; // type:function size:0x4C -fn_143_2E50 = .text:0x00002E50; // type:function size:0x85C +timingB__Q214dAcBlastboss_c10callback_cFUlPQ34nw4r3g3d13WorldMtxManipQ34nw4r3g3d6ResMdl = .text:0x00002E50; // type:function size:0x85C initializeState_Fight__14dAcBlastboss_cFv = .text:0x000036B0; // type:function size:0xBC executeState_Fight__14dAcBlastboss_cFv = .text:0x00003770; // type:function size:0x718 finalizeState_Fight__14dAcBlastboss_cFv = .text:0x00003E90; // type:function size:0x4 @@ -80,7 +80,7 @@ fn_143_72E0 = .text:0x000072E0; // type:function size:0x1C fn_143_7300 = .text:0x00007300; // type:function size:0x58 fn_143_7360 = .text:0x00007360; // type:function size:0x50 fn_143_73B0 = .text:0x000073B0; // type:function size:0x10 -fn_143_73C0 = .text:0x000073C0; // type:function size:0x60 +draw__14dAcBlastboss_cFv = .text:0x000073C0; // type:function size:0x60 fn_143_7420 = .text:0x00007420; // type:function size:0x17C fn_143_75A0 = .text:0x000075A0; // type:function size:0x218 fn_143_77C0 = .text:0x000077C0; // type:function size:0x338 @@ -92,10 +92,10 @@ fn_143_9420 = .text:0x00009420; // type:function size:0x148 fn_143_9570 = .text:0x00009570; // type:function size:0x9C fn_143_9610 = .text:0x00009610; // type:function size:0xAF4 fn_143_A110 = .text:0x0000A110; // type:function size:0xBC -fn_143_A1D0 = .text:0x0000A1D0; // type:function size:0x8 -fn_143_A1E0 = .text:0x0000A1E0; // type:function size:0x4 -fn_143_A1F0 = .text:0x0000A1F0; // type:function size:0x4 -fn_143_A200 = .text:0x0000A200; // type:function size:0x8 +vt_0x88__11dAcEnBase_cFi = .text:0x0000A1D0; // type:function size:0x8 +vt_0x84__11dAcEnBase_cFv = .text:0x0000A1E0; // type:function size:0x4 +vt_0x80__11dAcEnBase_cFv = .text:0x0000A1F0; // type:function size:0x4 +getObjectListEntry__11dAcEnBase_cFv = .text:0x0000A200; // type:function size:0x8 __dt__14dAcBlastboss_cFv = .text:0x0000A210; // type:function size:0x398 fn_143_A5B0 = .text:0x0000A5B0; // type:function size:0x4 fn_143_A5C0 = .text:0x0000A5C0; // type:function size:0x4 @@ -119,9 +119,9 @@ initializeState__29sFStateID_c<14dAcBlastboss_c>CFR14dAcBlastboss_c = .text:0x00 __sinit_\d_a_b_lastboss_cpp = .text:0x0000A7C0; // type:function size:0xA90 scope:local __dt__29sFStateID_c<14dAcBlastboss_c>Fv = .text:0x0000B250; // type:function size:0x58 isSameName__29sFStateID_c<14dAcBlastboss_c>CFPCc = .text:0x0000B2B0; // type:function size:0x88 -fn_143_B340 = .text:0x0000B340; // type:function size:0x8 -fn_143_B350 = .text:0x0000B350; // type:function size:0x8 -fn_143_B360 = .text:0x0000B360; // type:function size:0x8 +@272@__dt__15dCcD_Linked_CpsFv = .text:0x0000B340; // type:function size:0x8 +@272@__dt__15dCcD_Linked_SphFv = .text:0x0000B350; // type:function size:0x8 +@272@__dt__15dCcD_Linked_CylFv = .text:0x0000B360; // type:function size:0x8 _ctors = .ctors:0x00000000; // type:label scope:global _dtors = .dtors:0x00000000; // type:label scope:global __destroy_global_chain_reference = .dtors:0x00000000; // type:object size:0x4 scope:global @@ -141,7 +141,14 @@ lbl_143_rodata_1B8 = .rodata:0x000001B8; // type:object size:0x10 align:4 data:f lbl_143_rodata_1C8 = .rodata:0x000001C8; // type:object size:0xC align:4 data:float lbl_143_rodata_1D4 = .rodata:0x000001D4; // type:object size:0x3C align:4 data:float lbl_143_rodata_210 = .rodata:0x00000210; // type:object size:0x90 align:4 data:float -g_profile_B_LASTBOSS = .data:0x00000000; // type:object size:0x1A0 data:4byte +g_profile_B_LASTBOSS = .data:0x00000000; // type:object size:0x10 data:4byte +sSrcCyl1 = .data:0x00000010; // type:object size:0x30 +sSrcCyl2 = .data:0x00000040; // type:object size:0x30 +sSrcCyl3 = .data:0x00000070; // type:object size:0x30 +sSrcSph1 = .data:0x000000A0; // type:object size:0x2C +sSrcSph2 = .data:0x000000CC; // type:object size:0x2C +sSrcSph = .data:0x000000F8; // type:object size:0x2C +lbl_143_data_124 = .data:0x00000124; // type:object size:0x7C lbl_143_data_1A0 = .data:0x000001A0; // type:object size:0x10 data:string lbl_143_data_1B0 = .data:0x000001B0; // type:object size:0x28 lbl_143_data_1D8 = .data:0x000001D8; // type:object size:0x70 @@ -173,23 +180,31 @@ lbl_143_data_480 = .data:0x00000480; // type:object size:0xC data:string lbl_143_data_48C = .data:0x0000048C; // type:object size:0x34 lbl_143_data_4C0 = .data:0x000004C0; // type:object size:0x4 data:4byte lbl_143_data_4C4 = .data:0x000004C4; // type:object size:0x5C data:4byte -lbl_143_data_520 = .data:0x00000520; // type:object size:0x90 -lbl_143_data_5B0 = .data:0x000005B0; // type:object size:0x30 -lbl_143_data_5E0 = .data:0x000005E0; // type:object size:0x30 -lbl_143_data_610 = .data:0x00000610; // type:object size:0x18 -lbl_143_data_628 = .data:0x00000628; // type:object size:0x18 -lbl_143_data_640 = .data:0x00000640; // type:object size:0x70 -lbl_143_data_6B0 = .data:0x000006B0; // type:object size:0x18 -lbl_143_data_6C8 = .data:0x000006C8; // type:object size:0x70 -lbl_143_data_738 = .data:0x00000738; // type:object size:0x10 +__vt__14dAcBlastboss_c = .data:0x00000520; // type:object size:0x90 +__vt__53sFStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c> = .data:0x000005B0; // type:object size:0x30 +__vt__83sStateMgr_c<14dAcBlastboss_c,20sStateMethodUsr_FI_c,12sFStateFct_c,13sStateIDChk_c> = .data:0x000005E0; // type:object size:0x30 +__vt__30sFStateFct_c<14dAcBlastboss_c> = .data:0x00000610; // type:object size:0x18 +__vt__27sFState_c<14dAcBlastboss_c> = .data:0x00000628; // type:object size:0x18 +__vt__15dCcD_Linked_Cyl = .data:0x00000640; // type:object size:0x70 +__vt__Q214dAcBlastboss_c10callback_c = .data:0x000006B0; // type:object size:0x18 +__vt__15dCcD_Linked_Sph = .data:0x000006C8; // type:object size:0x70 +__vt__16dEnemySwordMdl_c = .data:0x00000738; // type:object size:0x10 lbl_143_data_748 = .data:0x00000748; // type:object size:0x70 -lbl_143_data_7B8 = .data:0x000007B8; // type:object size:0x410 -lbl_143_data_BC8 = .data:0x00000BC8; // type:object size:0x34 +__vt__26dSwordSwingEffectProcMgr_c = .data:0x000007B8; // type:object size:0x410 +__vt__29sFStateID_c<14dAcBlastboss_c> = .data:0x00000BC8; // type:object size:0x34 __global_destructor_chain = .bss:0x00000000; // type:object size:0x4 scope:global lbl_143_bss_8 = .bss:0x00000008; // type:object size:0x10 data:4byte -lbl_143_bss_18 = .bss:0x00000018; // type:object size:0x40 data:4byte -lbl_143_bss_58 = .bss:0x00000058; // type:object size:0x80 data:4byte -lbl_143_bss_D8 = .bss:0x000000D8; // type:object size:0x40 data:4byte -lbl_143_bss_118 = .bss:0x00000118; // type:object size:0x40 data:4byte -lbl_143_bss_158 = .bss:0x00000158; // type:object size:0x40 data:4byte -lbl_143_bss_198 = .bss:0x00000198; // type:object size:0x230 data:4byte +StateID_Fight__14dAcBlastboss_c = .bss:0x00000018; // type:object size:0x40 data:4byte +StateID_Guard__14dAcBlastboss_c = .bss:0x00000058; // type:object size:0x40 data:4byte +StateID_GuardBreak__14dAcBlastboss_c = .bss:0x00000098; // type:object size:0x40 data:4byte +StateID_Attack__14dAcBlastboss_c = .bss:0x000000D8; // type:object size:0x40 data:4byte +StateID_CounterAttack__14dAcBlastboss_c = .bss:0x00000118; // type:object size:0x40 data:4byte +StateID_PunchAttack__14dAcBlastboss_c = .bss:0x00000158; // type:object size:0x40 data:4byte +StateID_DashAttack__14dAcBlastboss_c = .bss:0x00000198; // type:object size:0x40 data:4byte +StateID_SmallAttack__14dAcBlastboss_c = .bss:0x000001D8; // type:object size:0x40 data:4byte +StateID_ThunderAttack__14dAcBlastboss_c = .bss:0x00000218; // type:object size:0x40 data:4byte +StateID_Damage__14dAcBlastboss_c = .bss:0x00000258; // type:object size:0x40 data:4byte +StateID_SitDamage__14dAcBlastboss_c = .bss:0x00000298; // type:object size:0x40 data:4byte +StateID_Down__14dAcBlastboss_c = .bss:0x000002D8; // type:object size:0x40 data:4byte +StateID_Stun__14dAcBlastboss_c = .bss:0x00000318; // type:object size:0x40 data:4byte +StateID_ThunderWait__14dAcBlastboss_c = .bss:0x00000358; // type:object size:0x40 data:4byte diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 029135b6..02c56d5e 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -91,8 +91,13 @@ toBeSorted/d_shadow.cpp: .sbss start:0x80575028 end:0x80575038 .sdata2 start:0x80576A78 end:0x80576B08 -toBeSorted/d_unk_mdl_stuff_1.cpp: - .text start:0x8001BFA0 end:0x8001E444 align:16 +toBeSorted/d_sword_swing_effect.cpp: + .text start:0x8001BFA0 end:0x8001CB9C align:16 + .data start:0x80500AF0 end:0x80500B48 + .sdata2 start:0x80576B08 end:0x80576B28 + +toBeSorted/d_unk_mdl_stuff_3.cpp: + .text start:0x8001CBA0 end:0x8001E444 align:16 .ctors start:0x804DB654 end:0x804DB658 .sbss start:0x80575038 end:0x80575058 @@ -396,11 +401,14 @@ toBeSorted/actor_info.cpp: .rodata start:0x804E0FA8 end:0x804E3418 .sdata2 start:0x805779F8 end:0x80579210 -toBeSorted/unk_vec_math.cpp: - .text start:0x8006A8D0 end:0x8006B3A4 align:16 +toBeSorted/d_sword_swing_effect_mgr.cpp: + .text start:0x8006A8D0 end:0x8006B3C0 align:16 + .sdata2 start:0x80579210 end:0x80579230 -toBeSorted/unk_mdl_cc.cpp: - .text start:0x8006B3B0 end:0x8006BBD4 align:16 +toBeSorted/d_enemy_sword_mdl.cpp: + .text start:0x8006B3C0 end:0x8006BBD4 align:16 + .data start:0x8050E060 end:0x8050E090 + .sdata2 start:0x80579230 end:0x80579238 toBeSorted/d_camera.cpp: .text start:0x8006BBE0 end:0x80083370 align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 34c5cbef..9bc3f409 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -657,20 +657,20 @@ fn_8001BE90 = .text:0x8001BE90; // type:function size:0x60 fn_8001BEF0 = .text:0x8001BEF0; // type:function size:0x58 fn_8001BF50 = .text:0x8001BF50; // type:function size:0x40 fn_8001BF90 = .text:0x8001BF90; // type:function size:0x4 -fn_8001BFA0 = .text:0x8001BFA0; // type:function size:0x54 -fn_8001C000 = .text:0x8001C000; // type:function size:0x40 -fn_8001C040 = .text:0x8001C040; // type:function size:0x30C -fn_8001C350 = .text:0x8001C350; // type:function size:0x14 -fn_8001C370 = .text:0x8001C370; // type:function size:0x44 -fn_8001C3C0 = .text:0x8001C3C0; // type:function size:0xCC -fn_8001C490 = .text:0x8001C490; // type:function size:0x18 -fn_8001C4B0 = .text:0x8001C4B0; // type:function size:0x78 -fn_8001C530 = .text:0x8001C530; // type:function size:0x94 -fn_8001C5D0 = .text:0x8001C5D0; // type:function size:0x3E4 -fn_8001C9C0 = .text:0x8001C9C0; // type:function size:0x60 -fn_8001CA20 = .text:0x8001CA20; // type:function size:0x7C -fn_8001CAA0 = .text:0x8001CAA0; // type:function size:0x80 -fn_8001CB20 = .text:0x8001CB20; // type:function size:0x7C +remove__27dSwordSwingEffectProcBase_cFv = .text:0x8001BFA0; // type:function size:0x54 +__dt__Q227dSwordSwingEffectProcBase_c11swing_entryFv = .text:0x8001C000; // type:function size:0x40 +drawXlu__27dSwordSwingEffectProcBase_cFv = .text:0x8001C040; // type:function size:0x30C +hasSwings__27dSwordSwingEffectProcBase_cCFv = .text:0x8001C350; // type:function size:0x14 +entry__27dSwordSwingEffectProcBase_cFv = .text:0x8001C370; // type:function size:0x44 +create__27dSwordSwingEffectProcBase_cFlP12mAllocator_c = .text:0x8001C3C0; // type:function size:0xCC +__ct__Q227dSwordSwingEffectProcBase_c11swing_entryFv = .text:0x8001C490; // type:function size:0x18 +addSwing__27dSwordSwingEffectProcBase_cFRC7mVec3_c6mColorRC7mVec3_c6mColor = .text:0x8001C4B0; // type:function size:0x78 +calc__27dSwordSwingEffectProcBase_cFf = .text:0x8001C530; // type:function size:0x94 +drawXlu__23dSwordSwingEffectProc_cFv = .text:0x8001C5D0; // type:function size:0x3E4 +create__23dSwordSwingEffectProc_cFlP12mAllocator_cPQ23EGG7ResTIMGf = .text:0x8001C9C0; // type:function size:0x60 +set__Q227dSwordSwingEffectProcBase_c11swing_entryFRC7mVec3_c6mColorRC7mVec3_c6mColor = .text:0x8001CA20; // type:function size:0x7C +__dt__23dSwordSwingEffectProc_cFv = .text:0x8001CAA0; // type:function size:0x80 +__dt__27dSwordSwingEffectProcBase_cFv = .text:0x8001CB20; // type:function size:0x7C fn_8001CBA0 = .text:0x8001CBA0; // type:function size:0x20C fn_8001CDB0 = .text:0x8001CDB0; // type:function size:0x308 fn_8001D0C0 = .text:0x8001D0C0; // type:function size:0x35C @@ -1134,7 +1134,7 @@ fn_8002EA60 = .text:0x8002EA60; // type:function size:0xD0 fn_8002EB30 = .text:0x8002EB30; // type:function size:0x5C ActorObjectBase__putInODesert = .text:0x8002EB90; // type:function size:0xD8 drawModelType1__12dAcObjBase_cFPQ23m3d6smdl_c = .text:0x8002EC70; // type:function size:0x60 -fn_8002ECD0 = .text:0x8002ECD0; // type:function size:0x50 +fn_8002ECD0__12dAcObjBase_cFPQ23m3d6smdl_ci = .text:0x8002ECD0; // type:function size:0x50 fn_8002ED20 = .text:0x8002ED20; // type:function size:0x88 fn_8002edb0__12dAcObjBase_cFRQ23m3d15mShadowCircle_cRQ23m3d6smdl_cPC7mQuat_cllf = .text:0x8002EDB0; // type:function size:0x8C drawShadow__12dAcObjBase_cFRQ23m3d15mShadowCircle_cPvRC6mMtx_cPC7mQuat_clllllf = .text:0x8002EE40; // type:function size:0xFC @@ -1146,7 +1146,7 @@ createInsectActor__12dAcObjBase_cFP9dAcBase_cQ28fProfile14PROFILE_NAME_eUlP7mVec createActorUnkGroup3__12dAcObjBase_cFQ28fProfile14PROFILE_NAME_eUlUlP7mVec3_cP7mAng3_cP7mVec3_cUl = .text:0x8002F1C0; // type:function size:0x98 createActorUnkGroup3__12dAcObjBase_cFPCcUlUlPC7mVec3_cPC7mAng3_cPC7mVec3_cUlUsSc = .text:0x8002F260; // type:function size:0xA0 __ct__11dAcEnBase_cFv = .text:0x8002F300; // type:function size:0x74 -ActorEnemyBase__dtor = .text:0x8002F380; // type:function size:0x74 +__dt__11dAcEnBase_cFv = .text:0x8002F380; // type:function size:0x74 ActorEnemyBase__shouldUpdateMaybe = .text:0x8002F400; // type:function size:0xB4 ActorEnemyBase__postUpdate = .text:0x8002F4C0; // type:function size:0x7C ActorEnemyBase__preDraw = .text:0x8002F540; // type:function size:0x74 @@ -3046,14 +3046,14 @@ getNameForProfileId__FUl = .text:0x8006A670; // type:function size:0xB8 getActorName__FPC9ActorInfo = .text:0x8006A730; // type:function size:0x18 getActorInfoByProfileAndSubtype__FUlUl = .text:0x8006A750; // type:function size:0x134 getSoundSourceTypeForName__FPCc = .text:0x8006A890; // type:function size:0x38 -fn_8006A8D0 = .text:0x8006A8D0; // type:function size:0x1DC -fn_8006AAB0 = .text:0x8006AAB0; // type:function size:0x85C -fn_8006B310 = .text:0x8006B310; // type:function size:0x94 -fn_8006B3B0 = .text:0x8006B3B0; // type:function size:0x10 -fn_8006B3C0 = .text:0x8006B3C0; // type:function size:0x140 -fn_8006B500 = .text:0x8006B500; // type:function size:0x13C -fn_8006B640 = .text:0x8006B640; // type:function size:0x20 -fn_8006B660 = .text:0x8006B660; // type:function size:0xB4 +fn_8006A8D0__FRC7mVec2_cRC7mVec2_cRC7mVec2_cRC7mVec2_cR7mVec2_c = .text:0x8006A8D0; // type:function size:0x1DC +createSwingEntries__26dSwordSwingEffectProcMgr_cFRC7mVec3_cRC7mVec3_c = .text:0x8006AAB0; // type:function size:0x85C +calc__26dSwordSwingEffectProcMgr_cFRC7mVec3_cRC7mVec3_c = .text:0x8006B310; // type:function size:0x94 +entry__26dSwordSwingEffectProcMgr_cFv = .text:0x8006B3B0; // type:function size:0x10 +create__16dEnemySwordMdl_cFP12mAllocator_cPvPCcUlRC7mVec3_cRC7mVec3_cR9cCcD_SttsPQ23EGG7ResTIMGiPUl = .text:0x8006B3C0; // type:function size:0x140 +create__16dEnemySwordMdl_cFP12mAllocator_cQ34nw4r3g3d7ResFilePCcUlRC7mVec3_cRC7mVec3_cR9cCcD_SttsPQ23EGG7ResTIMGiPUl = .text:0x8006B500; // type:function size:0x13C +fn_8006B640__16dEnemySwordMdl_cFv = .text:0x8006B640; // type:function size:0x20 +fn_8006B660__16dEnemySwordMdl_cFiiiiiiiiif = .text:0x8006B660; // type:function size:0xB4 fn_8006B720 = .text:0x8006B720; // type:function size:0x10 fn_8006B730 = .text:0x8006B730; // type:function size:0x5C fn_8006B790 = .text:0x8006B790; // type:function size:0x10 @@ -3061,8 +3061,8 @@ fn_8006B7A0 = .text:0x8006B7A0; // type:function size:0x5C fn_8006B800 = .text:0x8006B800; // type:function size:0x10 fn_8006B810 = .text:0x8006B810; // type:function size:0x5C fn_8006B870 = .text:0x8006B870; // type:function size:0x10 -fn_8006B880 = .text:0x8006B880; // type:function size:0x2A8 -fn_8006BB30 = .text:0x8006BB30; // type:function size:0xA4 +calc__16dEnemySwordMdl_cFRC6mMtx_cRC7mVec3_cb = .text:0x8006B880; // type:function size:0x2A8 +entry__16dEnemySwordMdl_cFP12dAcObjBase_cP15dShadowCircle_cP7mQuat_c = .text:0x8006BB30; // type:function size:0xA4 fn_8006BBE0 = .text:0x8006BBE0; // type:function size:0x70 fn_8006BC50 = .text:0x8006BC50; // type:function size:0x18 fn_8006BC70 = .text:0x8006BC70; // type:function size:0xA8 @@ -29953,8 +29953,8 @@ __vt__Q23d3d13AnmMdlWrapper = .data:0x80500A20; // type:object size:0x50 @15227 = .data:0x80500AA8; // type:object size:0x10 scope:local data:string __vt__14dScnCallback_c = .data:0x80500AB8; // type:object size:0x20 lbl_80500AD8 = .data:0x80500AD8; // type:object size:0x18 -lbl_80500AF0 = .data:0x80500AF0; // type:object size:0x2C -lbl_80500B1C = .data:0x80500B1C; // type:object size:0x2C +__vt__23dSwordSwingEffectProc_c = .data:0x80500AF0; // type:object size:0x2C +__vt__27dSwordSwingEffectProcBase_c = .data:0x80500B1C; // type:object size:0x2C lbl_80500B48 = .data:0x80500B48; // type:object size:0xA data:string lbl_80500B54 = .data:0x80500B54; // type:object size:0xA data:string lbl_80500B60 = .data:0x80500B60; // type:object size:0x40 @@ -42661,7 +42661,7 @@ l_lightMgr_pp__Q23m3d8internal = .sbss:0x80575BDC; // type:object size:0x4 data: l_numFogMgr__Q23m3d8internal = .sbss:0x80575BE0; // type:object size:0x4 data:4byte l_fogMgr_pp__Q23m3d8internal = .sbss:0x80575BE4; // type:object size:0x4 data:4byte l_alignment__Q23m3d8internal = .sbss:0x80575BE8; // type:object size:0x4 data:4byte -lbl_80575BF0 = .sbss:0x80575BF0; // type:object size:0x4 data:4byte +sInstance__Q23m3d9mShadow_c = .sbss:0x80575BF0; // type:object size:0x4 data:4byte lbl_80575BF4 = .sbss:0x80575BF4; // type:object size:0x4 data:4byte lbl_80575BF8 = .sbss:0x80575BF8; // type:object size:0x4 data:4byte @GUARD@draw__Q23m3d15mCustomShadow_cFRC6mMtx_c@nullMat = .sbss:0x80575BFC; // type:object size:0x1 data:byte diff --git a/configure.py b/configure.py index 51409cd2..86ce4cf8 100644 --- a/configure.py +++ b/configure.py @@ -427,7 +427,8 @@ config.libs = [ ), Object(NonMatching, "toBeSorted/d_unk_proc.cpp"), Object(NonMatching, "toBeSorted/d_shadow.cpp"), - Object(NonMatching, "toBeSorted/d_unk_mdl_stuff_1.cpp"), + Object(Matching, "toBeSorted/d_sword_swing_effect.cpp"), + Object(NonMatching, "toBeSorted/d_unk_mdl_stuff_3.cpp"), Object(NonMatching, "toBeSorted/d_unk_mdl_stuff_2.cpp"), Object(Matching, "d/d_light_env.cpp"), Object(NonMatching, "toBeSorted/d_emitter.cpp"), @@ -481,8 +482,8 @@ config.libs = [ Object(Matching, "toBeSorted/arc_managers/layout_arc_manager.cpp"), Object(NonMatching, "toBeSorted/arc_managers/layout_arc_control.cpp"), Object(Matching, "toBeSorted/actor_info.cpp"), - Object(NonMatching, "toBeSorted/unk_vec_math.cpp"), - Object(NonMatching, "toBeSorted/unk_mdl_cc.cpp"), + Object(NonMatching, "toBeSorted/d_sword_swing_effect_mgr.cpp"), + Object(NonMatching, "toBeSorted/d_enemy_sword_mdl.cpp"), Object(NonMatching, "toBeSorted/d_camera.cpp"), Object(NonMatching, "toBeSorted/d_event_1.cpp"), Object(NonMatching, "toBeSorted/unk_map_cam.cpp"), diff --git a/include/d/a/b/d_a_b_lastboss.h b/include/d/a/b/d_a_b_lastboss.h index 1d01a3f3..7cc03e8f 100644 --- a/include/d/a/b/d_a_b_lastboss.h +++ b/include/d/a/b/d_a_b_lastboss.h @@ -2,14 +2,60 @@ #define D_A_B_LASTBOSS_H #include "d/a/e/d_a_en_base.h" +#include "d/d_cc.h" +#include "d/d_light_env.h" +#include "m/m3d/m_anmmatclr.h" +#include "m/m3d/m_anmtexsrt.h" +#include "m/m3d/m_mdl.h" +#include "m/m3d/m_smdl.h" #include "s/s_State.hpp" -#include "s/s_StateMgr.hpp" +#include "toBeSorted/d_emitter.h" +#include "toBeSorted/d_enemy_sword_mdl.h" +#include "toBeSorted/stage_render_stuff.h" + +class dTgSwordBattleGame_c; + +// TODO this might be a template but what about the offset? +struct UnkLastBossCcSph1 { + /* 0x000 */ u8 _0x000[0x008 - 0x000]; + /* 0x008 */ mVec3_c field_0x008[5]; + /* 0x044 */ mVec3_c field_0x044[5]; + /* 0x080 */ mVec3_c field_0x080[5]; + /* 0x0BC */ dCcD_Linked_Sph mCc; +}; + +struct UnkLastBossCcSph2 { + /* 0x000 */ s16 field_0x000; + /* 0x002 */ s16 field_0x002; + /* 0x004 */ u8 _0x004[0x008 - 0x004]; + /* 0x008 */ s16 field_0x008; + /* 0x00A */ u8 _0x00A[0x014 - 0x00A]; + /* 0x014 */ mVec3_c field_0x014[10]; + /* 0x08C */ mVec3_c field_0x08C[10]; + /* 0x104 */ mVec3_c field_0x104[10]; + /* 0x17C */ dCcD_Linked_Sph mCc; +}; class dAcBlastboss_c : public dAcEnBase_c { + class callback_c : public m3d::callback_c { + public: + virtual void timingB(u32, nw4r::g3d::WorldMtxManip *, nw4r::g3d::ResMdl) override; + + /* 0x04 */ s16 field_0x04; + /* 0x06 */ u8 _0x06[0x34 - 0x06]; + /* 0x34 */ dAcBlastboss_c *mpOwner; + }; + public: - dAcBlastboss_c() : mStateMgr(*this, sStateID::null) {} + dAcBlastboss_c() : mStateMgr(*this, sStateID::null), mScnCallback(this) {} virtual ~dAcBlastboss_c() {} + virtual bool createHeap() override; + int create() override; + int doDelete() override; + int actorExecute() override; + int draw() override; + STATE_FUNC_DECLARE(dAcBlastboss_c, Fight); STATE_FUNC_DECLARE(dAcBlastboss_c, Guard); STATE_FUNC_DECLARE(dAcBlastboss_c, GuardBreak); @@ -26,7 +72,127 @@ public: STATE_FUNC_DECLARE(dAcBlastboss_c, ThunderWait); private: - /* 0x??? */ STATE_MGR_DECLARE(dAcBlastboss_c); + void fn_143_6720(); + void fn_143_A110(s32); + void fn_143_7B00(); + + /* 0x0378 */ d3d::AnmMdlWrapper mMdl; + /* 0x03E8 */ m3d::anmTexSrt_c mAnmTexSrt; + /* 0x0414 */ m3d::anmMatClr_c mAnmMatClr1; + /* 0x0440 */ m3d::smdl_c mThunderMdl; + /* 0x045C */ m3d::anmMatClr_c mThunderAnmMatClr; + /* 0x0488 */ callback_c mMdlCallback; + /* 0x04C0 */ dCcD_Linked_Cyl mCc1; + /* 0x0620 */ dCcD_Linked_Cyl mCc2; + /* 0x0780 */ dCcD_Linked_Cyl mCc3; + /* 0x08E0 */ dCcD_Linked_Sph mCc4; + /* 0x0A40 */ dCcD_Linked_Sph mCc5; + /* 0x0BA0 */ dScnCallback_c mScnCallback; + /* 0x0BAC */ STATE_MGR_DECLARE(dAcBlastboss_c); + /* 0x0BE8 */ dColliderLinkedList mCcList; + /* 0x0BF4 */ dEnemySwordMdl_c mSwordMdl; + + /* 0x1130 */ u8 field_0x1130; + /* 0x1131 */ u8 field_0x1131; + /* 0x1132 */ u8 field_0x1132; + /* 0x1133 */ u8 field_0x1133; + + /* 0x1134 */ u8 _0x1134[0x113D - 0x1134]; + + /* 0x113D */ u8 field_0x113D; + /* 0x113E */ u8 field_0x113E; + /* 0x113F */ u8 field_0x113F; + /* 0x1140 */ u8 field_0x1140; + /* 0x1141 */ u8 field_0x1141; + /* 0x1142 */ u8 field_0x1142; + /* 0x1143 */ u8 field_0x1143; + /* 0x1144 */ u8 field_0x1144; + /* 0x1145 */ u8 field_0x1145; + /* 0x1146 */ bool mIsSwordEmpowered; + + /* 0x1147 */ u8 _0x1147[0x114B - 0x1147]; + + /* 0x114B */ u8 field_0x114B; + /* 0x114C */ u8 field_0x114C; + /* 0x114D */ u8 field_0x114D; + /* 0x114E */ u8 field_0x114E; + /* 0x114F */ u8 field_0x114F; + + /* 0x1150 */ u8 _0x1150[0x1156 - 0x1150]; + + /* 0x1156 */ u16 field_0x1156; + /* 0x1158 */ u16 field_0x1158; + /* 0x115A */ u16 field_0x115A; + /* 0x115C */ u16 field_0x115C; + /* 0x115E */ u16 field_0x115E; + /* 0x1160 */ u16 field_0x1160; + + /* 0x1162 */ u8 _0x1162[0x1164 - 0x1162]; + + /* 0x1164 */ s16 field_0x1164; + + /* 0x1166 */ u8 _0x1166[0x116A - 0x1166]; + + /* 0x116A */ s16 field_0x116A; + + /* 0x116C */ u8 _0x116C[0x117C - 0x116C]; + + /* 0x117C */ s16 field_0x117C; + + /* 0x1186 */ u8 _0x117E[0x1186 - 0x117E]; + + /* 0x1186 */ s16 field_0x1186; + + /* 0x1188 */ u8 _0x1188[0x1190 - 0x1188]; + + /* 0x1190 */ f32 field_0x1190; + + /* 0x1194 */ u8 _0x1194[0x119C - 0x1194]; + + /* 0x119C */ f32 field_0x119C; + /* 0x11A0 */ f32 field_0x11A0; + /* 0x11A4 */ f32 field_0x11A4; + + /* 0x11A8 */ u8 _0x11A8[0x11B0 - 0x11A8]; + + /* 0x11B0 */ f32 field_0x11B0; + + /* 0x11B4 */ u8 _0x11B4[0x11BC - 0x11B4]; + + /* 0x11BC */ f32 field_0x11BC; + /* 0x11C0 */ f32 field_0x11C0; + + /* 0x11C4 */ u8 _0x11C4[0x11D4 - 0x11C4]; + + /* 0x11D4 */ s32 field_0x11D4; + /* 0x11D8 */ s32 field_0x11D8; + + /* 0x11DC */ u8 _0x11DC[0x11E4 - 0x11DC]; + + /* 0x11E4 */ mVec3_c field_0x11E4; + /* 0x11F0 */ mVec3_c field_0x11F0; + /* 0x11FC */ mVec3_c field_0x11FC; + /* 0x1208 */ mVec3_c field_0x1208; + + /* 0x1214 */ u8 _0x1214[0x1238 - 0x1214]; + + /* 0x1238 */ mVec3_c field_0x1238[2]; + /* 0x1250 */ mVec3_c field_0x1250[2]; + + /* 0x1268 */ UnkLastBossCcSph2 field_0x1260[8]; + /* 0x2948 */ UnkLastBossCcSph1 field_0x2948[1]; + + /* 0x2B64 */ dEmitter_c mEmitter1; + /* 0x2B98 */ dEmitter_c mEmitter2; + /* 0x2BCC */ dEmitter_c mEmitter3; + /* 0x2C00 */ dEmitter_c mEmitter4; + /* 0x2C34 */ dEmitter_c mEmitter5; + /* 0x2C68 */ dEmitter_c mEmitter6; + /* 0x2C9C */ dEmitter_c mEmitter7; + /* 0x2CD0 */ LIGHT_INFLUENCE mLightInfo; + /* 0x2CEC */ u16 field_0x2CEC; + /* 0x2CEE */ u8 _0x2CEE[0x2D20 - 0x2CEE]; + /* 0x2D20 */ dTgSwordBattleGame_c *mpSwordBattleGame; }; #endif diff --git a/include/d/a/obj/d_a_obj_base.h b/include/d/a/obj/d_a_obj_base.h index 6b798af5..a61a4b23 100644 --- a/include/d/a/obj/d_a_obj_base.h +++ b/include/d/a/obj/d_a_obj_base.h @@ -197,6 +197,7 @@ public: void fn_8002EA60(void *); void fn_8002EB30(void *); void putInODesert(f32 depth, mVec3_c *position); + void fn_8002ECD0(m3d::smdl_c *smdl, UNKWORD); // Disabling makes Items and Link Disappear void drawModelType1(m3d::smdl_c *smdl); // Disabling make Lava and other objects Disappear @@ -220,11 +221,11 @@ public: fProfile::PROFILE_NAME_e actorId, u32 params1, mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, u32 params2, u32 roomId ); - + // These may not belong here - static dAcBase_c* createInsectActor( - dAcBase_c* parent, - fProfile::PROFILE_NAME_e actorId, u32 params1, mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, u32 params2, s32 roomId + static dAcBase_c *createInsectActor( + dAcBase_c *parent, fProfile::PROFILE_NAME_e actorId, u32 params1, mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, + u32 params2, s32 roomId ); static dAcBase_c *createActorUnkGroup3( fProfile::PROFILE_NAME_e actorId, u32 roomId, u32 params1, mVec3_c *pos, mAng3_c *rot, mVec3_c *scale, @@ -243,6 +244,15 @@ public: if (!result) \ return result; \ } while (0) + +// Actors' createHeap functions often have patterns that can be matched with this macro +#define TRY_CREATE2(thing) \ + do { \ + result = (thing); \ + if (!result) \ + return result; \ + } while (0) + // Use this in actors' create functions #define CREATE_ALLOCATOR(className) \ do { \ diff --git a/include/d/col/cc/d_cc_d.h b/include/d/col/cc/d_cc_d.h index 88dff6b7..4af5b6ff 100644 --- a/include/d/col/cc/d_cc_d.h +++ b/include/d/col/cc/d_cc_d.h @@ -18,6 +18,7 @@ public: virtual cCcD_ShapeAttr *GetShapeAttr() override; using cM3dGCps::Set; + using cM3dGLin::Set; void Set(const dCcD_SrcCps &src); void unknownCalc(); }; diff --git a/include/d/d_cc.h b/include/d/d_cc.h index c5349190..ddc9803e 100644 --- a/include/d/d_cc.h +++ b/include/d/d_cc.h @@ -27,15 +27,14 @@ public: /* 0x210 */ LinkedColliderNode mNode; }; -class dCcD_Linked_Cyl : public dCcD_Cyl { +class dCcD_Linked_Cps : public dCcD_Cps { public: - dCcD_Linked_Cyl() : mNode(this) {} - virtual ~dCcD_Linked_Cyl() { + dCcD_Linked_Cps() : mNode(this) {} + virtual ~dCcD_Linked_Cps() { mNode.remove(); } - /* 0x150 */ LinkedColliderNode mNode; + /* 0x170 */ LinkedColliderNode mNode; }; - class dCcD_Linked_Sph : public dCcD_Sph { public: dCcD_Linked_Sph() : mNode(this) {} @@ -44,14 +43,13 @@ public: } /* 0x150 */ LinkedColliderNode mNode; }; - -class dCcD_Linked_Cps : public dCcD_Cps { +class dCcD_Linked_Cyl : public dCcD_Cyl { public: - dCcD_Linked_Cps() : mNode(this) {} - virtual ~dCcD_Linked_Cps() { + dCcD_Linked_Cyl() : mNode(this) {} + virtual ~dCcD_Linked_Cyl() { mNode.remove(); } - /* 0x170 */ LinkedColliderNode mNode; + /* 0x150 */ LinkedColliderNode mNode; }; class dColliderLinkedList { diff --git a/include/d/d_sc_game.h b/include/d/d_sc_game.h index b1ba5573..67bbddb4 100644 --- a/include/d/d_sc_game.h +++ b/include/d/d_sc_game.h @@ -172,6 +172,10 @@ public: sUpdateFrameCount = 0; } + static u32 getUpdateFrameCount() { + return sUpdateFrameCount; + } + bool savePromptFlag() const { return mSavePromptFlag; } diff --git a/include/toBeSorted/d_enemy_sword_mdl.h b/include/toBeSorted/d_enemy_sword_mdl.h new file mode 100644 index 00000000..33527979 --- /dev/null +++ b/include/toBeSorted/d_enemy_sword_mdl.h @@ -0,0 +1,59 @@ +#ifndef D_ENEMY_SWORD_MDL_H +#define D_ENEMY_SWORD_MDL_H + +#include "common.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/d_cc.h" +#include "d/d_shadow.h" +#include "egg/gfx/eggTexture.h" +#include "m/m3d/m_smdl.h" +#include "m/m_allocator.h" +#include "m/m_mtx.h" +#include "m/m_quat.h" +#include "m/m_vec.h" +#include "nw4r/types_nw4r.h" +#include "toBeSorted/d_sword_swing_effect_mgr.h" + +class dEnemySwordMdl_c { +public: + /* 0x000 */ m3d::smdl_c mMdl; + /* 0x01C */ dSwordSwingEffectProcMgr_c mProc; + +private: + /* 0x070 */ bool field_0x070; + /* 0x071 */ bool field_0x071; + /* 0x074 */ mVec3_c field_0x074; + /* 0x080 */ mVec3_c field_0x080; + /* 0x08C */ mVec3_c field_0x08C; + /* 0x098 */ mVec3_c field_0x098; + /* 0x0A4 */ f32 field_0x0A4; + /* 0x0A8 */ f32 field_0x0A8; + /* 0x0AC */ dCcD_Linked_Cps mCcs[3]; + /* 0x52C */ dColliderLinkedList mCcList; + +public: + dEnemySwordMdl_c() {} + virtual ~dEnemySwordMdl_c() {} + + bool create( + mAllocator_c *alloc, void *pData, const char *mdlName, u32 bufferOption, const mVec3_c &v1, const mVec3_c &v2, + cCcD_Stts &stts, EGG::ResTIMG *pImg, int nView, u32 *pSize + ); + bool create( + mAllocator_c *alloc, nw4r::g3d::ResFile resFile, const char *mdlName, u32 bufferOption, const mVec3_c &v1, + const mVec3_c &v2, cCcD_Stts &stts, EGG::ResTIMG *pImg, int nView, u32 *pSize + ); + + void calc(const mMtx_c &mtx, const mVec3_c &v1, bool mass); + bool entry(dAcObjBase_c *obj, dShadowCircle_c *shadow, mQuat_c *quat); + + void fn_8006B640(); + void fn_8006B660(UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, UNKWORD, f32); + + void setAttackActive(bool b) { + field_0x070 = b; + mProc.setActive(false); + } +}; + +#endif diff --git a/include/toBeSorted/d_sword_swing_effect.h b/include/toBeSorted/d_sword_swing_effect.h new file mode 100644 index 00000000..1a97f0cd --- /dev/null +++ b/include/toBeSorted/d_sword_swing_effect.h @@ -0,0 +1,65 @@ +#ifndef D_SWORD_SWING_EFFECT_H +#define D_SWORD_SWING_EFFECT_H + +#include "common.h" +#include "egg/gfx/eggTexture.h" +#include "m/m3d/m_proc.h" +#include "m/m_allocator.h" +#include "m/m_color.h" +#include "m/m_vec.h" + +class dSwordSwingEffectProcBase_c : public m3d::proc_c { +protected: + struct swing_entry { + swing_entry() { + mLifetime = 0.0f; + } + ~swing_entry() {} + + void set(const mVec3_c &pos1, const mColor &c1, const mVec3_c &pos2, const mColor &c2); + + /* 0x00 */ f32 mLifetime; + /* 0x04 */ mVec3_c mv1; + /* 0x10 */ mVec3_c mv2; + /* 0x1C */ mColor mc1; + /* 0x20 */ mColor mc2; + }; + +public: + dSwordSwingEffectProcBase_c() : mpEntries(nullptr), mCount(0), mHead(0) {} + virtual ~dSwordSwingEffectProcBase_c() { + remove(); + } + + virtual int entry() override; + virtual void remove() override; + virtual void drawXlu() override; + + bool create(s32 num, mAllocator_c *alloc); + void addSwing(const mVec3_c &pos1, const mColor c1, const mVec3_c &pos2, const mColor c2); + void calc(f32 f); + +protected: + bool hasSwings() const; + + /* 0x18 */ swing_entry *mpEntries; + /* 0x1C */ u16 mNum; + /* 0x1E */ u16 mCount; + /* 0x20 */ u16 mHead; +}; + +class dSwordSwingEffectProc_c : public dSwordSwingEffectProcBase_c { +public: + dSwordSwingEffectProc_c() : mpImg(nullptr) {} + virtual ~dSwordSwingEffectProc_c() {} + + virtual void drawXlu() override; + + bool create(s32 num, mAllocator_c *alloc, EGG::ResTIMG *pImg, f32 scale); + +private: + /* 0x24 */ EGG::ResTIMG *mpImg; + /* 0x28 */ f32 mTexScale; +}; + +#endif diff --git a/include/toBeSorted/d_sword_swing_effect_mgr.h b/include/toBeSorted/d_sword_swing_effect_mgr.h new file mode 100644 index 00000000..e14600ad --- /dev/null +++ b/include/toBeSorted/d_sword_swing_effect_mgr.h @@ -0,0 +1,43 @@ +#ifndef D_SWORD_SWING_EFFECT_MGR_H +#define D_SWORD_SWING_EFFECT_MGR_H + +#include "m/m_color.h" +#include "m/m_vec.h" +#include "toBeSorted/d_sword_swing_effect.h" + +// TODO better name +class dSwordSwingEffectProcMgr_c { +private: + /* 0x00 */ dSwordSwingEffectProc_c mProc; + /* 0x2C */ bool mIsActive; + /* 0x30 */ mColor mC1; + /* 0x34 */ mColor mC2; + /* 0x38 */ mVec3_c field_0x38; + /* 0x44 */ mVec3_c field_0x44; + + void createSwingEntries(const mVec3_c &v1, const mVec3_c &v2); + +public: + dSwordSwingEffectProcMgr_c() : mC1(0xFF, 0xFF, 0xFF, 0x40), mC2(0xFF, 0xFF, 0xFF, 0x20) {} + virtual ~dSwordSwingEffectProcMgr_c() {} + + void setColor1(mColor c1) { + mC1 = c1; + } + + void setColor2(mColor c1) { + mC2 = c1; + } + + void setActive(bool v) { + mIsActive = v; + } + + bool create(s32 num, mAllocator_c *alloc, EGG::ResTIMG *pImg, f32 scale) { + return mProc.create(num, alloc, pImg, scale); + } + void calc(const mVec3_c &v1, const mVec3_c &v2); + void entry(); +}; + +#endif diff --git a/src/REL/d/a/b/d_a_b_lastboss.cpp b/src/REL/d/a/b/d_a_b_lastboss.cpp index af5d73b5..f19e8390 100644 --- a/src/REL/d/a/b/d_a_b_lastboss.cpp +++ b/src/REL/d/a/b/d_a_b_lastboss.cpp @@ -1,5 +1,27 @@ #include "d/a/b/d_a_b_lastboss.h" +#include "c/c_lib.h" +#include "c/c_math.h" +#include "common.h" +#include "d/a/d_a_player.h" +#include "d/a/obj/d_a_obj_base.h" +#include "d/d_base.h" +#include "d/d_light_env.h" +#include "d/d_sc_game.h" +#include "d/snd/d_snd_wzsound.h" +#include "d/t/d_t_sword_battle_game.h" +#include "f/f_base.h" +#include "f/f_manager.h" +#include "f/f_profile_name.h" +#include "m/m3d/m_fanm.h" +#include "m/m_mtx.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" +#include "s/s_Math.h" +#include "toBeSorted/d_emitter.h" +#include "toBeSorted/minigame_mgr.h" + SPECIAL_ACTOR_PROFILE(B_LASTBOSS, dAcBlastboss_c, fProfile::B_LASTBOSS, 0xBA, 0, 0); STATE_DEFINE(dAcBlastboss_c, Fight); @@ -17,6 +39,421 @@ STATE_DEFINE(dAcBlastboss_c, Down); STATE_DEFINE(dAcBlastboss_c, Stun); STATE_DEFINE(dAcBlastboss_c, ThunderWait); +static dCcD_SrcCyl sSrcCyl1 = { + /* mObjInf */ + {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ + {~(AT_TYPE_BUGNET | AT_TYPE_0x80000 | AT_TYPE_BELLOWS | AT_TYPE_BEETLE | AT_TYPE_WIND | AT_TYPE_0x8000), + 0x4103, + {0, 0x4, 0x407}, + 0x0, + 0x0}, + /* mObjCo */ {0x0}}, + /* mCylInf */ + {40.f, 300.f} +}; + +static dCcD_SrcCyl sSrcCyl2 = { + /* mObjInf */ + {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ + {AT_TYPE_BELLOWS, 0x103, {0, 0x4, 0x407}, 0x0, 0x0}, + /* mObjCo */ {0x0}}, + /* mCylInf */ + {70.f, 30.f} +}; + +static dCcD_SrcCyl sSrcCyl3 = { + /* mObjInf */ + {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ + {0x0, 0x0, {0, 0x0, 0x407}, 0x0, 0x0}, + /* mObjCo */ {0xE5}}, + /* mCylInf */ + {100.f, 250.f} +}; + +static dCcD_SrcSph sSrcSph1 = { + /* mObjInf */ + {/* mObjAt */ {AT_TYPE_DAMAGE, 0x2008D, {0, 0, 0}, 4, 0, 0, 0, 0, 0}, + /* mObjTg */ + {0, 0, {0, 0x0, 0x407}, 0, 0}, + /* mObjCo */ {0}}, + /* mSphInf */ + {100.0f} +}; + +static dCcD_SrcSph sSrcSph2 = { + /* mObjInf */ + {/* mObjAt */ {AT_TYPE_DAMAGE, 0x22008D, {0, 0, 4}, 8, 0, 0, 0, 0, 0}, + /* mObjTg */ + {AT_TYPE_0x800000 | AT_TYPE_BUGNET, 0x103, {0, 0x19, 0x407}, 0, 0}, + /* mObjCo */ {0}}, + /* mSphInf */ + {100.0f} +}; + +static dCcD_SrcSph sSrcSph = { + /* mObjInf */ + {/* mObjAt */ {0, 0, {0, 0, 0}, 0, 0, 0, 0, 0, 0}, + /* mObjTg */ + {AT_TYPE_BELLOWS, 0x4103, {0, 0x0, 0x40F}, 0, 0}, + /* mObjCo */ {0}}, + /* mSphInf */ + {30.0f} +}; + +s32 useUnused() { + static const f32 a1[] = { + 0.95f, + 1.05f, + 0.0f, + }; + return (s32)a1; +} + +bool dAcBlastboss_c::createHeap() { + bool result; + void *pData = getOarcResFile("BLastBoss"); + + TRY_CREATE2(mMdl.create3(*this, pData, "LastBoss", "Wait", 0x334)); + mScnCallback.attach(mMdl.getModel()); + + nw4r::g3d::ResFile res(pData); + + TRY_CREATE2(mAnmTexSrt.create(mMdl.getModel().getResMdl(), res.GetResAnmTexSrt("Hair"), &mAllocator, nullptr, 1)); + mMdl.getModel().setAnm(mAnmTexSrt); + + TRY_CREATE2(mAnmMatClr1.create(mMdl.getModel().getResMdl(), res.GetResAnmClr("Wait"), &mAllocator, nullptr, 2)); + mAnmMatClr1.setAnm(mMdl.getModel(), res.GetResAnmClr("Hair"), 1, m3d::PLAY_MODE_0); + mMdl.getModel().setAnm(mAnmMatClr1); + + mMdl.getModel().setCallback(&mMdlCallback); + mMdlCallback.mpOwner = this; + + TRY_CREATE2(mSwordMdl.create( + &mAllocator, pData, "LastBossSword", 0x130, mVec3_c(0.0f, 0.0f, 0.0f), mVec3_c(0.0f, -230.0f, 0.0f), mStts, + nullptr, 1, nullptr + )); + // TODO I'm not going to try and make sense of this for now + mSwordMdl.fn_8006B660(4, 1, 0, 0x10000, 0, 0, 0, 0x400, 0xc, 60.0f); + mSwordMdl.mProc.setColor1(mColor(0xFF, 0xFF, 0xFF, 0x14)); + mSwordMdl.mProc.setColor2(mColor(0xFF, 0xFF, 0xFF, 0x14)); + + TRY_CREATE2(mThunderMdl.create(res.GetResMdl("FX_LBThunder"), &mAllocator, 0x120)); + + TRY_CREATE2( + mThunderAnmMatClr.create(mThunderMdl.getResMdl(), res.GetResAnmClr("FX_LBThunder"), &mAllocator, nullptr, 1) + ); + mThunderMdl.setAnm(mThunderAnmMatClr); + + dBase_c::createBase(fProfile::LYT_BOSS_CAPTION, this, 0, OTHER); + + return result; +} + +int dAcBlastboss_c::create() { + field_0x1130 = getFromParams(0, 0xFF); + if (MinigameManager::GetInstance()->checkInBossRush()) { + field_0x114D = 1; + } + CREATE_ALLOCATOR(dAcBlastboss_c); + + mStts.SetRank(10); + mCcList.addCc(mCc1, sSrcCyl1); + mCcList.addCc(mCc2, sSrcCyl2); + mCcList.addCc(mCc3, sSrcCyl3); + + for (int i = 0; i < (int)ARRAY_LENGTH(field_0x1260); i++) { + field_0x1260[i].field_0x000 = i; + field_0x1260[i].field_0x002 = cM::rndF(65536.0f); + mCcList.addCc(field_0x1260[i].mCc, sSrcSph); + for (int j = 0; j < (int)ARRAY_LENGTH(field_0x1260[j].field_0x014); j++) { + field_0x1260[i].field_0x014[j] = mPosition; + } + field_0x1260[i].field_0x008 = i * 15000; + } + + // TODO loop of length 1 might not exist + for (int i = 0; i < (int)ARRAY_LENGTH(field_0x2948); i++) { + mCcList.addCc(field_0x2948[i].mCc, sSrcSph); + for (int j = 0; j < (int)ARRAY_LENGTH(field_0x2948[j].field_0x008); j++) { + field_0x2948[i].field_0x008[j] = mPosition; + } + } + + mCcList.SetStts(mStts); + + mCc4.Set(sSrcSph1); + mCc4.SetStts(mStts); + + mCc5.Set(sSrcSph2); + mCc5.mTg.Set_0x4C(-1); + mCc5.SetStts(mStts); + + mAcceleration = -5.0f; + mMaxSpeed = -80.0f; + + mBoundingBox.Set(mVec3_c(-200.0f, -300.0f, -200.0f), mVec3_c(200.0f, 300.0f, 200.0f)); + mStateMgr.changeState(StateID_Fight); + + field_0x1132 = 1; + field_0x1164 = cM::rndF(65536.0f); + + mHealth = 400; + mPositionCopy3 = mPosition; + + field_0x11D4 = field_0x11D8 = -1; + + mEmitter1.init(this); + mEmitter2.init(this); + // mEmitter3.init(this); // TODO why not this one... + mEmitter4.init(this); + mEmitter5.init(this); + mEmitter6.init(this); + mEmitter7.init(this); + + mLightInfo.SetPosition(mPosition); + mLightInfo.mClr.Set(100, 150, 255, 255); + dLightEnv_c::GetPInstance()->plight_set(&mLightInfo); + fn_143_A110(100); + + if (!field_0x114D) { + field_0x2CEC = 200; + setActorProperty(AC_PROP_0x4); + } + + return SUCCEEDED; +} + +int dAcBlastboss_c::doDelete() { + dLightEnv_c::GetPInstance()->plight_cut(&mLightInfo); + return SUCCEEDED; +} + +int dAcBlastboss_c::actorExecute() { + if (field_0x114D && mpSwordBattleGame == nullptr) { + mpSwordBattleGame = static_cast( + fManager_c::searchBaseByProfName(fProfile::TAG_SWORD_BATTLE_GAME, mpSwordBattleGame) + ); + } + dAcPy_c *link = dAcPy_c::GetLinkM(); + + field_0x1164++; + + field_0x1133 = 0; + field_0x1131 = 0; + field_0x1141 = 0; + field_0x114E = 0; + + field_0x11A4 = 0.0f; + mLightInfo.mScale = 0.0f; + field_0x11B0 = 0.7f; + + if (field_0x1156 != 0) { + field_0x1156--; + } + + if (field_0x1158 != 0) { + field_0x1158--; + } + + if (field_0x115A != 0) { + field_0x115A--; + } + + if (field_0x115C != 0) { + field_0x115C--; + } + + if (field_0x115E != 0) { + field_0x115E--; + } + + if (field_0x1160 != 0) { + field_0x1160--; + } + + if (mMdlCallback.field_0x04 != 0) { + mMdlCallback.field_0x04--; + } + + if (field_0x117C != 0) { + field_0x117C--; + } + + if (field_0x113D != 0) { + field_0x113D--; + } + + if (field_0x113F != 0) { + field_0x113F--; + } + + if (field_0x113E != 0) { + field_0x113E--; + } + + mVec3_c linkPos = link->getPosition(); + field_0x116A = cLib::targetAngleY(mPosition, linkPos); + // TODO maybe inline + mVec3_c posDiff = link->getPosition() - mPosition; + field_0x1190 = posDiff.absXZ(); + + + field_0x1186 = field_0x116A - mRotation.y; + mSwordMdl.setAttackActive(false); + + mCc4.ClrAtSet(); + mCc5.ClrAtSet(); + + fn_143_6720(); + if (mpSwordBattleGame == nullptr || mpSwordBattleGame->checkFightStarted() == true) { + mStateMgr.executeState(); + } + + mRotation.x = mRotationCopy.x; + mRotation.z = mRotationCopy.z; + sLib::addCalcAngle(&mRotation.y.mVal, mRotationCopy.y, 2, 0x800); + + mMdl.play(); + if (!field_0x114F) { + mAnmMatClr1.play(); + } + + calcVelocity(); + mPosition += mVelocity; + mPosition += mStts.GetCcMove(); + mPosition.x += field_0x119C; + mPosition.z += field_0x11A0; + + field_0x119C *= 0.6f; + field_0x11A0 *= 0.6f; + + f32 f5 = 0.0f; + if (mRotation.x != 0) { + f5 += field_0x11C0 * mRotation.x.sin(); + } + + field_0x1140 = 0; + if (mPosition.y <= f5) { + mPosition.y = f5; + field_0x11BC = mVelocity.y; + mVelocity.y = 0.0f; + field_0x1140 = 1; + } + + fn_143_7B00(); + + mWorldMtx.transS(mPosition); + mWorldMtx.ZXYrotM(mRotation); + mScale.set(0.95f, 0.95f, 0.95f); + mMdl.getModel().setScale(mScale); + mMdl.getModel().setLocalMtx(mWorldMtx); + if (!field_0x114F) { + mAnmTexSrt.play(); + } + + mMdl.getModel().calc(false); + + nw4r::g3d::ResMdl resMdl = mMdl.getModel().getResMdl(); + mMtx_c nodeMtx; + mMdl.getModel().getNodeWorldMtx(resMdl.GetResNode("loc_sword01").GetID(), nodeMtx); + mMtx_c scaleMtx; + scaleMtx.scaleS(1.05f, 1.05f, 1.05f); + MTXConcat(nodeMtx, scaleMtx, nodeMtx); + + // TODO - inline? + mVec3_c v(mRotation.y.sin(), 0.0f, mRotation.y.cos()); + mSwordMdl.calc(nodeMtx, v, false); + + mVec3_c vEff(0.0f, -120.0f, 0.0f); + if ((s32)field_0x1144 == 9) { + vEff.y = -80.0f; + if (field_0x1190 > 300.0f) { + vEff.y -= (field_0x1190 - 300.0f); + if (vEff.y < -280.0f) { + vEff.y = -280.0f; + } + } + } + MTXMultVec(nodeMtx, vEff, field_0x1208); + + if (mIsSwordEmpowered) { + mEmitter4.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_619_, nodeMtx, nullptr, nullptr); + mLightInfo.mPos = field_0x1208; + if (dScGame_c::getUpdateFrameCount() & 2) { + mLightInfo.SetScale(300.0f); + } else { + mLightInfo.SetScale(200.0f); + } + holdSound(SE_BLasBos_SwordEnpowered); + } + + if (field_0x114B != 0) { + if (field_0x114B == 1) { + mEmitter7.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_852_, nodeMtx, nullptr, nullptr); + mMdl.getModel().getNodeWorldMtx(resMdl.GetResNode("backbone2").GetID(), nodeMtx); + mEmitter6.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_853_, nodeMtx, nullptr, nullptr); + holdSound(SE_BLasBos_UnderElecShock); + } else if (field_0x114B == 2) { + mMdl.getModel().getNodeWorldMtx(resMdl.GetResNode("backbone2").GetID(), nodeMtx); + dJEffManager_c::spawnEffect(PARTICLE_RESOURCE_ID_MAPPING_851_, nodeMtx, nullptr, nullptr, 0, 0); + mMtx_c transMtx; + transMtx.transS(0.0f, -100000.0f, 0.0f); + MTXConcat(nodeMtx, transMtx, nodeMtx); + mEmitter7.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_852_, nodeMtx, nullptr, nullptr); + mEmitter6.holdEffect(PARTICLE_RESOURCE_ID_MAPPING_853_, nodeMtx, nullptr, nullptr); + holdSound(SE_BLasBos_KillOffElecShock); + } + mLightInfo.mPos = field_0x1208; + if (dScGame_c::getUpdateFrameCount() & 2) { + mLightInfo.SetScale(400.0f); + } else { + mLightInfo.SetScale(300.0f); + } + field_0x114B = 0; + } + + // TODO NODE IDs + mMdl.getModel().getNodeWorldMtx(0x26, nodeMtx); + nodeMtx.getTranslation(field_0x11E4); + mMdl.getModel().getNodeWorldMtx(1, nodeMtx); + nodeMtx.getTranslation(field_0x11F0); + mMdl.getModel().getNodeWorldMtx(3, nodeMtx); + nodeMtx.getTranslation(field_0x11FC); + mMdl.getModel().getNodeWorldMtx(0x3C, nodeMtx); + nodeMtx.getTranslation(field_0x1238[0]); + mMdl.getModel().getNodeWorldMtx(0x40, nodeMtx); + nodeMtx.getTranslation(field_0x1238[1]); + + mMdl.getModel().getNodeWorldMtx(5, nodeMtx); + mVec3_c tmp1(0.0f, 0.0f, 0.0f); + MTXMultVec(nodeMtx, tmp1, mPositionCopy2); + // TODO + mPositionCopy3 = mVec3_c(mPositionCopy2.x, mPositionCopy2.y + 50.0f, mPositionCopy2.z); + + if (field_0x1132) { + fn_80030c20(0, 1500.0f, 50.0f, -200.0f, 200.0f); + } + + nodeMtx.YrotS(mRotation.y); + mVec3_c tmpCc; + if (link->isAttacking() && *mStateMgr.getStateID() == StateID_Guard) { + if (field_0x1144 == 9) { + tmpCc.z = 100.0f; + // TODO - ... + } + } + + MTXMultVec(nodeMtx, tmpCc, tmpCc); + tmpCc += mPosition; + + return SUCCEEDED; +} + +void dAcBlastboss_c::callback_c::timingB(u32 nodeId, nw4r::g3d::WorldMtxManip *manip, nw4r::g3d::ResMdl mdl) {} + void dAcBlastboss_c::initializeState_Fight() {} void dAcBlastboss_c::executeState_Fight() {} void dAcBlastboss_c::finalizeState_Fight() {} @@ -59,3 +496,12 @@ void dAcBlastboss_c::finalizeState_Stun() {} void dAcBlastboss_c::initializeState_ThunderWait() {} void dAcBlastboss_c::executeState_ThunderWait() {} void dAcBlastboss_c::finalizeState_ThunderWait() {} + +int dAcBlastboss_c::draw() { + drawModelType1(&mMdl.getModel()); + mSwordMdl.entry(this, nullptr, nullptr); + if (field_0x114C) { + drawModelType1(&mThunderMdl); + } + return SUCCEEDED; +} diff --git a/src/d/col/c/c_m3d_g_cps.cpp b/src/d/col/c/c_m3d_g_cps.cpp index 4457e2fb..6fbcfc3d 100644 --- a/src/d/col/c/c_m3d_g_cps.cpp +++ b/src/d/col/c/c_m3d_g_cps.cpp @@ -16,7 +16,7 @@ void cM3dGCps::SetR(f32 r) { r = 0.0f; } mRadius = r; - field_0x1C = (double)r; // huh + field_0x1C = mRadius; } void cM3dGCps::Set_0x1C(f32 f) { diff --git a/src/toBeSorted/d_enemy_sword_mdl.cpp b/src/toBeSorted/d_enemy_sword_mdl.cpp new file mode 100644 index 00000000..563b8131 --- /dev/null +++ b/src/toBeSorted/d_enemy_sword_mdl.cpp @@ -0,0 +1,131 @@ +#include "toBeSorted/d_enemy_sword_mdl.h" + +#include "common.h" +#include "d/col/cc/d_cc_s.h" +#include "d/d_sc_game.h" +#include "m/m3d/m_shadow.h" +#include "m/m_vec.h" +#include "nw4r/g3d/res/g3d_resfile.h" +#include "nw4r/g3d/res/g3d_resmdl.h" + +dCcD_SrcCps sCcSrc = { + { + {0x400, 0x8D, {1, 0, 0}, 1, 0, 0, 0, 0, 0}, + {0, 0, {0, 0, 0x407}, 0, 0}, + {0}, + }, + {30.0f}, +}; + +// Yeah these two functions do the same thing. Could've made one call the other... + +bool dEnemySwordMdl_c::create( + mAllocator_c *alloc, void *pData, const char *mdlName, u32 bufferOption, const mVec3_c &v1, const mVec3_c &v2, + cCcD_Stts &stts, EGG::ResTIMG *pImg, int nView, u32 *pSize +) { + nw4r::g3d::ResMdl mdl = nw4r::g3d::ResFile(pData).GetResMdl(mdlName); + if (!mMdl.create(mdl, alloc, bufferOption, nView, pSize)) { + return false; + } + + if (!mProc.create(100, alloc, pImg, 0.015f)) { + mMdl.remove(); + return false; + } + + field_0x074.set(v1.x, v1.y, v1.z); + field_0x080.set(v2.x, v2.y, v2.z); + + for (int i = 0; i < 3; i++) { + mCcList.addCc(mCcs[i], sCcSrc); + } + mCcList.SetStts(stts); + mCcList.ClrAt(); + return true; +} + +bool dEnemySwordMdl_c::create( + mAllocator_c *alloc, nw4r::g3d::ResFile resFile, const char *mdlName, u32 bufferOption, const mVec3_c &v1, + const mVec3_c &v2, cCcD_Stts &stts, EGG::ResTIMG *pImg, int nView, u32 *pSize +) { + nw4r::g3d::ResMdl mdl = resFile.GetResMdl(mdlName); + if (!mMdl.create(mdl, alloc, bufferOption, nView, pSize)) { + return false; + } + + if (!mProc.create(100, alloc, pImg, 0.015f)) { + mMdl.remove(); + return false; + } + + field_0x074.set(v1.x, v1.y, v1.z); + field_0x080.set(v2.x, v2.y, v2.z); + + for (int i = 0; i < 3; i++) { + mCcList.addCc(mCcs[i], sCcSrc); + } + mCcList.SetStts(stts); + mCcList.ClrAt(); + return true; +} + +void dEnemySwordMdl_c::fn_8006B640() { + mCcs[0].OnAtSet(); + field_0x070 = true; + field_0x071 = false; +} + +// TODO - ... + +void dEnemySwordMdl_c::calc(const mMtx_c &mtx, const mVec3_c &v1, bool mass) { + mMdl.setLocalMtx(mtx); + mMdl.calc(false); + MTXMultVec(mtx, field_0x074, field_0x08C); + MTXMultVec(mtx, field_0x080, field_0x098); + + if (field_0x070) { + mVec3_c v = field_0x098 - field_0x08C; + v.normalize(); + + mVec3_c hi = field_0x098 + v * field_0x0A8; + + mCcs[1].Set(mCcs[0].mEnd, hi); + mCcs[2].Set(mCcs[0].mStart, hi); + mCcs[0].Set(field_0x08C - v * field_0x0A4, hi); + + mCcs[0].SetAtVec(v1); + mCcs[1].SetAtVec(v1); + mCcs[2].SetAtVec(v1); + + if (field_0x071 && !mCcs[1].ChkAtSet()) { + mCcs[1].OnAtSet(); + mCcs[2].OnAtSet(); + } else { + field_0x071 = true; + } + + mCcList.registerColliders(); + if (mass) { + dCcS::GetInstance()->GetMassMng().SetObj(&mCcs[0], 2); + } + } else { + field_0x071 = false; + if (mCcs[0].ChkAtSet()) { + mCcList.ClrAt(); + } + } + mProc.calc(field_0x098, field_0x08C); +} + +bool dEnemySwordMdl_c::entry(dAcObjBase_c *obj, dShadowCircle_c *shadow, mQuat_c *quat) { + if (dScGame_c::currentSpawnInfo.getTrial() == SpawnInfo::TRIAL) { + obj->fn_8002ECD0(&mMdl, 7); + } else { + obj->drawModelType1(&mMdl); + } + mProc.entry(); + if (shadow != nullptr && quat != nullptr) { + m3d::mShadow_c::GetInstance()->addMdlToCircle(shadow, mMdl, *quat); + } + return true; +} diff --git a/src/toBeSorted/d_sword_swing_effect.cpp b/src/toBeSorted/d_sword_swing_effect.cpp new file mode 100644 index 00000000..944e79dc --- /dev/null +++ b/src/toBeSorted/d_sword_swing_effect.cpp @@ -0,0 +1,218 @@ +#include "toBeSorted/d_sword_swing_effect.h" + +#include "d/d_stage_mgr.h" +#include "egg/gfx/eggDrawGX.h" +#include "m/m3d/m3d.h" +#include "m/m3d/m_proc.h" +#include "m/m3d/m_scnleaf.h" +#include "nw4r/g3d/g3d_scnobj.h" +#include "nw4r/math/math_types.h" + +void dSwordSwingEffectProcBase_c::remove() { + if (mpEntries != nullptr) { + delete[] mpEntries; + mpEntries = nullptr; + } + m3d::scnLeaf_c::remove(); +} + +void dSwordSwingEffectProcBase_c::drawXlu() { + m3d::resetMaterial(); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetNumTexGens(0); + GXSetNumTevStages(1); + GXSetNumIndStages(0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV); + GXSetZCompLoc(1); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR); + GXSetZMode(GX_TRUE, GX_LEQUAL, GX_FALSE); + GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); + GXSetFog(GX_FOG_NONE, mColor(0), 0.0, 0.0, 0.0, 0.0); + GXSetFogRangeAdj(0, 0, 0); + GXSetCullMode(GX_CULL_NONE); + nw4r::math::MTX34 mtx; + nw4r::g3d::Camera cam = m3d::getCurrentCamera(); + cam.GetCameraMtx(&mtx); + GXLoadPosMtxImm(mtx, 0); + GXSetCurrentMtx(0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, mCount * 2); + + swing_entry *entry = &mpEntries[mHead]; + for (u16 i = 0; i < mCount; i++) { + if (entry == &mpEntries[0]) { + entry = &mpEntries[mNum]; + } + entry--; + + GXPosition3f32(entry->mv1.x, entry->mv1.y, entry->mv1.z); + GXColor4u8(entry->mc1.r, entry->mc1.g, entry->mc1.b, entry->mc1.a * entry->mLifetime); + GXPosition3f32(entry->mv2.x, entry->mv2.y, entry->mv2.z); + GXColor4u8(entry->mc2.r, entry->mc2.g, entry->mc2.b, entry->mc2.a * entry->mLifetime); + } + + GXEnd(); +} + +bool dSwordSwingEffectProcBase_c::hasSwings() const { + return mCount != 0; +} + +int dSwordSwingEffectProcBase_c::entry() { + if (hasSwings()) { + return m3d::pushBack(mpScnLeaf); + } + return 0; +} + +bool dSwordSwingEffectProcBase_c::create(s32 num, mAllocator_c *alloc) { + if (!m3d::proc_c::create(alloc, nullptr)) { + return false; + } + + mpEntries = new (alloc->getHeap(), 4) swing_entry[num](); + if (mpEntries == nullptr) { + remove(); + return false; + } + + mNum = num; + setOption(nw4r::g3d::ScnObj::OPTION_DISABLE_DRAW_OPA, true); + return true; +} + +void dSwordSwingEffectProcBase_c::addSwing( + const mVec3_c &pos1, mColor c1, const mVec3_c &pos2, mColor c2 +) { + mpEntries[mHead].set(pos1, c1, pos2, c2); + mHead++; + if (mHead >= mNum) { + mHead = 0; + } + if (mCount < mNum) { + mCount++; + } +} + +void dSwordSwingEffectProcBase_c::calc(f32 f) { + s32 count = mCount; + if (count == 0) { + return; + } + + swing_entry *entry = &mpEntries[mHead]; + for (u16 i = 0; i < mCount; i++) { + if (entry == &mpEntries[0]) { + entry = &mpEntries[mNum]; + } + entry--; + entry->mLifetime -= f; + if (entry->mLifetime <= 0.0f) { + entry->mLifetime = 0.0f; + count--; + } + } + if (mCount != 0 && count == 0) { + mHead = 0; + } + mCount = count; +} + +void dSwordSwingEffectProc_c::drawXlu() { + if (mpImg == nullptr) { + dSwordSwingEffectProcBase_c::drawXlu(); + } else { + EGG::DrawGX::LoadTexture(mpImg, GX_TEXMAP0); + GXSetNumChans(1); + GXSetChanCtrl(GX_COLOR0A0, false, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c, 0, 0x7d); + GXSetNumTevStages(1); + GXSetNumIndStages(0); + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_RASC, GX_CC_TEXC, GX_CC_ZERO); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, 1, GX_TEVPREV); + GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_RASA, GX_CA_TEXA, GX_CA_ZERO); + GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetZCompLoc(0); + GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR); + GXSetZMode(true, GX_LEQUAL, false); + GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0); + GXSetFog(GX_FOG_NONE, mColor(0), 0.0, 0.0, 0.0, 0.0); + GXSetFogRangeAdj(0, 0, 0); + GXSetCullMode(GX_CULL_NONE); + nw4r::math::MTX34 mtx; + nw4r::g3d::Camera cam = m3d::getCurrentCamera(); + cam.GetCameraMtx(&mtx); + GXLoadPosMtxImm(mtx, 0); + GXSetCurrentMtx(0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, mCount * 2); + + u8 alpha = dStageMgr_c::GetInstance()->getGlobalAlpha(); + f32 fAlpha = alpha * (1.0f / 255.0f); + + s32 idx = mHead - mCount; + if (idx < 0) { + idx += mNum; + } + + f32 texCoordOffset = mTexScale * idx; + + swing_entry *entry = &mpEntries[idx]; + swing_entry *last = &mpEntries[mNum]; + + for (u16 i = 0; i < mCount; i++) { + GXPosition3f32(entry->mv1.x, entry->mv1.y, entry->mv1.z); + GXColor4u8(entry->mc1.r, entry->mc1.g, entry->mc1.b, entry->mc1.a * entry->mLifetime * fAlpha); + GXTexCoord2f32(texCoordOffset, 0.0f); + + GXPosition3f32(entry->mv2.x, entry->mv2.y, entry->mv2.z); + GXColor4u8(entry->mc2.r, entry->mc2.g, entry->mc2.b, entry->mc2.a * entry->mLifetime * fAlpha); + GXTexCoord2f32(texCoordOffset, 1.0f); + + texCoordOffset += mTexScale; + entry++; + if (entry == last) { + entry = &mpEntries[0]; + } + } + } +} + +bool dSwordSwingEffectProc_c::create(s32 num, mAllocator_c *alloc, EGG::ResTIMG *pImg, f32 scale) { + if (!dSwordSwingEffectProcBase_c::create(num, alloc)) { + return false; + } + + mpImg = pImg; + mTexScale = scale; + return true; +} + +void dSwordSwingEffectProcBase_c::swing_entry::set( + const mVec3_c &pos1, const mColor &c1, const mVec3_c &pos2, const mColor &c2 +) { + mLifetime = 1.0f; + mv1 = pos1; + mv2 = pos2; + mc1 = c1; + mc2 = c2; +} diff --git a/src/toBeSorted/d_sword_swing_effect_mgr.cpp b/src/toBeSorted/d_sword_swing_effect_mgr.cpp new file mode 100644 index 00000000..1d0339c3 --- /dev/null +++ b/src/toBeSorted/d_sword_swing_effect_mgr.cpp @@ -0,0 +1,196 @@ +#include "toBeSorted/d_sword_swing_effect_mgr.h" + +#include "c/c_math.h" +#include "egg/math/eggMatrix.h" +#include "m/m_vec.h" + +// TODO: can't use EGG::Vector3f::cross because the Vector3f -> mVec3_c conversion +// forces additional stack stores. An open-coded cross function works too in this +// file but maybe pattern comes up in more files and then we can move it to d_vec? +inline void cross(mVec3_c &result, const mVec3_c &left, const mVec3_c &right) { + result.set( + (left.y * right.z) - (left.z * right.y), (left.z * right.x) - (left.x * right.z), + (left.x * right.y) - (left.y * right.x) + ); +} + +static bool fn_8006A8D0(const mVec2_c &v1, const mVec2_c &v2, const mVec2_c &v3, const mVec2_c &v4, mVec2_c &result) { + mVec2_c t1 = v2 - v1; + mVec2_c t2 = v4 - v3; + + if (cM::isZero(t1.x)) { + if (cM::isZero(t2.x)) { + return false; + } else { + result.x = v1.x; + result.y = v3.y + (t2.y / t2.x) * (v1.x - v3.x); + } + } else { + if (cM::isZero(t2.x)) { + result.x = v3.x; + } else { + f32 tmp = t1.y / t1.x - t2.y / t2.x; + if (cM::isZero(tmp)) { + return false; + } + result.x = (v3.x + (((t1.y / t1.x) * v1.x - v1.y) - (t2.y / t2.x) * v3.x)) / tmp; + } + result.y = v1.y + (t1.y / t1.x) * (result.x - v1.x); + } + + mVec2_c diff = result - v1; + if (diff.x * t1.x + diff.y * t1.y >= 0.0f) { + return false; + } + + diff = result - v3; + if (diff.x * t2.x + diff.y * t2.y >= 0.0f) { + return false; + } + + return true; +} + +void dSwordSwingEffectProcMgr_c::createSwingEntries(const mVec3_c &v1, const mVec3_c &v2) { + mVec3_c lastDiff = field_0x44 - field_0x38; + mVec3_c diff = v1 - v2; + + mVec3_c cross_; + cross(cross_, lastDiff, diff); + + f32 diffMag = diff.mag(); + + lastDiff.normalize(); + + diff /= diffMag; + + cross_.normalize(); + + // Same code as in dowsing_target... + f32 dot = lastDiff.dot(diff); + dot = cM::minMaxLimit(dot, -1.0f, 1.0f); + f32 a = 1.0f - dot * dot <= 0.0f ? 0.0f : nw4r::math::FrSqrt(1.0f - dot * dot) * (1.0f - dot * dot); + EGG::Matrix34f mat; + mat.setAxisRotation(cross_, cM::atan2f(a, dot) * 0.1f); + + mVec2_c p1, p2, p3, p4; + mVec2_c res1, res2, res3; + + p1.set(field_0x38.x, field_0x38.y); + p2.set(field_0x44.x, field_0x44.y); + p3.set(v2.x, v2.y); + p4.set(v1.x, v1.y); + bool b1 = fn_8006A8D0(p1, p2, p3, p4, res1); + + p1.set(field_0x38.y, field_0x38.z); + p2.set(field_0x44.y, field_0x44.z); + p3.set(v2.y, v2.z); + p4.set(v1.y, v1.z); + bool b2 = fn_8006A8D0(p1, p2, p3, p4, res2); + + p1.set(field_0x38.z, field_0x38.x); + p2.set(field_0x44.z, field_0x44.x); + p3.set(v2.z, v2.x); + p4.set(v1.z, v1.x); + bool b3 = fn_8006A8D0(p1, p2, p3, p4, res3); + + bool b; + mVec3_c local_124 = (v2 + field_0x38) * 0.5f; + mVec3_c diff1; + mVec3_c v; + f32 f_29; + f32 f_28; + EGG::Matrix34f mat2; + int i = 0; + if (!b1) { + i += 1; + } + if (!b2) { + i += 1; + } + + if (!b3) { + i += 1; + } + + if (i >= 2) { + v = (v2 - field_0x38) * 0.1f; + b = false; + } else { + if (b1 && b3) { + local_124.x = (res1.x + res3.y) * 0.5f; + } else if (b1) { + local_124.x = res1.x; + } else if (b3) { + local_124.x = res3.y; + } + + if (b2 && b1) { + local_124.y = (res2.x + res1.y) * 0.5f; + } else if (b2) { + local_124.y = res2.x; + } else if (b1) { + local_124.y = res1.y; + } + + if (b3 && b2) { + local_124.z = (res3.x + res2.y) * 0.5f; + } else if (b3) { + local_124.z = res3.x; + } else if (b2) { + local_124.z = res2.y; + } + + diff1 = field_0x38 - local_124; + mVec3_c diff2 = v2 - local_124; + + f_29 = diff1.mag(); + f_28 = (diff2.mag() - f_29) * 0.1f; + + diff2.normalize(); + diff1.normalize(); + + cross(cross_, diff1, diff2); + cross_.normalize(); + + // Same code as in dowsing_target... + f32 dot = diff1.dot(diff2); + dot = cM::minMaxLimit(dot, -1.0f, 1.0f); + f32 a = 1.0f - dot * dot <= 0.0f ? 0.0f : nw4r::math::FrSqrt(1.0f - dot * dot) * (1.0f - dot * dot); + mat2.setAxisRotation(cross_, cM::atan2f(a, dot) * 0.1f); + + b = true; + } + + f32 blub = 0.1f; + for (int i = 1; i <= 10; i++) { + mVec3_c a; + mVec3_c t; + if (b) { + MTXMultVecSR(mat2.m, diff1, diff1); + t = local_124 + (diff1 * (f_29 + (f_28 * i))); + } else { + t = field_0x38 + v * i; + } + + MTXMultVecSR(mat.m, lastDiff, lastDiff); + a = t + lastDiff * diffMag; + + mProc.addSwing(a, mC1, t, mC2); + // Unused + blub += 0.1f; + } +} + +void dSwordSwingEffectProcMgr_c::calc(const mVec3_c &v1, const mVec3_c &v2) { + mProc.calc(0.1f); + if (mIsActive) { + createSwingEntries(v1, v2); + } + field_0x44 = v1; + field_0x38 = v2; +} + +void dSwordSwingEffectProcMgr_c::entry() { + mProc.entry(); +} diff --git a/src/toBeSorted/dowsing_target.cpp b/src/toBeSorted/dowsing_target.cpp index 5969bf73..35311efb 100644 --- a/src/toBeSorted/dowsing_target.cpp +++ b/src/toBeSorted/dowsing_target.cpp @@ -174,6 +174,7 @@ DowsingTarget *DowsingTarget::getDowsingInfo( targetDir.normalize(); + // Same code as in d_sword_swing_effect_mgr... f32 dot = dwsDir.dot(targetDir); dot = cM::minMaxLimit(dot, -1.0f, 1.0f); f32 a = 1.0f - dot * dot <= 0.0f ? 0.0f : nw4r::math::FrSqrt(1.0f - dot * dot) * (1.0f - dot * dot);