From ec9b500c67952f619112990051751cd0721280be Mon Sep 17 00:00:00 2001 From: Niklas080208 Date: Fri, 2 Oct 2026 17:20:07 +0200 Subject: [PATCH] daybreak: Add a setting to bypass the firmware version check Let users turn off the Exosphere compatibility gate from the main menu when installing firmware newer than this Atmosphere build supports. --- troposphere/daybreak/source/ui.cpp | 96 ++++++++++++++++++++++++- troposphere/daybreak/source/ui.hpp | 22 +++++- troposphere/daybreak/source/ui_util.cpp | 21 ++++++ troposphere/daybreak/source/ui_util.hpp | 1 + 4 files changed, 135 insertions(+), 5 deletions(-) diff --git a/troposphere/daybreak/source/ui.cpp b/troposphere/daybreak/source/ui.cpp index 7afd444e6..56b07589a 100644 --- a/troposphere/daybreak/source/ui.cpp +++ b/troposphere/daybreak/source/ui.cpp @@ -49,6 +49,7 @@ namespace dbk { u32 g_screen_height; constinit u32 g_supported_version = std::numeric_limits::max(); + constinit bool g_hos_version_check_enabled = true; std::shared_ptr g_current_menu; bool g_initialized = false; @@ -153,6 +154,10 @@ namespace dbk { } bool IsHosVersionSupported(u32 hos_version) { + if (!g_hos_version_check_enabled) { + return true; + } + return hos_version <= g_supported_version; } @@ -536,8 +541,11 @@ namespace dbk { const float x = g_screen_width / 2.0f - WindowWidth / 2.0f; const float y = g_screen_height / 2.0f - WindowHeight / 2.0f; - this->AddButton(InstallButtonId, "Installieren", x + HorizontalInset, y + TitleGap, WindowWidth - HorizontalInset * 2, ButtonHeight); - this->AddButton(ExitButtonId, "Beenden", x + HorizontalInset, y + TitleGap + ButtonHeight + VerticalGap, WindowWidth - HorizontalInset * 2, ButtonHeight); + const float button_x = x + HorizontalInset; + const float button_w = WindowWidth - HorizontalInset * 2; + this->AddButton(InstallButtonId, "Installieren", button_x, y + TitleGap, button_w, ButtonHeight); + this->AddButton(SettingsButtonId, "Einstellungen", button_x, y + TitleGap + ButtonHeight + VerticalGap, button_w, ButtonHeight); + this->AddButton(ExitButtonId, "Beenden", button_x, y + TitleGap + (ButtonHeight + VerticalGap) * 2, button_w, ButtonHeight); this->SetButtonSelected(InstallButtonId, true); } @@ -585,6 +593,9 @@ namespace dbk { return; } + case SettingsButtonId: + ChangeMenu(std::make_shared(g_current_menu)); + return; case ExitButtonId: g_exit_requested = true; return; @@ -604,6 +615,87 @@ namespace dbk { this->DrawButtons(vg, ns); } + SettingsMenu::SettingsMenu(std::shared_ptr prev_menu) : Menu(prev_menu) { + const float x = g_screen_width / 2.0f - WindowWidth / 2.0f; + const float y = g_screen_height / 2.0f - WindowHeight / 2.0f; + const float button_x = x + HorizontalInset; + const float button_w = WindowWidth - HorizontalInset * 2.0f; + + this->AddButton(VersionCheckButtonId, "Firmware-Prüfung", button_x, y + TitleGap, button_w, ButtonHeight); + this->AddButton(BackButtonId, "Zurück", button_x, y + WindowHeight - BottomInset - ButtonHeight, button_w, ButtonHeight); + this->SetButtonSelected(VersionCheckButtonId, true); + } + + void SettingsMenu::Update(u64 ns) { + const u64 k_down = padGetButtonsDown(&g_pad); + + if (k_down & HidNpadButton_B) { + ReturnToPreviousMenu(); + return; + } + + if (const Button *activated_button = this->GetActivatedButton(); activated_button != nullptr) { + switch (activated_button->id) { + case VersionCheckButtonId: + g_hos_version_check_enabled = !g_hos_version_check_enabled; + break; + case BackButtonId: + ReturnToPreviousMenu(); + return; + } + } + + this->UpdateButtons(); + + if (const Button *selected_button = this->GetSelectedButton(); k_down && selected_button == nullptr) { + this->SetButtonSelected(VersionCheckButtonId, true); + } + } + + void SettingsMenu::Draw(NVGcontext *vg, u64 ns) { + const float x = g_screen_width / 2.0f - WindowWidth / 2.0f; + const float y = g_screen_height / 2.0f - WindowHeight / 2.0f; + + DrawWindow(vg, "Einstellungen", x, y, WindowWidth, WindowHeight); + + if (const Button *toggle = this->GetButton(VersionCheckButtonId); toggle != nullptr) { + const ButtonStyle style = toggle->selected ? ButtonStyle::StandardSelected : ButtonStyle::Standard; + DrawButton(vg, "", toggle->x, toggle->y, toggle->w, toggle->h, style, ns); + + nvgFontSize(vg, 20.0f); + nvgFontFace(vg, "switch-standard"); + nvgTextAlign(vg, NVG_ALIGN_LEFT | NVG_ALIGN_MIDDLE); + nvgFillColor(vg, toggle->selected ? nvgRGB(255, 255, 255) : nvgRGB(0, 0, 0)); + nvgText(vg, toggle->x + 16.0f, toggle->y + toggle->h * 0.5f, "Firmware-Prüfung", nullptr); + + constexpr float ToggleWidth = 64.0f; + constexpr float ToggleHeight = 32.0f; + DrawToggle(vg, + toggle->x + toggle->w - 16.0f - ToggleWidth, + toggle->y + (toggle->h - ToggleHeight) * 0.5f, + ToggleWidth, + ToggleHeight, + g_hos_version_check_enabled, + toggle->selected); + } + + char hint[64]; + const unsigned major = (g_supported_version >> 24) & 0xff; + const unsigned minor = (g_supported_version >> 16) & 0xff; + const unsigned micro = (g_supported_version >> 8) & 0xff; + if (g_hos_version_check_enabled) { + snprintf(hint, sizeof(hint), "Firmware <= %u.%u.%u", major, minor, micro); + } else { + snprintf(hint, sizeof(hint), "Auch Firmware > %u.%u.%u", major, minor, micro); + } + DrawText(vg, x + HorizontalInset, y + TitleGap + ButtonHeight + VerticalGap + 8.0f, WindowWidth - HorizontalInset * 2.0f, hint); + + if (const Button *back = this->GetButton(BackButtonId); back != nullptr) { + const ButtonStyle style = back->selected ? ButtonStyle::StandardSelected : ButtonStyle::Standard; + DrawButton(vg, "Zurück", back->x, back->y, back->w, back->h, style, ns); + } + } + FileMenu::FileMenu(std::shared_ptr prev_menu, const char *root) : Menu(prev_menu), m_current_index(0), m_scroll_offset(0), m_touch_start_scroll_offset(0), m_touch_finalize_selection(false) { Result rc = 0; diff --git a/troposphere/daybreak/source/ui.hpp b/troposphere/daybreak/source/ui.hpp index 8b08965a1..554ac3e1c 100644 --- a/troposphere/daybreak/source/ui.hpp +++ b/troposphere/daybreak/source/ui.hpp @@ -133,11 +133,12 @@ namespace dbk { class MainMenu : public Menu { private: - static constexpr u32 InstallButtonId = 0; - static constexpr u32 ExitButtonId = 1; + static constexpr u32 InstallButtonId = 0; + static constexpr u32 SettingsButtonId = 1; + static constexpr u32 ExitButtonId = 2; static constexpr float WindowWidth = 400.0f; - static constexpr float WindowHeight = 240.0f; + static constexpr float WindowHeight = 310.0f; static constexpr float TitleGap = 90.0f; public: MainMenu(); @@ -146,6 +147,21 @@ namespace dbk { virtual void Draw(NVGcontext *vg, u64 ns) override; }; + class SettingsMenu : public Menu { + private: + static constexpr u32 VersionCheckButtonId = 0; + static constexpr u32 BackButtonId = 1; + + static constexpr float WindowWidth = 560.0f; + static constexpr float WindowHeight = 300.0f; + static constexpr float TitleGap = 90.0f; + public: + SettingsMenu(std::shared_ptr prev_menu); + + virtual void Update(u64 ns) override; + virtual void Draw(NVGcontext *vg, u64 ns) override; + }; + class FileMenu : public Menu { private: struct FileEntry { diff --git a/troposphere/daybreak/source/ui_util.cpp b/troposphere/daybreak/source/ui_util.cpp index a177b1995..dbe0c60de 100644 --- a/troposphere/daybreak/source/ui_util.cpp +++ b/troposphere/daybreak/source/ui_util.cpp @@ -129,6 +129,27 @@ namespace dbk { } } + void DrawToggle(NVGcontext *vg, float x, float y, float w, float h, bool on, bool selected) { + const float radius = h * 0.5f; + + nvgBeginPath(vg); + nvgRoundedRect(vg, x, y, w, h, radius); + if (on) { + nvgFillColor(vg, selected ? nvgRGB(255, 255, 255) : nvgRGB(83, 71, 185)); + } else { + nvgFillColor(vg, selected ? nvgRGBA(255, 255, 255, 80) : nvgRGBA(0, 0, 0, 48)); + } + nvgFill(vg); + + const float pad = 3.0f; + const float knob = h - pad * 2.0f; + const float knob_x = on ? (x + w - pad - knob) : (x + pad); + nvgBeginPath(vg); + nvgRoundedRect(vg, knob_x, y + pad, knob, knob, knob * 0.5f); + nvgFillColor(vg, on && selected ? nvgRGB(83, 71, 185) : nvgRGB(255, 255, 255)); + nvgFill(vg); + } + void DrawTextBackground(NVGcontext *vg, float x, float y, float w, float h) { nvgBeginPath(vg); nvgRoundedRect(vg, x, y, w, h, TextAreaCornerRadius); diff --git a/troposphere/daybreak/source/ui_util.hpp b/troposphere/daybreak/source/ui_util.hpp index 81a5e6e28..031b0b9fc 100644 --- a/troposphere/daybreak/source/ui_util.hpp +++ b/troposphere/daybreak/source/ui_util.hpp @@ -31,6 +31,7 @@ namespace dbk { void DrawBackground(NVGcontext *vg, float w, float h); void DrawWindow(NVGcontext *vg, const char *title, float x, float y, float w, float h); void DrawButton(NVGcontext *vg, const char *text, float x, float y, float w, float h, ButtonStyle style, u64 ns); + void DrawToggle(NVGcontext *vg, float x, float y, float w, float h, bool on, bool selected); void DrawTextBackground(NVGcontext *vg, float x, float y, float w, float h); void DrawText(NVGcontext *vg, float x, float y, float w, const char *text); void DrawProgressText(NVGcontext *vg, float x, float y, float progress);