options_menu: implemented greyed out options and localisation

This commit is contained in:
Hyper 2024-11-21 01:34:10 +00:00
parent 49b6b0e262
commit 1f7f093e22
12 changed files with 300 additions and 181 deletions

View file

@ -36,6 +36,7 @@
#include "SWA/CSD/CsdProject.h"
#include "SWA/CSD/CsdTexListMirage.h"
#include "SWA/CSD/GameObjectCSD.h"
#include "SWA/HUD/Pause/HudPause.h"
#include "SWA/Player/Character/EvilSonic/Hud/EvilHudGuide.h"
#include "SWA/Player/Character/EvilSonic/EvilSonic.h"
#include "SWA/Player/Character/EvilSonic/EvilSonicContext.h"

View file

@ -0,0 +1,55 @@
#pragma once
#include <SWA.inl>
namespace SWA
{
enum EActionType : uint32_t
{
eActionType_Undefined,
eActionType_Status,
eActionType_Return,
eActionType_Inventory,
eActionType_Skills,
eActionType_Lab,
eActionType_Wait,
eActionType_Restart = 8,
eActionType_Continue
};
enum EMenuType : uint32_t
{
eMenuType_WorldMap,
eMenuType_Village,
eMenuType_Stage,
eMenuType_Hub,
eMenuType_Misc
};
enum EStatusType : uint32_t
{
eStatusType_Idle,
eStatusType_Accept,
eStatusType_Decline
};
enum ETransitionType : uint32_t
{
eTransitionType_Undefined,
eTransitionType_Quit = 2,
eTransitionType_Dialog = 5,
eTransitionType_Hide,
eTransitionType_Abort,
eTransitionType_SubMenu
};
class CHudPause : public CGameObject
{
public:
SWA_INSERT_PADDING(0xC8);
be<EActionType> m_Action;
be<EMenuType> m_Menu;
be<EStatusType> m_Status;
be<ETransitionType> m_Transition;
};
}

View file

@ -15,7 +15,7 @@ PPC_FUNC(sub_822C1130)
SDL_FlushEvents(SDL_FIRSTEVENT, SDL_LASTEVENT);
Window::Update();
audio_patches::Update(g_deltaTime);
AudioPatches::Update(g_deltaTime);
__imp__sub_822C1130(ctx, base);
}

View file

