From f856f871bb937c1aea63369e40e6df7b073a0f0a Mon Sep 17 00:00:00 2001 From: Pheenoh Date: Sun, 26 Apr 2026 13:55:32 -0600 Subject: [PATCH] Only show languages if PAL disc --- src/dusk/imgui/ImGuiPreLaunchWindow.cpp | 22 ++++++++++-------- src/dusk/imgui/ImGuiPreLaunchWindow.hpp | 1 + src/dusk/iso_validate.cpp | 31 +++++++++++++++++++++++++ src/dusk/iso_validate.hpp | 1 + 4 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/dusk/imgui/ImGuiPreLaunchWindow.cpp b/src/dusk/imgui/ImGuiPreLaunchWindow.cpp index 6347e9bc01..eef8c08e0d 100644 --- a/src/dusk/imgui/ImGuiPreLaunchWindow.cpp +++ b/src/dusk/imgui/ImGuiPreLaunchWindow.cpp @@ -75,6 +75,7 @@ void fileDialogCallback(void* userdata, const char* path, const char* error) { } self->m_selectedIsoPath = path; + self->m_isPal = iso::isPal(path); getSettings().backend.isoPath.setValue(self->m_selectedIsoPath); config::Save(); } @@ -92,6 +93,7 @@ bool ImGuiPreLaunchWindow::isSelectedPathValid() const { void ImGuiPreLaunchWindow::draw() { if (m_IsFirstDraw) { m_selectedIsoPath = getSettings().backend.isoPath; + m_isPal = !m_selectedIsoPath.empty() && iso::isPal(m_selectedIsoPath.c_str()); m_initialGraphicsBackend = getSettings().backend.graphicsBackend; m_IsFirstDraw = false; } @@ -199,18 +201,18 @@ void ImGuiPreLaunchWindow::drawOptions() { false); } - // TODO: Only show if PAL disc selected? - // Language selection - auto selectedLanguage = getSettings().game.language.getValue(); - if (ImGui::BeginCombo("Language", skLanguageNames[static_cast(selectedLanguage)])) { - for (u8 i = 0; i < skLanguageNames.size(); ++i) { - if (ImGui::Selectable(skLanguageNames[i])) { - getSettings().game.language.setValue(static_cast(i)); - config::Save(); + if (m_isPal) { + auto selectedLanguage = getSettings().game.language.getValue(); + if (ImGui::BeginCombo("Language", skLanguageNames[static_cast(selectedLanguage)])) { + for (u8 i = 0; i < skLanguageNames.size(); ++i) { + if (ImGui::Selectable(skLanguageNames[i])) { + getSettings().game.language.setValue(static_cast(i)); + config::Save(); + } } - } - ImGui::EndCombo(); + ImGui::EndCombo(); + } } AuroraBackend configuredBackend = BACKEND_AUTO; diff --git a/src/dusk/imgui/ImGuiPreLaunchWindow.hpp b/src/dusk/imgui/ImGuiPreLaunchWindow.hpp index 5d16a6ba0b..6cb078a228 100644 --- a/src/dusk/imgui/ImGuiPreLaunchWindow.hpp +++ b/src/dusk/imgui/ImGuiPreLaunchWindow.hpp @@ -18,5 +18,6 @@ public: std::string m_selectedIsoPath; std::string m_errorString; + bool m_isPal = false; }; } // namespace dusk diff --git a/src/dusk/iso_validate.cpp b/src/dusk/iso_validate.cpp index 0b4a19ae9c..e83b3fd34e 100644 --- a/src/dusk/iso_validate.cpp +++ b/src/dusk/iso_validate.cpp @@ -17,6 +17,11 @@ constexpr const char* TP_GAME_IDS[] = { "RZDK01", // Wii KOR }; +constexpr const char* PAL_GAME_IDS[] = { + "GZ2P01", // GCN PAL + "RZDP01", // Wii PAL +}; + constexpr const char* SUPPORTED_TP_GAME_IDS[] = { "GZ2E01", // GCN USA "GZ2P01", // GCN PAL @@ -124,4 +129,30 @@ ValidationError validate(const char* path) { return ValidationError::Success; } +bool isPal(const char* path) { + NodHandleWrapper disc; + + const auto sdlStream = SDL_IOFromFile(path, "rb"); + if (sdlStream == nullptr) { + return false; + } + + const NodDiscStream nod_stream{ + .user_data = sdlStream, + .read_at = StreamReadAt, + .stream_len = StreamLength, + .close = StreamClose, + }; + + if (nod_disc_open_stream(&nod_stream, nullptr, &disc.handle) != NOD_RESULT_OK || disc.handle == nullptr) { + return false; + } + + NodDiscHeader header{}; + if (nod_disc_header(disc.handle, &header) != NOD_RESULT_OK) { + return false; + } + + return matches(header.game_id, PAL_GAME_IDS); +} } // namespace dusk::iso \ No newline at end of file diff --git a/src/dusk/iso_validate.hpp b/src/dusk/iso_validate.hpp index da1ef1f2a6..d961f052cd 100644 --- a/src/dusk/iso_validate.hpp +++ b/src/dusk/iso_validate.hpp @@ -13,6 +13,7 @@ namespace dusk::iso { }; ValidationError validate(const char* path); + bool isPal(const char* path); } #endif // DUSK_ISO_VALIDATE_HPP