options_menu: find nearest window size on lock, intro transition fixes

This commit is contained in:
Hyper 2025-01-03 02:46:30 +00:00
parent 31fb63ad81
commit 0613dc6337
4 changed files with 39 additions and 31 deletions

View file

@ -181,6 +181,13 @@ void GameWindow::Init(const char* sdlVideoDriver)
SetProcessDPIAware(); SetProcessDPIAware();
#endif #endif
Config::WindowSize.LockCallback = [](ConfigDef<int32_t>* def)
{
// Try matching the current window size with a known configuration.
if (def->Value < 0)
def->Value = GameWindow::FindNearestDisplayMode();
};
Config::WindowSize.ApplyCallback = [](ConfigDef<int32_t>* def) Config::WindowSize.ApplyCallback = [](ConfigDef<int32_t>* def)
{ {
auto displayModes = GetDisplayModes(); auto displayModes = GetDisplayModes();
@ -519,19 +526,28 @@ std::vector<SDL_DisplayMode> GameWindow::GetDisplayModes(bool ignoreInvalidModes
return result; return result;
} }
int GameWindow::FindMatchingDisplayMode() int GameWindow::FindNearestDisplayMode()
{ {
auto result = -1;
auto displayModes = GetDisplayModes(); auto displayModes = GetDisplayModes();
auto currentDiff = std::numeric_limits<int>::max();
for (int i = 0; i < displayModes.size(); i++) for (int i = 0; i < displayModes.size(); i++)
{ {
auto& mode = displayModes[i]; auto& mode = displayModes[i];
if (mode.w == s_width && mode.h == s_height) auto widthDiff = abs(mode.w - s_width);
return i; auto heightDiff = abs(mode.h - s_height);
auto totalDiff = widthDiff + heightDiff;
if (totalDiff < currentDiff)
{
currentDiff = totalDiff;
result = i;
}
} }
return -1; return result;
} }
bool GameWindow::IsPositionValid() bool GameWindow::IsPositionValid()

View file

@ -44,7 +44,7 @@ public:
static int GetDisplay(); static int GetDisplay();
static void SetDisplay(int displayIndex); static void SetDisplay(int displayIndex);
static std::vector<SDL_DisplayMode> GetDisplayModes(bool ignoreInvalidModes = true, bool ignoreRefreshRates = true); static std::vector<SDL_DisplayMode> GetDisplayModes(bool ignoreInvalidModes = true, bool ignoreRefreshRates = true);
static int FindMatchingDisplayMode(); static int FindNearestDisplayMode();
static bool IsPositionValid(); static bool IsPositionValid();
static void Init(const char* sdlVideoDriver = nullptr); static void Init(const char* sdlVideoDriver = nullptr);
static void Update(); static void Update();

View file

@ -505,6 +505,9 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
// remember value // remember value
s_oldValue = config->Value; s_oldValue = config->Value;
if (config->LockCallback)
config->LockCallback(config);
Game_PlaySound("sys_worldmap_decide"); Game_PlaySound("sys_worldmap_decide");
} }
else else
@ -781,13 +784,9 @@ static void DrawConfigOption(int32_t rowIndex, float yOffset, ConfigDef<T>* conf
{ {
auto displayModes = GameWindow::GetDisplayModes(); auto displayModes = GameWindow::GetDisplayModes();
// Try matching the current window size with a known configuration.
if (config->Value < 0)
config->Value = GameWindow::FindMatchingDisplayMode();
if (config->Value >= 0 && config->Value < displayModes.size()) if (config->Value >= 0 && config->Value < displayModes.size())
{ {
auto displayMode = displayModes[config->Value]; auto& displayMode = displayModes[config->Value];
valueText = fmt::format("{}x{}", displayMode.w, displayMode.h); valueText = fmt::format("{}x{}", displayMode.w, displayMode.h);
} }
@ -1005,6 +1004,8 @@ static void DrawSettingsPanel()
if (DrawCategories()) if (DrawCategories())
{ {
DrawConfigOptions(); DrawConfigOptions();
g_isControlsVisible = true;
} }
else else
{ {
@ -1147,14 +1148,7 @@ static bool DrawFadeTransition()
if (scaleMotion < 0.8) if (scaleMotion < 0.8)
return false; return false;
if (fgAlphaOutMotion >= 1.0)
{
g_isControlsVisible = true;
}
else
{
drawList->AddRectFilled({ 0, 0 }, res, IM_COL32(0, 0, 0, Lerp(255, 0, fgAlphaOutMotion))); drawList->AddRectFilled({ 0, 0 }, res, IM_COL32(0, 0, 0, Lerp(255, 0, fgAlphaOutMotion)));
}
return fgAlphaOutMotion >= 1.0; return fgAlphaOutMotion >= 1.0;
} }
@ -1175,10 +1169,7 @@ void OptionsMenu::Init()
void OptionsMenu::Draw() void OptionsMenu::Draw()
{ {
if (!s_isVisible) if (!s_isVisible)
{
g_isControlsVisible = false;
return; return;
}
// We've entered the menu now, no need to check this. // We've entered the menu now, no need to check this.
auto pInputState = SWA::CInputState::GetInstance(); auto pInputState = SWA::CInputState::GetInstance();
@ -1190,10 +1181,6 @@ void OptionsMenu::Draw()
if (!DrawMilesElectric()) if (!DrawMilesElectric())
return; return;
} }
else
{
g_isControlsVisible = true;
}
if (!g_isClosing) if (!g_isClosing)
{ {
@ -1249,18 +1236,22 @@ void OptionsMenu::Open(bool isPause, SWA::EMenuType pauseMenuType)
void OptionsMenu::Close() void OptionsMenu::Close()
{ {
g_isClosing = true; if (!g_isClosing)
{
g_appearTime = ImGui::GetTime(); g_appearTime = ImGui::GetTime();
g_isControlsVisible = false;
g_isClosing = true;
ButtonGuide::Close();
Config::Save();
}
// Skip Miles Electric animation at main menu. // Skip Miles Electric animation at main menu.
if (!g_isStage) if (!g_isStage)
SetOptionsMenuVisible(false); SetOptionsMenuVisible(false);
ButtonGuide::Close();
Config::Save();
} }
bool OptionsMenu::CanClose() bool OptionsMenu::CanClose()
{ {
return !g_lockedOnOption; return !g_lockedOnOption && g_isControlsVisible;
} }

View file

@ -294,6 +294,7 @@ public:
std::map<T, std::string> EnumTemplateReverse{}; std::map<T, std::string> EnumTemplateReverse{};
CONFIG_ENUM_LOCALE(T)* EnumLocale{}; CONFIG_ENUM_LOCALE(T)* EnumLocale{};
std::function<void(ConfigDef<T>*)> Callback; std::function<void(ConfigDef<T>*)> Callback;
std::function<void(ConfigDef<T>*)> LockCallback;
std::function<void(ConfigDef<T>*)> ApplyCallback; std::function<void(ConfigDef<T>*)> ApplyCallback;
// CONFIG_DEFINE // CONFIG_DEFINE