#include #include #include #include #include #include #include bool g_isClosed; float g_achievementMenuIntroTime = 0.0f; constexpr float g_achievementMenuIntroThreshold = 3.0f; float g_achievementMenuOutroTime = 0.0f; constexpr float g_achievementMenuOutroThreshold = 0.32f; bool g_isAchievementMenuOutro = false; void CHudPauseAddOptionsItemMidAsmHook(PPCRegister& pThis) { guest_stack_var menu("TopMenu"); guest_stack_var name("option"); GuestToHostFunction(sub_824AE690, pThis.u32, menu.get(), name.get()); } bool InjectMenuBehaviour(uint32_t pThis, uint32_t count) { if (App::s_isLoading) return true; auto pHudPause = (SWA::CHudPause*)g_memory.Translate(pThis); auto cursorIndex = *(be*)g_memory.Translate(4 * (*(be*)g_memory.Translate(pThis + 0x19C) + 0x68) + pThis); auto actionType = SWA::eActionType_Undefined; auto transitionType = SWA::eTransitionType_Undefined; switch (pHudPause->m_Menu) { case SWA::eMenuType_WorldMap: case SWA::eMenuType_Stage: case SWA::eMenuType_Misc: actionType = SWA::eActionType_Return; transitionType = SWA::eTransitionType_Quit; break; case SWA::eMenuType_Village: case SWA::eMenuType_Hub: actionType = SWA::eActionType_Return; transitionType = SWA::eTransitionType_Hide; break; } if (auto pInputState = SWA::CInputState::GetInstance()) { if (pInputState->GetPadState().IsTapped(SWA::eKeyState_Select)) { AchievementMenu::Open(); pHudPause->m_Action = SWA::eActionType_Undefined; pHudPause->m_Transition = SWA::eTransitionType_SubMenu; return false; } } if (pHudPause->m_Status == SWA::eStatusType_Accept) { if (cursorIndex == count - 2) { OptionsMenu::Open(true, pHudPause->m_Menu); pHudPause->m_Action = SWA::eActionType_Undefined; pHudPause->m_Transition = SWA::eTransitionType_Hide; if (pHudPause->m_rcBg1Select) pHudPause->m_rcBg1Select->SetHideFlag(true); return true; } else if (cursorIndex == count - 1) { pHudPause->m_Action = actionType; pHudPause->m_Transition = transitionType; return true; } } return false; } bool CHudPauseItemCountMidAsmHook(PPCRegister& pThis, PPCRegister& count) { count.u32 += 1; return InjectMenuBehaviour(pThis.u32, count.u32); } void CHudPauseVillageItemCountMidAsmHook(PPCRegister& pThis, PPCRegister& count) { count.u32 += 1; InjectMenuBehaviour(pThis.u32, count.u32); } bool CHudPauseMiscItemCountMidAsmHook(PPCRegister& count) { if (count.u32 < 3) return true; return false; } bool CHudPauseMiscInjectOptionsMidAsmHook(PPCRegister& pThis) { return InjectMenuBehaviour(pThis.u32, 3); } // SWA::CHudPause::Update PPC_FUNC_IMPL(__imp__sub_824B0930); PPC_FUNC(sub_824B0930) { if (App::s_isLoading) { __imp__sub_824B0930(ctx, base); return; } auto pHudPause = (SWA::CHudPause*)g_memory.Translate(ctx.r3.u32); auto pInputState = SWA::CInputState::GetInstance(); g_achievementMenuIntroTime += App::s_deltaTime; if (g_isAchievementMenuOutro) { g_achievementMenuOutroTime += App::s_deltaTime; // Re-open pause menu after achievement menu closes with delay. if (g_achievementMenuOutroTime >= g_achievementMenuOutroThreshold) { GuestToHostFunction(sub_824AFD28, pHudPause, 0, 1, 0, 0); g_achievementMenuOutroTime = 0; g_isAchievementMenuOutro = false; } } if (AchievementMenu::s_isVisible) { // HACK: wait for transition to finish before restoring control. if (g_achievementMenuIntroThreshold >= g_achievementMenuIntroTime) __imp__sub_824B0930(ctx, base); if (pInputState->GetPadState().IsTapped(SWA::eKeyState_B) && !g_isAchievementMenuOutro) { AchievementMenu::Close(); g_isAchievementMenuOutro = true; } } else if (OptionsMenu::s_isVisible && OptionsMenu::s_isPause) { if (OptionsMenu::CanClose() && pInputState->GetPadState().IsTapped(SWA::eKeyState_B)) { OptionsMenu::Close(); GuestToHostFunction(sub_824AFD28, pHudPause, 0, 0, 0, 1); __imp__sub_824B0930(ctx, base); } } else { g_achievementMenuIntroTime = 0; if (*SWA::SGlobals::ms_IsRenderHud && pHudPause->m_IsShown && !pHudPause->m_Submenu && pHudPause->m_Transition == SWA::eTransitionType_Undefined) { ButtonGuide::Open(Button("Achievements_Name", EButtonIcon::Back, EButtonAlignment::Left, EFontQuality::Low)); g_isClosed = false; } else if (!g_isClosed) { ButtonGuide::Close(); g_isClosed = true; } __imp__sub_824B0930(ctx, base); } }