@ -1,8 +1,8 @@
#pragma once
#include "config_detail.h"
#include "config_locale.h"
#include "exports.h"
#include <cfg/config_detail.h>
#include <locale/config_locale.h>
#include <exports.h>
class Config
{

View file

@ -1,6 +1,6 @@
#pragma once
#include "config_detail.h"
#include <cfg/config_detail.h>
#define CONFIG_DEFINE_LOCALE(name) \
inline static std::unordered_map<ELanguage, std::tuple<std::string, std::string>> g_##name##_locale =

View file

@ -0,0 +1,65 @@
#pragma once
#include <cfg/config.h>
inline static std::string g_localeMissing = "<missing string>";
inline static std::unordered_map<std::string, std::unordered_map<ELanguage, std::string>> g_locale
{
{
"Options_Category_System",
{
{ ELanguage::English, "SYSTEM" }
}
},
{
"Options_Category_Input",
{
{ ELanguage::English, "INPUT" }
}
},
{
"Options_Category_Audio",
{
{ ELanguage::English, "AUDIO" }
}
},
{
"Options_Category_Video",
{
{ ELanguage::English, "VIDEO" }
}
},
{
"Options_Value_Max",
{
{ ELanguage::English, "MAX" }
}
},
{
"Options_Desc_NotAvailable",
{
{ ELanguage::English, "This option is not available at this location." }
}
}
};
static std::string& Localise(const char* key)
{
if (!g_locale.count(key))
return g_localeMissing;
if (!g_locale[key].count(Config::Language))
{
if (g_locale[key].count(ELanguage::English))
{
return g_locale[key][ELanguage::English];
}
else
{
return g_localeMissing;
}
}
return g_locale[key][Config::Language];
}

View file

@ -14,7 +14,7 @@ be<float>* GetVolume(bool isMusic = true)
return (be<float>*)g_memory.Translate(4 * ((int)isMusic + 0x1C) + ((be<uint32_t>*)g_memory.Translate(ppUnkClass->get() + 4))->get());
}
void audio_patches::Update(float deltaTime)
void AudioPatches::Update(float deltaTime)
{
auto pMusicVolume = GetVolume();
auto pSEVolume = GetVolume(false);

View file

@ -1,6 +1,6 @@
#pragma once
class audio_patches
class AudioPatches
{
public:
static void Update(float deltaTime);

View file

@ -3,8 +3,6 @@
#include <api/SWA.h>
#include <ui/options_menu.h>
bool m_isOptionsFromPause = false;
void CHudPauseAddOptionsItemMidAsmHook(PPCRegister& pThis)
{
auto pStrMemory = __HH_ALLOC(8);
@ -23,74 +21,43 @@ void CHudPauseAddOptionsItemMidAsmHook(PPCRegister& pThis)
bool InjectOptionsBehaviour(uint32_t pThis, uint32_t count)
{
auto status = *(be<uint32_t>*)g_memory.Translate(pThis + 0x190);
auto pauseType = *(be<uint32_t>*)g_memory.Translate(pThis + 0x18C);
auto pHudPause = (SWA::CHudPause*)g_memory.Translate(pThis);
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 ---- Wait until Day/Night
7 ---- Undefined
8 ---- Restart Stage
9 ---- Continue Stage
<=10 - Undefined
*/
auto pExitType = (be<uint32_t>*)g_memory.Translate(pThis + 0x188);
auto exitType = SWA::eActionType_Undefined;
auto transitionType = SWA::eTransitionType_Undefined;
/*
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);
auto exitType = 0;
auto transitionType = 0;
switch (pauseType)
switch (pHudPause->m_Menu)
{
case 0: // World Map
case 2: // Stage
case 4: // Misc
exitType = 2;
transitionType = 2;
case SWA::eMenuType_WorldMap:
case SWA::eMenuType_Stage:
case SWA::eMenuType_Misc:
exitType = SWA::eActionType_Return;
transitionType = SWA::eTransitionType_Quit;
break;
case 1: // Village
case 3: // Hub
exitType = 2;
transitionType = 6;
case SWA::eMenuType_Village:
case SWA::eMenuType_Hub:
exitType = SWA::eActionType_Return;
transitionType = SWA::eTransitionType_Hide;
break;
}
if (status == 1)
if (pHudPause->m_Status == SWA::eStatusType_Accept)
{
if (cursorIndex == count - 2)
{
OptionsMenu::Open(pauseType);
m_isOptionsFromPause = true;
OptionsMenu::Open(true, pHudPause->m_Menu);
*pExitType = 0;
*pTransitionType = 6;
pHudPause->m_Action = SWA::eActionType_Undefined;
pHudPause->m_Transition = SWA::eTransitionType_Hide;
return true;
}
else if (cursorIndex == count - 1)
{
*pExitType = exitType;
*pTransitionType = transitionType;
pHudPause->m_Action = exitType;
pHudPause->m_Transition = transitionType;
return true;
}
@ -130,21 +97,18 @@ bool CHudPauseMiscInjectOptionsMidAsmHook(PPCRegister& pThis)
PPC_FUNC_IMPL(__imp__sub_824B0930);
PPC_FUNC(sub_824B0930)
{
if (!OptionsMenu::s_isVisible || !m_isOptionsFromPause)
if (!OptionsMenu::s_isVisible || !OptionsMenu::s_isPause)
{
__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 (OptionsMenu::CanClose() && pInputState->GetPadState().IsTapped(SWA::eKeyState_B))
{
OptionsMenu::Close(pauseType);
m_isOptionsFromPause = false;
OptionsMenu::Close();
// Re-open pause menu.
GuestToHostFunction<int>(0x824AFD28, ctx.r3.u32, 0, 0, 0, 1);

View file

@ -17,6 +17,7 @@ PPC_FUNC(sub_825882B8)
{
Game_PlaySound("sys_worldmap_window");
Game_PlaySound("sys_worldmap_decide");
OptionsMenu::Open();
}
}
@ -29,6 +30,7 @@ PPC_FUNC(sub_825882B8)
if (OptionsMenu::CanClose() && pInputState->GetPadState().IsTapped(SWA::eKeyState_B))
{
Game_PlaySound("sys_worldmap_cansel");
OptionsMenu::Close();
}
}

View file

@ -6,6 +6,7 @@
#include <gpu/imgui_common.h>
#include <kernel/heap.h>
#include <kernel/memory.h>
#include <locale/locale.h>
constexpr float COMMON_PADDING_POS_Y = 118.0f;
constexpr float COMMON_PADDING_POS_X = 30.0f;
@ -16,6 +17,7 @@ static ImFont* g_dfsogeistdFont;
static ImFont* g_newRodinFont;
static const IConfigDef* g_selectedItem;
static bool g_isSelectedItemAccessible;
static bool g_isEnterKeyBuffered = false;
@ -151,7 +153,7 @@ static void DrawScanlineBars()
auto& res = ImGui::GetIO().DisplaySize;
auto drawList = ImGui::GetForegroundDrawList();
if (OptionsMenu::s_isStage)
if (OptionsMenu::s_pauseMenuType != SWA::eMenuType_WorldMap)
{
// Top bar fade
drawList->AddRectFilledMultiColor(
@ -291,19 +293,23 @@ static void DrawContainer(ImVec2 min, ImVec2 max)
drawList->PushClipRect({ min.x + gridSize * 2.0f, min.y + gridSize * 2.0f }, { max.x - gridSize * 2.0f + 1.0f, max.y - gridSize * 2.0f + 1.0f });
}
// TODO: localise this.
static constexpr const char* CATEGORIES[] =
{
"SYSTEM",
"INPUT",
"AUDIO",
"VIDEO"
};
static int32_t g_categoryCount = 4;
static int32_t g_categoryIndex;
static ImVec2 g_categoryAnimMin;
static ImVec2 g_categoryAnimMax;
static std::string& GetCategory(int index)
{
// TODO: Don't use raw numbers here!
switch (index)
{
case 0: return Localise("Options_Category_System");
case 1: return Localise("Options_Category_Input");
case 2: return Localise("Options_Category_Audio");
case 3: return Localise("Options_Category_Video");
}
}
static int32_t g_firstVisibleRowIndex;
static int32_t g_prevSelectedRowIndex;
static int32_t g_selectedRowIndex;
@ -352,12 +358,12 @@ static bool DrawCategories()
{
--g_categoryIndex;
if (g_categoryIndex < 0)
g_categoryIndex = std::size(CATEGORIES) - 1;
g_categoryIndex = g_categoryCount - 1;
}
else if (moveRight)
{
++g_categoryIndex;
if (g_categoryIndex >= std::size(CATEGORIES))
if (g_categoryIndex >= g_categoryCount)
g_categoryIndex = 0;
}
@ -376,22 +382,22 @@ static bool DrawCategories()
float tabPadding = gridSize;
float size = Scale(32.0f);
ImVec2 textSizes[std::size(CATEGORIES)];
ImVec2 textSizes[g_categoryCount];
float tabWidthSum = 0.0f;
for (size_t i = 0; i < std::size(CATEGORIES); i++)
for (size_t i = 0; i < g_categoryCount; i++)
{
textSizes[i] = g_dfsogeistdFont->CalcTextSizeA(size, FLT_MAX, 0.0f, CATEGORIES[i]);
textSizes[i] = g_dfsogeistdFont->CalcTextSizeA(size, FLT_MAX, 0.0f, GetCategory(i).c_str());
tabWidthSum += textSizes[i].x + textPadding * 2.0f;
}
tabWidthSum += (std::size(CATEGORIES) - 1) * tabPadding;
tabWidthSum += (g_categoryCount - 1) * tabPadding;
float tabHeight = gridSize * 4.0f;
float xOffset = ((clipRectMax.x - clipRectMin.x) - tabWidthSum) / 2.0f;
xOffset -= (1.0 - motion) * gridSize * 4.0;
ImVec2 minVec[std::size(CATEGORIES)];
ImVec2 minVec[g_categoryCount];
for (size_t i = 0; i < std::size(CATEGORIES); i++)
for (size_t i = 0; i < g_categoryCount; i++)
{
ImVec2 min = { clipRectMin.x + xOffset, clipRectMin.y };
@ -454,7 +460,7 @@ static bool DrawCategories()
minVec[i] = min;
}
for (size_t i = 0; i < std::size(CATEGORIES); i++)
for (size_t i = 0; i < g_categoryCount; i++)
{
auto& min = minVec[i];
uint8_t alpha = (i == g_categoryIndex ? 235 : 128) * motion;
@ -470,7 +476,7 @@ static bool DrawCategories()
size,
min,
IM_COL32_WHITE,
CATEGORIES[i],
GetCategory(i).c_str(),
Scale(3),
IM_COL32_BLACK);
@ -490,16 +496,13 @@ static bool DrawCategories()
extern void VideoConfigValueChangedCallback(IConfigDef* config);
template<typename T>
static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* config, T valueMin = T(0), T valueCenter = T(0.5), T valueMax = T(1))
static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* config, bool isAccessible, T valueMin = T(0), T valueCenter = T(0.5), T valueMax = T(1))
{
auto drawList = ImGui::GetForegroundDrawList();
auto clipRectMin = drawList->GetClipRectMin();
auto clipRectMax = drawList->GetClipRectMax();
auto& padState = SWA::CInputState::GetInstance()->GetPadState();
constexpr ImU32 COLOR0 = IM_COL32(0xE2, 0x71, 0x22, 0x80);
constexpr ImU32 COLOR1 = IM_COL32(0x92, 0xFF, 0x31, 0x80);
auto gridSize = Scale(GRID_SIZE);
auto optionWidth = gridSize * 54.0f;
auto optionHeight = gridSize * 5.5f;
@ -524,8 +527,11 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
if (g_selectedRowIndex == rowIndex)
{
g_selectedItem = config;
g_isSelectedItemAccessible = isAccessible;
if (!g_isEnterKeyBuffered)
{
if (isAccessible)
{
if constexpr (std::is_same_v<T, bool>)
{
@ -548,6 +554,7 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
if (padState.IsTapped(SWA::eKeyState_A))
{
g_lockedOnOption ^= true;
if (g_lockedOnOption)
{
g_leftWasHeld = false;
@ -578,10 +585,17 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
lockedOnOption = g_lockedOnOption;
}
}
else
{
if (padState.IsTapped(SWA::eKeyState_A))
Game_PlaySound("sys_actstg_stateserror");
}
}
}
bool fadedOut = g_lockedOnOption && g_selectedItem != config;
float alpha = fadedOut ? 0.5f : 1.0f;
auto fadedOut = (g_lockedOnOption && g_selectedItem != config) || !isAccessible;
auto alpha = fadedOut ? 0.5f : 1.0f;
auto textColour = IM_COL32(255, 255, 255, 255 * alpha);
if (g_selectedItem == config)
{
@ -589,13 +603,16 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
double animRatio = std::clamp((ImGui::GetTime() - g_rowSelectionTime) * 60.0 / 8.0, 0.0, 1.0);
prevItemOffset *= pow(1.0 - animRatio, 3.0);
drawList->AddRectFilledMultiColor({ min.x, min.y + prevItemOffset }, { max.x, max.y + prevItemOffset }, COLOR0, COLOR0, COLOR1, COLOR1);
auto c0 = IM_COL32(0xE2, 0x71, 0x22, isAccessible ? 0x80 : 0x30);
auto c1 = IM_COL32(0x92, 0xFF, 0x31, isAccessible ? 0x80 : 0x30);
DrawTextWithMarquee(g_seuratFont, size, textPos, min, max, IM_COL32_WHITE, configName.c_str(), g_rowSelectionTime, 0.9, 250.0);
drawList->AddRectFilledMultiColor({ min.x, min.y + prevItemOffset }, { max.x, max.y + prevItemOffset }, c0, c0, c1, c1);
DrawTextWithMarquee(g_seuratFont, size, textPos, min, max, textColour, configName.c_str(), g_rowSelectionTime, 0.9, 250.0);
}
else
{
drawList->AddText(g_seuratFont, size, textPos, IM_COL32(255, 255, 255, 255 * alpha), configName.c_str(), 0, 0.0f, &textClipRect);
drawList->AddText(g_seuratFont, size, textPos, textColour, configName.c_str(), 0, 0.0f, &textClipRect);
}
// Right side
@ -773,7 +790,7 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
if constexpr (std::is_same_v<T, float>)
valueText = std::format("{}%", int32_t(round(config->Value * 100.0f)));
else if constexpr (std::is_same_v<T, int32_t>)
valueText = config->Value >= valueMax ? "MAX" : std::format("{}", config->Value);
valueText = config->Value >= valueMax ? Localise("Options_Value_Max") : std::format("{}", config->Value);
else
valueText = config->GetValueLocalised();
@ -816,48 +833,50 @@ static void DrawConfigOptions()
int32_t rowCount = 0;
bool isStage = OptionsMenu::s_pauseMenuType == SWA::eMenuType_Stage || OptionsMenu::s_pauseMenuType == SWA::eMenuType_Hub;
// TODO: Don't use raw numbers here!
switch (g_categoryIndex)
{
case 0: // SYSTEM
DrawConfigOption(rowCount++, yOffset, &Config::Language);
DrawConfigOption(rowCount++, yOffset, &Config::Hints);
DrawConfigOption(rowCount++, yOffset, &Config::ControlTutorial);
DrawConfigOption(rowCount++, yOffset, &Config::SaveScoreAtCheckpoints);
DrawConfigOption(rowCount++, yOffset, &Config::UnleashGaugeBehaviour);
DrawConfigOption(rowCount++, yOffset, &Config::WerehogHubTransformVideo);
DrawConfigOption(rowCount++, yOffset, &Config::LogoSkip);
DrawConfigOption(rowCount++, yOffset, &Config::Language, !OptionsMenu::s_isPause);
DrawConfigOption(rowCount++, yOffset, &Config::Hints, !isStage);
DrawConfigOption(rowCount++, yOffset, &Config::ControlTutorial, !isStage);
DrawConfigOption(rowCount++, yOffset, &Config::SaveScoreAtCheckpoints, true);
DrawConfigOption(rowCount++, yOffset, &Config::UnleashGaugeBehaviour, true);
DrawConfigOption(rowCount++, yOffset, &Config::WerehogHubTransformVideo, true);
DrawConfigOption(rowCount++, yOffset, &Config::LogoSkip, true);
break;
case 1: // INPUT
DrawConfigOption(rowCount++, yOffset, &Config::CameraXInvert);
DrawConfigOption(rowCount++, yOffset, &Config::CameraYInvert);
DrawConfigOption(rowCount++, yOffset, &Config::XButtonHoming);
DrawConfigOption(rowCount++, yOffset, &Config::UnleashCancel);
DrawConfigOption(rowCount++, yOffset, &Config::BackgroundInput);
DrawConfigOption(rowCount++, yOffset, &Config::CameraXInvert, true);
DrawConfigOption(rowCount++, yOffset, &Config::CameraYInvert, true);
DrawConfigOption(rowCount++, yOffset, &Config::XButtonHoming, !OptionsMenu::s_isPause); // TODO: make this editable in stages.
DrawConfigOption(rowCount++, yOffset, &Config::UnleashCancel, true);
DrawConfigOption(rowCount++, yOffset, &Config::BackgroundInput, true);
break;
case 2: // AUDIO
DrawConfigOption(rowCount++, yOffset, &Config::MusicVolume);
DrawConfigOption(rowCount++, yOffset, &Config::SEVolume);
DrawConfigOption(rowCount++, yOffset, &Config::VoiceLanguage);
DrawConfigOption(rowCount++, yOffset, &Config::Subtitles);
DrawConfigOption(rowCount++, yOffset, &Config::WerehogBattleMusic);
DrawConfigOption(rowCount++, yOffset, &Config::MusicVolume, true);
DrawConfigOption(rowCount++, yOffset, &Config::SEVolume, true);
DrawConfigOption(rowCount++, yOffset, &Config::VoiceLanguage, true);
DrawConfigOption(rowCount++, yOffset, &Config::Subtitles, true);
DrawConfigOption(rowCount++, yOffset, &Config::WerehogBattleMusic, true);
break;
case 3: // VIDEO
// TODO: expose WindowWidth/WindowHeight as WindowSize.
DrawConfigOption(rowCount++, yOffset, &Config::ResolutionScale, 0.25f, 1.0f, 2.0f);
DrawConfigOption(rowCount++, yOffset, &Config::Fullscreen);
DrawConfigOption(rowCount++, yOffset, &Config::VSync);
DrawConfigOption(rowCount++, yOffset, &Config::TripleBuffering);
DrawConfigOption(rowCount++, yOffset, &Config::FPS, 15, 120, 240);
DrawConfigOption(rowCount++, yOffset, &Config::Brightness);
DrawConfigOption(rowCount++, yOffset, &Config::AntiAliasing);
DrawConfigOption(rowCount++, yOffset, &Config::AlphaToCoverage);
DrawConfigOption(rowCount++, yOffset, &Config::ShadowResolution);
DrawConfigOption(rowCount++, yOffset, &Config::GITextureFiltering);
DrawConfigOption(rowCount++, yOffset, &Config::MotionBlur);
DrawConfigOption(rowCount++, yOffset, &Config::Xbox360ColourCorrection);
DrawConfigOption(rowCount++, yOffset, &Config::MovieScaleMode);
DrawConfigOption(rowCount++, yOffset, &Config::UIScaleMode);
DrawConfigOption(rowCount++, yOffset, &Config::ResolutionScale, true, 0.25f, 1.0f, 2.0f);
DrawConfigOption(rowCount++, yOffset, &Config::Fullscreen, true);
DrawConfigOption(rowCount++, yOffset, &Config::VSync, true);
DrawConfigOption(rowCount++, yOffset, &Config::TripleBuffering, true);
DrawConfigOption(rowCount++, yOffset, &Config::FPS, true, 15, 120, 240);
DrawConfigOption(rowCount++, yOffset, &Config::Brightness, true);
DrawConfigOption(rowCount++, yOffset, &Config::AntiAliasing, true);
DrawConfigOption(rowCount++, yOffset, &Config::AlphaToCoverage, true);
DrawConfigOption(rowCount++, yOffset, &Config::ShadowResolution, true);
DrawConfigOption(rowCount++, yOffset, &Config::GITextureFiltering, true);
DrawConfigOption(rowCount++, yOffset, &Config::MotionBlur, true);
DrawConfigOption(rowCount++, yOffset, &Config::Xbox360ColourCorrection, true);
DrawConfigOption(rowCount++, yOffset, &Config::MovieScaleMode, true);
DrawConfigOption(rowCount++, yOffset, &Config::UIScaleMode, true);
break;
}
@ -974,6 +993,8 @@ static void DrawInfoPanel()
{
auto desc = g_selectedItem->GetDescription();
if (g_isSelectedItemAccessible)
{
// Specialised description for resolution scale
if (g_selectedItem->GetName() == "ResolutionScale")
{
@ -988,6 +1009,11 @@ static void DrawInfoPanel()
}
desc += "\n\n" + g_selectedItem->GetValueDescription();
}
else
{
desc = Localise("Options_Desc_NotAvailable");
}
auto size = Scale(26.0f);
@ -1022,7 +1048,7 @@ void OptionsMenu::Draw()
auto& res = ImGui::GetIO().DisplaySize;
auto drawList = ImGui::GetForegroundDrawList();
if (s_isStage)
if (s_isPause && s_pauseMenuType != SWA::eMenuType_WorldMap)
drawList->AddRectFilled({ 0.0f, 0.0f }, res, IM_COL32(0, 0, 0, 223));
DrawScanlineBars();
@ -1030,10 +1056,13 @@ void OptionsMenu::Draw()
DrawInfoPanel();
}
void OptionsMenu::Open(bool stage)
void OptionsMenu::Open(bool isPause, SWA::EMenuType pauseMenuType)
{
s_isVisible = true;
s_isStage = stage;
s_isPause = isPause;
s_pauseMenuType = pauseMenuType;
g_appearTime = ImGui::GetTime();
g_categoryIndex = 0;
g_categoryAnimMin = { 0.0f, 0.0f };
@ -1051,10 +1080,9 @@ void OptionsMenu::Open(bool stage)
// TODO: animate Miles Electric in if we're in a stage.
}
void OptionsMenu::Close(bool stage)
void OptionsMenu::Close()
{
s_isVisible = false;
s_isStage = stage;
*(bool*)g_memory.Translate(0x8328BB26) = true;

View file

@ -1,15 +1,19 @@
#pragma once
#include <api/SWA.h>
struct OptionsMenu
{
public:
inline static bool s_isVisible = false;
inline static bool s_isStage = false;
inline static bool s_isPause = false;
inline static SWA::EMenuType s_pauseMenuType;
static void Init();
static void Draw();
static void Open(bool stage = false);
static void Close(bool stage = false);
static void Open(bool isPause = false, SWA::EMenuType pauseMenuType = SWA::eMenuType_WorldMap);
static void Close();
static bool CanClose();
};