diff --git a/config/RSBE01_02/rels/sora_menu_challenger/splits.txt b/config/RSBE01_02/rels/sora_menu_challenger/splits.txt index 501547889e..02790014b2 100644 --- a/config/RSBE01_02/rels/sora_menu_challenger/splits.txt +++ b/config/RSBE01_02/rels/sora_menu_challenger/splits.txt @@ -5,6 +5,10 @@ Sections: .data type:data align:32 .bss type:bss align:8 +mo_menu/sora_menu_challenger/mu_challenger_approach.cpp: + .text start:0x00000000 end:0x000007A8 + .data start:0x00000000 end:0x000002D0 + mo_menu/mo_menu.cpp: .text start:0x000007A8 end:0x00000844 .data start:0x000002D0 end:0x000002DC diff --git a/config/RSBE01_02/rels/sora_menu_challenger/symbols.txt b/config/RSBE01_02/rels/sora_menu_challenger/symbols.txt index 261dbcfe5e..c155250ab9 100644 --- a/config/RSBE01_02/rels/sora_menu_challenger/symbols.txt +++ b/config/RSBE01_02/rels/sora_menu_challenger/symbols.txt @@ -1,23 +1,24 @@ -fn_23_0 = .text:0x00000000; // type:function size:0x34 -fn_23_34 = .text:0x00000034; // type:function size:0x178 -fn_23_1AC = .text:0x000001AC; // type:function size:0x58 -fn_23_204 = .text:0x00000204; // type:function size:0x3B8 -fn_23_5BC = .text:0x000005BC; // type:function size:0x1C -fn_23_5D8 = .text:0x000005D8; // type:function size:0x98 -fn_23_670 = .text:0x00000670; // type:function size:0x138 +create__24muChallengerApproachTaskFv = .text:0x00000000; // type:function size:0x34 +__ct__24muChallengerApproachTaskFv = .text:0x00000034; // type:function size:0x178 +__dt__24muChallengerApproachTaskFv = .text:0x000001AC; // type:function size:0x58 +processDefault__24muChallengerApproachTaskFv = .text:0x00000204; // type:function size:0x3B8 +initialize__24muChallengerApproachTaskFi = .text:0x000005BC; // type:function size:0x1C +release__24muChallengerApproachTaskFv = .text:0x000005D8; // type:function size:0x98 +createData__24muChallengerApproachTaskFP9gfArchive = .text:0x00000670; // type:function size:0x138 _prolog = .text:0x000007A8; // type:function size:0x48 scope:global _epilog = .text:0x000007F0; // type:function size:0x48 scope:global _unresolved = .text:0x00000838; // type:function size:0xC scope:global _ctors = .ctors:0x00000000; // type:label scope:global data:4byte _dtors = .dtors:0x00000000; // type:label scope:global data:4byte -lbl_23_section4_0 = .data:0x00000000; // type:object size:0x1A4 +lbl_23_section4_0 = .data:0x00000000; // type:object size:0x13 data:string +lbl_23_section4_14 = .data:0x00000014; // type:object size:0x190 jumptable_23_section4_1A4 = .data:0x000001A4; // type:object size:0x34 scope:local lbl_23_data_1D8 = .data:0x000001D8; // type:object size:0x54 -lbl_23_section4_22C = .data:0x0000022C; // type:object size:0x64 +__vt__24muChallengerApproachTask = .data:0x0000022C; // type:object size:0x64 lbl_23_section4_290 = .data:0x00000290; // type:object size:0x19 data:string lbl_23_section4_2AC = .data:0x000002AC; // type:object size:0xC -lbl_23_section4_2B8 = .data:0x000002B8; // type:object size:0x8 +__RTTI__24muChallengerApproachTask = .data:0x000002B8; // type:object size:0x8 lbl_23_section4_2C0 = .data:0x000002C0; // type:object size:0x7 data:string -lbl_23_section4_2C8 = .data:0x000002C8; // type:object size:0x8 +__RTTI__6gfTask = .data:0x000002C8; // type:object size:0x8 lbl_23_data_2D0 = .data:0x000002D0; // type:object size:0xC scope:local align:4 data:string HomeBtnIcon = .data:0x000002E0; // type:object size:0x18C0 scope:global align:32 diff --git a/config/RSBE01_02/symbols.txt b/config/RSBE01_02/symbols.txt index fedea1b01b..28525f83d9 100644 --- a/config/RSBE01_02/symbols.txt +++ b/config/RSBE01_02/symbols.txt @@ -3799,7 +3799,7 @@ fn_80075830 = .text:0x80075830; // type:function size:0x34C fn_80075B7C = .text:0x80075B7C; // type:function size:0x110 fn_80075C8C = .text:0x80075C8C; // type:function size:0x90 fn_80075D1C = .text:0x80075D1C; // type:function size:0x200 -fn_80075F1C = .text:0x80075F1C; // type:function size:0x90 +stopSE__9sndSystemFll = .text:0x80075F1C; // type:function size:0x90 fn_80075FAC = .text:0x80075FAC; // type:function size:0x2C8 fn_80076274 = .text:0x80076274; // type:function size:0x33C fn_800765B0 = .text:0x800765B0; // type:function size:0xC4 @@ -4423,7 +4423,7 @@ startRumbleController__6muMenuFiii = .text:0x800AFAFC; // type:function size:0x8 loadMenuSound__6muMenuFv = .text:0x800AFB80; // type:function size:0x8 isLoadFinishMenuSound__6muMenuFv = .text:0x800AFB88; // type:function size:0x8 freeMenuSound__6muMenuFiii = .text:0x800AFB90; // type:function size:0x4 -fn_800AFB94 = .text:0x800AFB94; // type:function size:0x68 +create__8MenuRootFPCciPCc = .text:0x800AFB94; // type:function size:0x68 fn_800AFBFC = .text:0x800AFBFC; // type:function size:0x78 fn_800AFC74 = .text:0x800AFC74; // type:function size:0x170 fn_800AFDE4 = .text:0x800AFDE4; // type:function size:0x11C @@ -4479,9 +4479,9 @@ fn_800B60E0 = .text:0x800B60E0; // type:function size:0x38 fn_800B6118 = .text:0x800B6118; // type:function size:0x38 fn_800B6150 = .text:0x800B6150; // type:function size:0x38 fn_800B6188 = .text:0x800B6188; // type:function size:0x38 -fn_800B61C0 = .text:0x800B61C0; // type:function size:0xA8 -fn_800B6268 = .text:0x800B6268; // type:function size:0xA8 -fn_800B6310 = .text:0x800B6310; // type:function size:0xA8 +isNodeAnimFinished__8MuObjectFv = .text:0x800B61C0; // type:function size:0xA8 +isVisAnimFinished__8MuObjectFv = .text:0x800B6268; // type:function size:0xA8 +isClrAnimFinished__8MuObjectFv = .text:0x800B6310; // type:function size:0xA8 fn_800B63B8 = .text:0x800B63B8; // type:function size:0x2E8 fn_800B66A0 = .text:0x800B66A0; // type:function size:0x30 fn_800B66D0 = .text:0x800B66D0; // type:function size:0x5C @@ -7189,7 +7189,7 @@ fn_8018E4F0 = .text:0x8018E4F0; // type:function size:0x4C fn_8018E53C = .text:0x8018E53C; // type:function size:0x4C fn_8018E588 = .text:0x8018E588; // type:function size:0x4C fn_8018E5D4 = .text:0x8018E5D4; // type:function size:0x234 -fn_8018E808 = .text:0x8018E808; // type:function size:0x200 +Release__Q34nw4r3g3d7ResFileFv = .text:0x8018E808; // type:function size:0x200 Init__Q34nw4r3g3d7ResFileFPv = .text:0x8018EA08; // type:function size:0x2C4 fn_8018ECCC = .text:0x8018ECCC; // type:function size:0x44 GetResNode__Q34nw4r3g3d6ResMdlCFPCc = .text:0x8018ED10; // type:function size:0x44 diff --git a/configure.py b/configure.py index e3d75ef1b0..8ece8d5579 100755 --- a/configure.py +++ b/configure.py @@ -845,7 +845,9 @@ def MatchingFor(*versions): "mw_version": config.linker_version, "cflags": cflags_rel, "host": False, - "objects": [], + "objects": [ + Object(Matching, "mo_menu/sora_menu_challenger/mu_challenger_approach.cpp"), + ], }, { "lib": "sora_menu_collect_viewer", diff --git a/include/lib/BrawlHeaders b/include/lib/BrawlHeaders index e1c66b35ee..fd97ee40a4 160000 --- a/include/lib/BrawlHeaders +++ b/include/lib/BrawlHeaders @@ -1 +1 @@ -Subproject commit e1c66b35eeeea6e8993633f823246df1611f6e2d +Subproject commit fd97ee40a414ceb1322bbc1f9831cb6d2224a76a diff --git a/include/sora_menu_challenger/mu_challenger_approach.h b/include/sora_menu_challenger/mu_challenger_approach.h new file mode 100644 index 0000000000..f676d37d31 --- /dev/null +++ b/include/sora_menu_challenger/mu_challenger_approach.h @@ -0,0 +1,33 @@ +#pragma once + +#include "gf/gf_archive.h" +#include "mu/mu_menuroot.h" +#include "mu/mu_object.h" +#include "nw4r/g3d/g3d_resfile.h" +#include +#include +#include + +class muChallengerApproachTask : public gfTask { +public: + nw4r::g3d::ResFile m_backgroundRes; + nw4r::g3d::ResFile m_challengerRes; + MenuRoot* m_menuRoot; + MuObject* m_backgroundAnim; + MuObject* m_challengerAnim; + int m_challengerIndex; + int m_soundHandle; + char m_names[14][0x40]; + int m_animState; + int m_frameCount; + + static muChallengerApproachTask* create(); + muChallengerApproachTask(); + virtual ~muChallengerApproachTask(); + void processDefault(); + void initialize(int); + void release(); + void createData(gfArchive*); + +}; +static_assert(sizeof(muChallengerApproachTask) == 0x3E4, "Class is wrong size!"); diff --git a/src/mo_menu/sora_menu_challenger/mu_challenger_approach.cpp b/src/mo_menu/sora_menu_challenger/mu_challenger_approach.cpp new file mode 100644 index 0000000000..36044e2695 --- /dev/null +++ b/src/mo_menu/sora_menu_challenger/mu_challenger_approach.cpp @@ -0,0 +1,204 @@ +#include "gf/gf_archive.h" +#include "gf/gf_pad_system.h" +#include "gm/gm_global.h" +#include "mu/mu_menuroot.h" +#include "snd/snd_system.h" +#include +#include +#include + +muChallengerApproachTask* muChallengerApproachTask::create() { + return new (Heaps::MenuInstance) muChallengerApproachTask(); +} + +muChallengerApproachTask::muChallengerApproachTask() : gfTask("ChallengerApproach", Category_Menu, 0xF, 8, true) { + memset(m_names, 0, sizeof(m_names)); + + sprintf(m_names[0], "MenChallenger0001_TopN"); + sprintf(m_names[1], "MenChallenger0002_TopN"); + sprintf(m_names[2], "MenChallenger0003_TopN"); + sprintf(m_names[3], "MenChallenger0004_TopN"); + sprintf(m_names[4], "MenChallenger0005_TopN"); + sprintf(m_names[5], "MenChallenger0006_TopN"); + sprintf(m_names[6], "MenChallenger0007_TopN"); + sprintf(m_names[7], "MenChallenger0008_TopN"); + sprintf(m_names[8], "MenChallenger0009_TopN"); + sprintf(m_names[9], "MenChallenger0010_TopN"); + sprintf(m_names[10], "MenChallenger0011_TopN"); + sprintf(m_names[11], "MenChallenger0012_TopN"); + sprintf(m_names[12], "MenChallenger0013_TopN"); + sprintf(m_names[13], "MenChallenger0014_TopN"); + + m_menuRoot = NULL; + m_backgroundAnim = NULL; + m_challengerAnim = NULL; + + m_animState = 0; + m_frameCount = 0; +} + +muChallengerApproachTask::~muChallengerApproachTask() {} + +void muChallengerApproachTask::processDefault() { + + + gfPadStatus status; + g_gfPadSystem->getSysPadStatus((u8)g_GameGlobal->m_modeMelee->m_playersInitData[0].m_controllerNo - 1, &status); + + // NOTE: No idea why, but... + // ... cases 0, 11, and 12 are intentionally just breaks + // ... cases 1, 4, 5, and 7 are intentionally just incrementing-sets + switch (m_animState) { + case 0: + break; + + case 1: + m_animState = 2; + break; + + case 2: { + char animName[64]; + memset(animName, 0, sizeof(animName)); + strcat(animName, m_names[m_challengerIndex]); + strcat(animName, "__0"); + + m_backgroundAnim->changeNodeAnimNIf("MenChallenger0000_TopN__0"); + m_backgroundAnim->changeVisAnimNIf("MenChallenger0000_TopN__0"); + m_backgroundAnim->changeClrAnimN("MenChallenger0000_TopN__0"); + + m_challengerAnim->changeNodeAnimNIf(animName); + m_challengerAnim->changeVisAnimNIf(animName); + m_challengerAnim->changeClrAnimN(animName); + + m_soundHandle = g_sndSystem->playSE(snd_se_Dispay_challenger_siren, -1, 0, 0, -1); + m_animState = 3; + break; + } + + case 3: { + bool done; + if (!m_backgroundAnim->isNodeAnimFinished()) done = false; + else if (!m_backgroundAnim->isVisAnimFinished()) done = false; + else if (!m_backgroundAnim->isClrAnimFinished()) done = false; + else if (!m_challengerAnim->isNodeAnimFinished()) done = false; + else if (!m_challengerAnim->isVisAnimFinished()) done = false; + else if (!m_challengerAnim->isClrAnimFinished()) done = false; + else done = true; + + if (done == true) { + m_animState = 4; + } + break; + } + + case 4: + m_animState = 5; + break; + + case 5: + m_animState = 6; + break; + + case 6: { + u32 pressed = status.m_buttonsPressedThisFrame.bits; + bool advance; + if (pressed & gfPadButtons::A) advance = true; + else if (pressed & gfPadButtons::B) advance = true; + else if (pressed & gfPadButtons::Start) advance = true; + else advance = pressed & 0x100000; // unknown button + + if (advance == true) { + g_sndSystem->playSE(SND_SE_SYSTEM_FIXED_L, -1, 0, 0, -1); + m_animState = 7; + } + break; + } + + case 7: + m_animState = 8; + break; + + case 8: { + char animName[64]; + memset(animName, 0, sizeof(animName)); + strcat(animName, m_names[m_challengerIndex]); + strcat(animName, "__1"); + + m_backgroundAnim->changeNodeAnimNIf("MenChallenger0000_TopN__1"); + m_backgroundAnim->changeVisAnimNIf("MenChallenger0000_TopN__1"); + m_backgroundAnim->changeClrAnimN("MenChallenger0000_TopN__1"); + + m_challengerAnim->changeNodeAnimNIf(animName); + m_challengerAnim->changeVisAnimNIf(animName); + m_challengerAnim->changeClrAnimN(animName); + + m_animState = 9; + break; + } + + case 9: { + bool done; + if (!m_backgroundAnim->isNodeAnimFinished()) done = false; + else if (!m_backgroundAnim->isVisAnimFinished()) done = false; + else if (!m_backgroundAnim->isClrAnimFinished()) done = false; + else if (!m_challengerAnim->isNodeAnimFinished()) done = false; + else if (!m_challengerAnim->isVisAnimFinished()) done = false; + else if (!m_challengerAnim->isClrAnimFinished()) done = false; + else done = true; + + if (done == true) { + m_animState = 10; + } + break; + } + + case 10: + g_sndSystem->stopSE((s32)m_soundHandle, 0); + m_animState = 11; + break; + + case 11: + break; + + case 12: + break; + } + + m_frameCount++; +} + +void muChallengerApproachTask::initialize(int param) { + m_challengerIndex = param; + unk2C_b1 = false; + m_soundHandle = 0; +} + +void muChallengerApproachTask::release() { + m_menuRoot->exit(); + m_menuRoot = NULL; + + m_backgroundRes.Release(); + m_challengerRes.Release(); + + delete m_backgroundAnim; + m_backgroundAnim = NULL; + + delete m_challengerAnim; + m_challengerAnim = NULL; +} + +void muChallengerApproachTask::createData(gfArchive* archive) { + m_backgroundRes = archive->getData(Data_Type_Model, 0, 0xFFFE); + m_challengerRes = archive->getData(Data_Type_Model, 1, 0xFFFE); + + nw4r::g3d::ResFile::Init(&m_backgroundRes); + nw4r::g3d::ResFile::Init(&m_challengerRes); + + m_menuRoot = MenuRoot::create("ChallengerTask", 0x10, "/menu/defaultcamera/CharacterSelect.brres"); + + m_backgroundAnim = MuObject::create(&m_backgroundRes, "MenChallenger0000_TopN", 1, 0, Heaps::MenuInstance); + m_challengerAnim = MuObject::create(&m_challengerRes, m_names[m_challengerIndex], 1, 0, Heaps::MenuInstance); + + m_menuRoot->scene->Insert(m_menuRoot->scene->sceneItemsCount, m_backgroundAnim->m_scnMdl); + m_menuRoot->scene->Insert(m_menuRoot->scene->sceneItemsCount, m_challengerAnim->m_scnMdl); +}