diff --git a/UnleashedRecomp/api/SWA.h b/UnleashedRecomp/api/SWA.h index 6a30e75..e451003 100644 --- a/UnleashedRecomp/api/SWA.h +++ b/UnleashedRecomp/api/SWA.h @@ -102,6 +102,7 @@ #include "SWA/System/GameMode/Title/TitleMenu.h" #include "SWA/System/GameMode/Title/TitleStateBase.h" #include "SWA/System/GameMode/Title/TitleStateIntro.h" +#include "SWA/System/GameMode/Title/TitleStateMenu.h" #include "SWA/System/GameMode/Title/TitleStateWorldMap.h" #include "SWA/System/GameMode/WorldMap/WorldMapCamera.h" #include "SWA/System/GameMode/WorldMap/WorldMapCursor.h" diff --git a/UnleashedRecomp/api/SWA/HUD/GeneralWindow/GeneralWindow.h b/UnleashedRecomp/api/SWA/HUD/GeneralWindow/GeneralWindow.h index 6728eba..f17d2e4 100644 --- a/UnleashedRecomp/api/SWA/HUD/GeneralWindow/GeneralWindow.h +++ b/UnleashedRecomp/api/SWA/HUD/GeneralWindow/GeneralWindow.h @@ -4,6 +4,15 @@ namespace SWA { + enum EWindowStatus : uint32_t + { + eWindowStatus_Closed, + eWindowStatus_OpeningMessage = 2, + eWindowStatus_DisplayingMessage, + eWindowStatus_OpeningControls, + eWindowStatus_DisplayingControls + }; + class CGeneralWindow { public: @@ -14,5 +23,20 @@ namespace SWA Chao::CSD::RCPtr m_rcWindow_2; Chao::CSD::RCPtr m_rcWindowSelect; Chao::CSD::RCPtr m_rcFooter; + SWA_INSERT_PADDING(0x58); + be m_Status; + be m_CursorIndex; + SWA_INSERT_PADDING(0x04); + be m_SelectedIndex; }; + + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_rcGeneral, 0xD0); + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_rcBg, 0xD8); + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_rcWindow, 0xE0); + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_rcWindow_2, 0xE8); + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_rcWindowSelect, 0xF0); + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_rcFooter, 0xF8); + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_Status, 0x158); + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_CursorIndex, 0x15C); + SWA_ASSERT_OFFSETOF(CGeneralWindow, m_SelectedIndex, 0x164); } diff --git a/UnleashedRecomp/api/SWA/System/GameDocument.h b/UnleashedRecomp/api/SWA/System/GameDocument.h index 150ebd9..d701301 100644 --- a/UnleashedRecomp/api/SWA/System/GameDocument.h +++ b/UnleashedRecomp/api/SWA/System/GameDocument.h @@ -34,7 +34,9 @@ namespace SWA SWA_INSERT_PADDING(0x88); Hedgehog::Base::CSharedString m_StageName; xpointer m_pSoundAdministrator; - SWA_INSERT_PADDING(0x124); + SWA_INSERT_PADDING(0x48); + xpointer m_pGeneralWindow; + SWA_INSERT_PADDING(0xD8); SScoreInfo m_ScoreInfo; SWA_INSERT_PADDING(0x0C); }; @@ -60,6 +62,7 @@ namespace SWA SWA_ASSERT_OFFSETOF(CGameDocument::CMember, m_spDatabase, 0x1C); SWA_ASSERT_OFFSETOF(CGameDocument::CMember, m_StageName, 0xAC); SWA_ASSERT_OFFSETOF(CGameDocument::CMember, m_pSoundAdministrator, 0xB0); + SWA_ASSERT_OFFSETOF(CGameDocument::CMember, m_pGeneralWindow, 0xFC); SWA_ASSERT_OFFSETOF(CGameDocument::CMember, m_ScoreInfo, 0x1D8); SWA_ASSERT_SIZEOF(CGameDocument::CMember, 0x230); diff --git a/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h b/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h index a533e26..bb195ce 100644 --- a/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h +++ b/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h @@ -4,10 +4,36 @@ namespace SWA { - class CTitleMenu + class CTitleMenu : public CMenuWindowBase { public: - SWA_INSERT_PADDING(0x44); + SWA_INSERT_PADDING(0x28); + be m_Field38; + bool m_Field3C; // Seems to be related to exit transition. + SWA_INSERT_PADDING(0x04); be m_CursorIndex; + SWA_INSERT_PADDING(0x0C); + bool m_Field54; // Seems to be related to exit transition. + SWA_INSERT_PADDING(0x0B); + be m_Field60; + SWA_INSERT_PADDING(0x34); + bool m_Field98; + bool m_IsDeleteCheckMessageOpen; + bool m_Field9A; // Seems to be related to cursor selection. + SWA_INSERT_PADDING(0x04); + bool m_Field9F; + SWA_INSERT_PADDING(0x02); + bool m_IsDLCInfoMessageOpen; }; + + SWA_ASSERT_OFFSETOF(CTitleMenu, m_Field38, 0x38); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_Field3C, 0x3C); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_CursorIndex, 0x44); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_Field54, 0x54); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_Field60, 0x60); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_Field98, 0x98); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_IsDeleteCheckMessageOpen, 0x99); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_Field9A, 0x9A); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_Field9F, 0x9F); + SWA_ASSERT_OFFSETOF(CTitleMenu, m_IsDLCInfoMessageOpen, 0xA2); } diff --git a/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleStateMenu.h b/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleStateMenu.h new file mode 100644 index 0000000..567ef59 --- /dev/null +++ b/UnleashedRecomp/api/SWA/System/GameMode/Title/TitleStateMenu.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace SWA +{ + class CTitleStateMenu : public CTitleStateBase {}; +} diff --git a/UnleashedRecomp/patches/CTitleStateMenu_patches.cpp b/UnleashedRecomp/patches/CTitleStateMenu_patches.cpp index c4050a7..1012a99 100644 --- a/UnleashedRecomp/patches/CTitleStateMenu_patches.cpp +++ b/UnleashedRecomp/patches/CTitleStateMenu_patches.cpp @@ -1,9 +1,12 @@ #include +#include #include +#include #include #include #include #include +#include #include #include #include @@ -50,12 +53,14 @@ PPC_FUNC_IMPL(__imp__sub_825882B8); PPC_FUNC(sub_825882B8) { auto pTitleState = (SWA::CTitleStateBase*)g_memory.Translate(ctx.r3.u32); + auto pGameDocument = SWA::CGameDocument::GetInstance(); auto pInputState = SWA::CInputState::GetInstance(); auto& pPadState = pInputState->GetPadState(); auto isAccepted = pPadState.IsTapped(SWA::eKeyState_A) || pPadState.IsTapped(SWA::eKeyState_Start); auto pContext = pTitleState->GetContextBase(); + auto isNewGameIndex = pContext->m_pTitleMenu->m_CursorIndex == 0; auto isOptionsIndex = pContext->m_pTitleMenu->m_CursorIndex == 2; auto isInstallIndex = pContext->m_pTitleMenu->m_CursorIndex == 3; @@ -63,7 +68,17 @@ PPC_FUNC(sub_825882B8) if (App::s_isSaveDataCorrupt && pContext->m_pTitleMenu->m_CursorIndex == 1) pContext->m_pTitleMenu->m_CursorIndex = 0; - if (!OptionsMenu::s_isVisible && isOptionsIndex) + if (isNewGameIndex && isAccepted) + { + if (pContext->m_pTitleMenu->m_IsDeleteCheckMessageOpen && + pGameDocument->m_pMember->m_pGeneralWindow->m_SelectedIndex == 1) + { + LOGN("Resetting achievements..."); + + AchievementManager::Reset(); + } + } + else if (!OptionsMenu::s_isVisible && isOptionsIndex) { if (OptionsMenu::s_isRestartRequired) { @@ -76,7 +91,6 @@ PPC_FUNC(sub_825882B8) { Game_PlaySound("sys_worldmap_window"); Game_PlaySound("sys_worldmap_decide"); - OptionsMenu::Open(); } } @@ -93,7 +107,6 @@ PPC_FUNC(sub_825882B8) if (OptionsMenu::CanClose() && pPadState.IsTapped(SWA::eKeyState_B)) { Game_PlaySound("sys_worldmap_cansel"); - OptionsMenu::Close(); } } diff --git a/UnleashedRecomp/user/achievement_manager.cpp b/UnleashedRecomp/user/achievement_manager.cpp index fc449db..4310155 100644 --- a/UnleashedRecomp/user/achievement_manager.cpp +++ b/UnleashedRecomp/user/achievement_manager.cpp @@ -67,9 +67,15 @@ void AchievementManager::Unlock(uint16_t id) AchievementOverlay::Open(id); } -void AchievementManager::Load() +void AchievementManager::Reset() { Data = {}; +} + +void AchievementManager::Load() +{ + AchievementManager::Reset(); + Status = EAchStatus::Success; auto dataPath = GetDataPath(true); diff --git a/UnleashedRecomp/user/achievement_manager.h b/UnleashedRecomp/user/achievement_manager.h index 443f176..7e002a2 100644 --- a/UnleashedRecomp/user/achievement_manager.h +++ b/UnleashedRecomp/user/achievement_manager.h @@ -27,6 +27,7 @@ public: static size_t GetTotalRecords(); static bool IsUnlocked(uint16_t id); static void Unlock(uint16_t id); + static void Reset(); static void Load(); static void Save(bool ignoreStatus = false); };