mirror of
https://github.com/hedge-dev/UnleashedRecomp.git
synced 2026-04-27 21:01:37 +00:00
Implemented accessing options menu via pause and title screen
This commit is contained in:
parent
91db1eae2b
commit
e14439626d
14 changed files with 336 additions and 23 deletions
|
|
@ -65,6 +65,8 @@ set(SWA_HID_CXX_SOURCES
|
|||
)
|
||||
|
||||
set(SWA_PATCHES_CXX_SOURCES
|
||||
"patches/ui/CHudPause_patches.cpp"
|
||||
"patches/ui/CTitleMenu_patches.cpp"
|
||||
"patches/ui/frontend_listener.cpp"
|
||||
"patches/fps_patches.cpp"
|
||||
"patches/misc_patches.cpp"
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ namespace Hedgehog::Base
|
|||
const size_t memSize = GetMemorySize(in_Length);
|
||||
const size_t memSizeAligned = GetMemorySizeAligned(in_Length);
|
||||
|
||||
SStringHolder* pHolder = (SStringHolder*)__HH_ALLOC(memSizeAligned);
|
||||
auto pHolder = (SStringHolder*)__HH_ALLOC(memSizeAligned);
|
||||
pHolder->RefCount = 1;
|
||||
pHolder->Length = (uint16_t)in_Length;
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@
|
|||
#include "SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h"
|
||||
#include "SWA/Player/Character/EvilSonic/EvilSonic.h"
|
||||
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"
|
||||
#include "SWA/System/GameMode/Title/TitleMenu.h"
|
||||
#include "SWA/System/GameMode/Title/TitleStateBase.h"
|
||||
#include "SWA/System/ApplicationDocument.h"
|
||||
#include "SWA/System/GameDocument.h"
|
||||
#include "SWA/System/InputState.h"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ namespace SWA::Player
|
|||
SWA_INSERT_PADDING(0x14D);
|
||||
bool m_IsShown;
|
||||
bool m_IsVisible;
|
||||
EGuideType m_GuideType;
|
||||
be<EGuideType> m_GuideType;
|
||||
};
|
||||
}
|
||||
|
|
|
|||
13
UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h
Normal file
13
UnleashedRecomp/api/SWA/System/GameMode/Title/TitleMenu.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <SWA.inl>
|
||||
|
||||
namespace SWA
|
||||
{
|
||||
class CTitleMenu
|
||||
{
|
||||
public:
|
||||
SWA_INSERT_PADDING(0x44);
|
||||
be<uint32_t> m_CursorIndex;
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <SWA.inl>
|
||||
|
||||
namespace SWA
|
||||
{
|
||||
class CTitleStateBase // : Hedgehog::Universe::TStateMachine<SWA::CTitleManager>::TState
|
||||
{
|
||||
public:
|
||||
class CMember
|
||||
{
|
||||
public:
|
||||
SWA_INSERT_PADDING(0x1E8);
|
||||
xpointer<CTitleMenu> m_pTitleMenu;
|
||||
};
|
||||
|
||||
SWA_INSERT_PADDING(0x08);
|
||||
xpointer<CMember> m_pMember;
|
||||
SWA_INSERT_PADDING(0x5C);
|
||||
be<uint32_t> m_State;
|
||||
};
|
||||
}
|
||||
|
|
@ -30,8 +30,8 @@ public:
|
|||
CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::D3D12);
|
||||
CONFIG_DEFINE("Video", int32_t, WindowX, WINDOWPOS_CENTRED);
|
||||
CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED);
|
||||
CONFIG_DEFINE_LOCALISED("Video", int32_t, WindowWidth, 1280);
|
||||
CONFIG_DEFINE_LOCALISED("Video", int32_t, WindowHeight, 720);
|
||||
CONFIG_DEFINE("Video", int32_t, WindowWidth, 1280);
|
||||
CONFIG_DEFINE("Video", int32_t, WindowHeight, 720);
|
||||
CONFIG_DEFINE_ENUM("Video", EWindowState, WindowState, EWindowState::Normal);
|
||||
|
||||
CONFIG_DEFINE_CALLBACK("Video", float, ResolutionScale, 1.0f,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
#include "config_detail.h"
|
||||
|
||||
#define CONFIG_DEFINE_LOCALE(name) \
|
||||
inline static std::unordered_map<ELanguage, std::string> g_##name##_locale =
|
||||
|
||||
#define CONFIG_DEFINE_ENUM_LOCALE(type) \
|
||||
inline static std::unordered_map<ELanguage, std::unordered_map<type, std::string>> g_##type##_locale =
|
||||
|
||||
CONFIG_DEFINE_ENUM_LOCALE(bool)
|
||||
{
|
||||
{
|
||||
|
|
@ -135,14 +141,9 @@ CONFIG_DEFINE_LOCALE(WerehogBattleMusic)
|
|||
{ ELanguage::English, "Werehog Battle Theme" }
|
||||
};
|
||||
|
||||
CONFIG_DEFINE_LOCALE(WindowWidth)
|
||||
CONFIG_DEFINE_LOCALE(WindowSize)
|
||||
{
|
||||
{ ELanguage::English, "Window Width" }
|
||||
};
|
||||
|
||||
CONFIG_DEFINE_LOCALE(WindowHeight)
|
||||
{
|
||||
{ ELanguage::English, "Window Height" }
|
||||
{ ELanguage::English, "Window Size" }
|
||||
};
|
||||
|
||||
CONFIG_DEFINE_LOCALE(ResolutionScale)
|
||||
|
|
|
|||
133
UnleashedRecomp/patches/ui/CHudPause_patches.cpp
Normal file
133
UnleashedRecomp/patches/ui/CHudPause_patches.cpp
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
#include <cpu/guest_code.h>
|
||||
#include <kernel/function.h>
|
||||
#include <api/SWA.h>
|
||||
#include <ui/options_menu.h>
|
||||
|
||||
bool m_isOptionsFromPause = false;
|
||||
|
||||
void CHudPauseAddOptionsItemMidAsmHook(PPCRegister& pThis)
|
||||
{
|
||||
auto pStrMemory = __HH_ALLOC(8);
|
||||
|
||||
auto menu = Hedgehog::Base::CSharedString("TopMenu");
|
||||
auto name = Hedgehog::Base::CSharedString("option");
|
||||
|
||||
// TODO: replace with wrapper to put these into guest memory.
|
||||
memcpy(pStrMemory, &menu, 4);
|
||||
memcpy((void*)((size_t)pStrMemory + 4), &name, 4);
|
||||
|
||||
GuestToHostFunction<int>(0x824AE690, pThis.u32, pStrMemory, (void*)((size_t)pStrMemory + 4));
|
||||
|
||||
__HH_FREE(pStrMemory);
|
||||
}
|
||||
|
||||
bool InjectOptionsBehaviour(uint32_t pThis, uint32_t count, uint32_t exitType = 2, uint32_t transitionType = 2)
|
||||
{
|
||||
auto status = *(be<uint32_t>*)g_memory.Translate(pThis + 0x190);
|
||||
auto pauseType = *(be<uint32_t>*)g_memory.Translate(pThis + 0x18C);
|
||||
auto cursorIndex = *(be<uint32_t>*)g_memory.Translate(4 * (*(be<uint32_t>*)g_memory.Translate(pThis + 0x19C) + 0x68) + pThis);
|
||||
|
||||
/*
|
||||
0 ---- Undefined
|
||||
1 ---- Status
|
||||
2 ---- Return to Previous Area
|
||||
3 ---- Inventory
|
||||
4 ---- Skills
|
||||
5 ---- Go to the Lab
|
||||
6 ---- Return to World Map
|
||||
7 ---- Undefined
|
||||
8 ---- Restart Stage
|
||||
9 ---- Continue Stage
|
||||
<=10 - Undefined
|
||||
*/
|
||||
auto pExitType = (be<uint32_t>*)g_memory.Translate(pThis + 0x188);
|
||||
|
||||
/*
|
||||
0 --- Undefined
|
||||
1 --- Unknown menu
|
||||
2 --- Quit menu
|
||||
3 --- Pause menu?
|
||||
4 --- Undefined
|
||||
5 --- Make cursor small?
|
||||
6 --- Hide UI and ignore face buttons
|
||||
7 --- Stop updating pause menu
|
||||
8 --- Hide UI (apart from pause header) and ignore face buttons
|
||||
<=9 - Stop updating pause menu
|
||||
*/
|
||||
auto pTransitionType = (be<uint32_t>*)g_memory.Translate(pThis + 0x194);
|
||||
|
||||
if (status == 1)
|
||||
{
|
||||
if (cursorIndex == count - 2)
|
||||
{
|
||||
OptionsMenu::Open(pauseType);
|
||||
m_isOptionsFromPause = true;
|
||||
|
||||
*pExitType = 0;
|
||||
*pTransitionType = 6;
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (cursorIndex == count - 1)
|
||||
{
|
||||
*pExitType = exitType;
|
||||
*pTransitionType = transitionType;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CHudPauseItemCountMidAsmHook(PPCRegister& pThis, PPCRegister& count)
|
||||
{
|
||||
count.u32 += 1;
|
||||
|
||||
return InjectOptionsBehaviour(pThis.u32, count.u32);
|
||||
}
|
||||
|
||||
bool CHudPauseHubItemCountMidAsmHook(PPCRegister& pThis, PPCRegister& count)
|
||||
{
|
||||
count.u32 += 1;
|
||||
|
||||
return InjectOptionsBehaviour(pThis.u32, count.u32, 2, 6);
|
||||
}
|
||||
|
||||
bool CHudPauseMiscItemCountMidAsmHook(PPCRegister& count)
|
||||
{
|
||||
if (count.u32 < 3)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CHudPauseMiscInjectOptionsMidAsmHook(PPCRegister& pThis)
|
||||
{
|
||||
return InjectOptionsBehaviour(pThis.u32, 3);
|
||||
}
|
||||
|
||||
// SWA::CHudPause::Update
|
||||
PPC_FUNC_IMPL(__imp__sub_824B0930);
|
||||
PPC_FUNC(sub_824B0930)
|
||||
{
|
||||
if (!OptionsMenu::s_isVisible || !m_isOptionsFromPause)
|
||||
{
|
||||
__imp__sub_824B0930(ctx, base);
|
||||
return;
|
||||
}
|
||||
|
||||
auto pauseType = *(be<uint32_t>*)g_memory.Translate(ctx.r3.u32 + 0x18C);
|
||||
|
||||
if (auto pInputState = SWA::CInputState::GetInstance())
|
||||
{
|
||||
// TODO: disable Start button closing menu.
|
||||
if (pInputState->GetPadState().IsTapped(SWA::eKeyState_B))
|
||||
{
|
||||
OptionsMenu::Close(pauseType);
|
||||
m_isOptionsFromPause = false;
|
||||
|
||||
GuestToHostFunction<int>(0x824AFD28, ctx.r3.u32, 0, 0, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
29
UnleashedRecomp/patches/ui/CTitleMenu_patches.cpp
Normal file
29
UnleashedRecomp/patches/ui/CTitleMenu_patches.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include <cpu/guest_code.h>
|
||||
#include <api/SWA.h>
|
||||
#include <ui/options_menu.h>
|
||||
|
||||
// SWA::CTitleStateMenu::Update
|
||||
PPC_FUNC_IMPL(__imp__sub_825882B8);
|
||||
PPC_FUNC(sub_825882B8)
|
||||
{
|
||||
auto pTitleState = (SWA::CTitleStateBase*)g_memory.Translate(ctx.r3.u32);
|
||||
auto pInputState = SWA::CInputState::GetInstance();
|
||||
auto isOptionsIndex = pTitleState->m_pMember->m_pTitleMenu->m_CursorIndex == 2;
|
||||
|
||||
if (pInputState && isOptionsIndex)
|
||||
{
|
||||
// TODO: play sys_worldmap_decide.
|
||||
if (pInputState->GetPadState().IsTapped(SWA::eKeyState_A))
|
||||
OptionsMenu::Open();
|
||||
}
|
||||
|
||||
if (!OptionsMenu::s_isVisible)
|
||||
__imp__sub_825882B8(ctx, base);
|
||||
|
||||
if (pInputState && isOptionsIndex)
|
||||
{
|
||||
// TODO: play sys_worldmap_cancel (could be "cansel" instead).
|
||||
if (pInputState->GetPadState().IsTapped(SWA::eKeyState_B))
|
||||
OptionsMenu::Close();
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "kernel/memory.h"
|
||||
#include "ui/sdl_listener.h"
|
||||
#include "ui/options_menu.h"
|
||||
|
||||
class FrontendListener : public SDLEventListener
|
||||
{
|
||||
|
|
@ -10,6 +11,9 @@ class FrontendListener : public SDLEventListener
|
|||
public:
|
||||
void OnSDLEvent(SDL_Event* event) override
|
||||
{
|
||||
if (OptionsMenu::s_isVisible)
|
||||
return;
|
||||
|
||||
switch (event->type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
|
|
|
|||
|
|
@ -414,32 +414,54 @@ static void DrawConfigOptions()
|
|||
|
||||
void OptionsMenu::Draw()
|
||||
{
|
||||
g_callbackDataIndex = 0;
|
||||
if (!s_isVisible)
|
||||
return;
|
||||
|
||||
g_callbackDataIndex = 0;
|
||||
|
||||
auto& res = ImGui::GetIO().DisplaySize;
|
||||
auto drawList = ImGui::GetForegroundDrawList();
|
||||
|
||||
//drawList->AddRectFilled({ 0.0f, 0.0f }, res, IM_COL32(0, 0, 0, 223));
|
||||
|
||||
//*(bool*)g_memory.Translate(0x8328BB26) = false;
|
||||
|
||||
|
||||
if (s_isDimBackground)
|
||||
drawList->AddRectFilled({ 0.0f, 0.0f }, res, IM_COL32(0, 0, 0, 127));
|
||||
|
||||
DrawScanlineBars();
|
||||
|
||||
|
||||
constexpr float CONTAINER_POS_X = 236.0f;
|
||||
constexpr float CONTAINER_POS_Y = 118.0f;
|
||||
|
||||
ImVec2 min = { Scale(AlignToNextGrid(CONTAINER_POS_X)), Scale(AlignToNextGrid(CONTAINER_POS_Y)) };
|
||||
ImVec2 max = { Scale(AlignToNextGrid(1280.0f - CONTAINER_POS_X)), Scale(AlignToNextGrid(720.0f - CONTAINER_POS_Y)) };
|
||||
|
||||
|
||||
DrawContainer(min, max);
|
||||
|
||||
|
||||
DrawCategories();
|
||||
|
||||
|
||||
DrawConfigOptions();
|
||||
|
||||
|
||||
// Pop clip rect from DrawCategories
|
||||
drawList->PopClipRect();
|
||||
|
||||
|
||||
// Pop clip rect from DrawContainer
|
||||
drawList->PopClipRect();
|
||||
}
|
||||
|
||||
void OptionsMenu::Open(bool stage)
|
||||
{
|
||||
s_isVisible = true;
|
||||
s_isDimBackground = stage;
|
||||
|
||||
*(bool*)g_memory.Translate(0x8328BB26) = false;
|
||||
|
||||
// TODO: animate Miles Electric in if we're in a stage.
|
||||
}
|
||||
|
||||
void OptionsMenu::Close(bool stage)
|
||||
{
|
||||
s_isVisible = false;
|
||||
s_isDimBackground = stage;
|
||||
|
||||
*(bool*)g_memory.Translate(0x8328BB26) = true;
|
||||
|
||||
// TODO: animate Miles Electric out if we're in a stage.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@
|
|||
|
||||
struct OptionsMenu
|
||||
{
|
||||
public:
|
||||
inline static bool s_isVisible = false;
|
||||
inline static bool s_isDimBackground = false;
|
||||
|
||||
static void Init();
|
||||
static void Draw();
|
||||
static void Open(bool stage = false);
|
||||
static void Close(bool stage = false);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -422,3 +422,82 @@ registers = ["r7"]
|
|||
name = "LoadingScreenSpeedFixMidAsmHook"
|
||||
address = 0x824DAB60
|
||||
registers = ["r4"]
|
||||
|
||||
# World Map Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseAddOptionsItemMidAsmHook"
|
||||
address = 0x824AF140
|
||||
registers = ["r31"]
|
||||
|
||||
# Village Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseAddOptionsItemMidAsmHook"
|
||||
address = 0x824AF430
|
||||
registers = ["r31"]
|
||||
|
||||
# Stage Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseAddOptionsItemMidAsmHook"
|
||||
address = 0x824AF988
|
||||
registers = ["r31"]
|
||||
|
||||
# Hub Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseAddOptionsItemMidAsmHook"
|
||||
address = 0x824AFB20
|
||||
registers = ["r31"]
|
||||
|
||||
# Misc Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseAddOptionsItemMidAsmHook"
|
||||
address = 0x824AFCC8
|
||||
registers = ["r31"]
|
||||
|
||||
# World Map Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseItemCountMidAsmHook"
|
||||
address = 0x824B02F8
|
||||
registers = ["r3", "r11"]
|
||||
return_on_true = true
|
||||
|
||||
# Village Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseItemCountMidAsmHook"
|
||||
address = 0x824B04AC
|
||||
registers = ["r31", "r10"]
|
||||
return_on_true = true
|
||||
|
||||
# Stage Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseItemCountMidAsmHook"
|
||||
address = 0x824B061C
|
||||
registers = ["r3", "r11"]
|
||||
return_on_true = true
|
||||
|
||||
# Hub Pause Menu
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseHubItemCountMidAsmHook"
|
||||
address = 0x824B07C4
|
||||
registers = ["r3", "r10"]
|
||||
return_on_true = true
|
||||
|
||||
# Misc Pause Menu Index Wrap-around
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseItemCountMidAsmHook"
|
||||
address = 0x824B08A8
|
||||
registers = ["r3", "r11"]
|
||||
return_on_true = true
|
||||
|
||||
# Misc Pause Menu Index Comparison
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseMiscItemCountMidAsmHook"
|
||||
address = 0x824B08B0
|
||||
registers = ["r11"]
|
||||
jump_address_on_true = 0x824B08C0
|
||||
|
||||
# Misc Pause Menu Inject Options Behaviour
|
||||
[[midasm_hook]]
|
||||
name = "CHudPauseMiscInjectOptionsMidAsmHook"
|
||||
address = 0x824B08C0
|
||||
registers = ["r3"]
|
||||
return_on_true = true
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue