From 519ba87ba951373ee355ea8c7f7dbbd089949e8d Mon Sep 17 00:00:00 2001 From: Hyper <34012267+hyperbx@users.noreply.github.com> Date: Fri, 23 Oct 2026 21:15:55 +0100 Subject: [PATCH] Fix pause mission window displaying when there's no text --- .../Message/HUDPause/MsgChangeState.h | 6 ++-- MarathonRecomp/api/Sonicteam/PauseTask.h | 10 +++--- MarathonRecomp/patches/pause_patches.cpp | 36 ++++++++++++++----- MarathonRecompLib/config/Marathon.toml.in | 11 ++++-- 4 files changed, 46 insertions(+), 17 deletions(-) diff --git a/MarathonRecomp/api/Sonicteam/Message/HUDPause/MsgChangeState.h b/MarathonRecomp/api/Sonicteam/Message/HUDPause/MsgChangeState.h index 647594a3f..ee25ff7dc 100644 --- a/MarathonRecomp/api/Sonicteam/Message/HUDPause/MsgChangeState.h +++ b/MarathonRecomp/api/Sonicteam/Message/HUDPause/MsgChangeState.h @@ -8,11 +8,13 @@ namespace Sonicteam::Message::HUDPause struct MsgChangeState : SoX::Message<0x1B04E> { be State{}; - MARATHON_INSERT_PADDING(0x04); + be Field08{}; - MsgChangeState(uint32_t in_state) : State(in_state) {} + MsgChangeState(const uint32_t in_state, const uint32_t in_field08) + : State(in_state), Field08(in_field08) {} }; MARATHON_ASSERT_OFFSETOF(MsgChangeState, State, 0x04); + MARATHON_ASSERT_OFFSETOF(MsgChangeState, Field08, 0x08); MARATHON_ASSERT_SIZEOF(MsgChangeState, 0x0C); } diff --git a/MarathonRecomp/api/Sonicteam/PauseTask.h b/MarathonRecomp/api/Sonicteam/PauseTask.h index 310274845..db6546232 100644 --- a/MarathonRecomp/api/Sonicteam/PauseTask.h +++ b/MarathonRecomp/api/Sonicteam/PauseTask.h @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -25,11 +26,11 @@ namespace Sonicteam be m_State; be m_Flags; be m_SelectedIndex; - MARATHON_INSERT_PADDING(0x28); + be m_Field78; + MARATHON_INSERT_PADDING(0x24); be m_Buttons; MARATHON_INSERT_PADDING(0x1D8); - xpointer m_pMissionText; - MARATHON_INSERT_PADDING(0x04); + boost::shared_ptr m_spMissionText; be m_ItemCount; MARATHON_INSERT_PADDING(0x12C); }; @@ -38,8 +39,9 @@ namespace Sonicteam MARATHON_ASSERT_OFFSETOF(PauseTask, m_State, 0x6C); MARATHON_ASSERT_OFFSETOF(PauseTask, m_Flags, 0x70); MARATHON_ASSERT_OFFSETOF(PauseTask, m_SelectedIndex, 0x74); + MARATHON_ASSERT_OFFSETOF(PauseTask, m_Field78, 0x78); MARATHON_ASSERT_OFFSETOF(PauseTask, m_Buttons, 0xA0); - MARATHON_ASSERT_OFFSETOF(PauseTask, m_pMissionText, 0x27C); + MARATHON_ASSERT_OFFSETOF(PauseTask, m_spMissionText, 0x27C); MARATHON_ASSERT_OFFSETOF(PauseTask, m_ItemCount, 0x284); MARATHON_ASSERT_SIZEOF(PauseTask, 0x3B4); } diff --git a/MarathonRecomp/patches/pause_patches.cpp b/MarathonRecomp/patches/pause_patches.cpp index 0e7c426d4..ae95dc52b 100644 --- a/MarathonRecomp/patches/pause_patches.cpp +++ b/MarathonRecomp/patches/pause_patches.cpp @@ -79,8 +79,6 @@ PPC_FUNC(sub_824F05D8) const auto pHUDPause = static_cast(reinterpret_cast(base + ctx.r3.u32)); const auto pMessage = reinterpret_cast(base + ctx.r4.u32); - pHUDPause->m_ShowMissionWindow = true; - if (pMessage->ID == Sonicteam::Message::HUDPause::MsgChangeState::GetID()) { const auto pMsgChangeState = static_cast(pMessage); @@ -188,15 +186,37 @@ PPC_FUNC(sub_82509870) }); } - SetTextEntityModifier(pPauseTask->m_pMissionText.get(), CSD_ALIGN_BOTTOM | CSD_SCALE); + SetTextEntityModifier(pPauseTask->m_spMissionText.get(), CSD_ALIGN_BOTTOM | CSD_SCALE); __imp__sub_82509870(ctx, base); } -// The mission text is drawn at a lower priority -// than the mission box by default. 1001.0f is the -// priority value used by the rest of the pause menu. -void PauseTask_SetMissionTextPriority(PPCRegister& priority) +// Skips the original code that sends this message, as it's sent *before* the +// text entity for the mission window is created, resulting in the message processor +// seeing nullptr. We'll send this message ourselves after the text entity is created. +bool PauseTask_SkipSendMsgChangeState() +{ + return Config::RestorePauseMissionText; +} + +void PauseTask_ConfigureMissionWindow(PPCRegister& r31) { - priority.f64 = 1001.0f; + const auto pPauseTask = reinterpret_cast(g_memory.Translate(r31.u32)); + + // The mission text is drawn at a lower priority than the mission window by default. + // 1001.0f is the priority value used by the rest of the pause menu. + if (pPauseTask->m_spMissionText) + GuestToHostFunction(sub_8262AF00, pPauseTask->m_spMissionText.get(), 1001.0f); + + if (!Config::RestorePauseMissionText) + return; + + auto showMissionWindow = true; + + if (!pPauseTask->m_spMissionText || pPauseTask->m_spMissionText->m_TextLength <= 0) + showMissionWindow = false; + + auto msgChangeState = guest_stack_var(0, pPauseTask->m_Field78.get()); + pPauseTask->m_pHUDPause->m_ShowMissionWindow = showMissionWindow; + pPauseTask->m_pHUDPause->ProcessMessage(msgChangeState.get()); } diff --git a/MarathonRecompLib/config/Marathon.toml.in b/MarathonRecompLib/config/Marathon.toml.in index 9dab3e3c9..67fbac95e 100644 --- a/MarathonRecompLib/config/Marathon.toml.in +++ b/MarathonRecompLib/config/Marathon.toml.in @@ -551,9 +551,14 @@ address = 0x822196EC registers = ["r3", "r31"] [[midasm_hook]] -name = "PauseTask_SetMissionTextPriority" -address = 0x82509AEC -registers = ["f1"] +name = "PauseTask_SkipSendMsgChangeState" +address = 0x82509A30 +jump_address_on_true = 0x82509A60 + +[[midasm_hook]] +name = "PauseTask_ConfigureMissionWindow" +address = 0x82509B04 +registers = ["r31"] [[midasm_hook]] name = "SonicGauge_FixGemSprite"