daybreak: Add firmware compatibility gate and German UI
Block unsupported firmware updates via a dedicated dialog using Exosphere's maximum supported HOS version, and translate the Daybreak interface to German.
This commit is contained in:
@@ -141,8 +141,31 @@ namespace dbk {
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 EncodeVersion(u32 major, u32 minor, u32 micro, u32 relstep = 0) {
|
u32 EncodeVersion(u32 major, u32 minor, u32 micro) {
|
||||||
return ((major & 0xFF) << 24) | ((minor & 0xFF) << 16) | ((micro & 0xFF) << 8) | ((relstep & 0xFF) << 8);
|
return ((major & 0xFF) << 24) | ((minor & 0xFF) << 16) | ((micro & 0xFF) << 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 NcmVersionToHosVersion(u32 ncm_version) {
|
||||||
|
const u32 major = (ncm_version >> 26) & 0x1f;
|
||||||
|
const u32 minor = (ncm_version >> 20) & 0x1f;
|
||||||
|
const u32 micro = (ncm_version >> 16) & 0xf;
|
||||||
|
return EncodeVersion(major, minor, micro);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsHosVersionSupported(u32 hos_version) {
|
||||||
|
return hos_version <= g_supported_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Menu> CreateUpdateMenuAfterPathSelection(std::shared_ptr<Menu> prev_menu) {
|
||||||
|
AmsSuUpdateInformation update_info = {};
|
||||||
|
if (R_SUCCEEDED(amssuGetUpdateInformation(&update_info, g_update_path))) {
|
||||||
|
const u32 update_hos_version = NcmVersionToHosVersion(update_info.version);
|
||||||
|
if (!IsHosVersionSupported(update_hos_version)) {
|
||||||
|
return std::make_shared<FirmwareNotSupportedMenu>(prev_menu, update_info.version, g_supported_version);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_shared<ValidateUpdateMenu>(prev_menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -347,7 +370,7 @@ namespace dbk {
|
|||||||
|
|
||||||
/* Copy result text if there is a result. */
|
/* Copy result text if there is a result. */
|
||||||
if (R_FAILED(rc)) {
|
if (R_FAILED(rc)) {
|
||||||
snprintf(m_result_text, sizeof(m_result_text), "Result: 0x%08x", rc);
|
snprintf(m_result_text, sizeof(m_result_text), "Ergebnis: 0x%08x", rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -375,7 +398,7 @@ namespace dbk {
|
|||||||
const float button_width = WindowWidth - HorizontalInset * 2.0f;
|
const float button_width = WindowWidth - HorizontalInset * 2.0f;
|
||||||
|
|
||||||
/* Add buttons. */
|
/* Add buttons. */
|
||||||
this->AddButton(ExitButtonId, "Exit", x + HorizontalInset, button_y, button_width, ButtonHeight);
|
this->AddButton(ExitButtonId, "Beenden", x + HorizontalInset, button_y, button_width, ButtonHeight);
|
||||||
this->SetButtonSelected(ExitButtonId, true);
|
this->SetButtonSelected(ExitButtonId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,8 +435,8 @@ namespace dbk {
|
|||||||
|
|
||||||
const float button_y = y + TitleGap + SubTextHeight + VerticalGap * 2.0f + (R_FAILED(m_rc) ? SubTextHeight : 0.0f);
|
const float button_y = y + TitleGap + SubTextHeight + VerticalGap * 2.0f + (R_FAILED(m_rc) ? SubTextHeight : 0.0f);
|
||||||
const float button_width = (WindowWidth - HorizontalInset * 2.0f) / 2.0f - ButtonHorizontalGap;
|
const float button_width = (WindowWidth - HorizontalInset * 2.0f) / 2.0f - ButtonHorizontalGap;
|
||||||
this->AddButton(BackButtonId, "Back", x + HorizontalInset, button_y, button_width, ButtonHeight);
|
this->AddButton(BackButtonId, "Zurück", x + HorizontalInset, button_y, button_width, ButtonHeight);
|
||||||
this->AddButton(ContinueButtonId, "Continue", x + HorizontalInset + button_width + ButtonHorizontalGap, button_y, button_width, ButtonHeight);
|
this->AddButton(ContinueButtonId, "Weiter", x + HorizontalInset + button_width + ButtonHorizontalGap, button_y, button_width, ButtonHeight);
|
||||||
this->SetButtonSelected(ContinueButtonId, true);
|
this->SetButtonSelected(ContinueButtonId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,12 +469,75 @@ namespace dbk {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct FirmwareNotSupportedSubtext {
|
||||||
|
char value[0x100];
|
||||||
|
|
||||||
|
FirmwareNotSupportedSubtext(u32 update_ncm_version, u32 max_supported_hos_version) {
|
||||||
|
snprintf(this->value, sizeof(this->value),
|
||||||
|
"Maximal unterstützte Firmware ist %u.%u.%u.\n"
|
||||||
|
"Aktualisiere Atmosphere, bevor du diese Firmware installierst.",
|
||||||
|
(max_supported_hos_version >> 24) & 0xff, (max_supported_hos_version >> 16) & 0xff, (max_supported_hos_version >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const char *() const {
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
FirmwareNotSupportedMenu::FirmwareNotSupportedMenu(std::shared_ptr<Menu> prev_menu, u32 update_ncm_version, u32 max_supported_hos_version)
|
||||||
|
: AlertMenu(prev_menu, "Nicht unterstützte Firmware-Version", FirmwareNotSupportedSubtext(update_ncm_version, max_supported_hos_version), 0) {
|
||||||
|
const float window_height = WindowHeight + SubTextAreaHeight;
|
||||||
|
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
||||||
|
const float y = g_screen_height / 2.0f - window_height / 2.0f;
|
||||||
|
const float button_y = y + TitleGap + SubTextAreaHeight + VerticalGap * 2.0f;
|
||||||
|
const float button_width = WindowWidth - HorizontalInset * 2.0f;
|
||||||
|
|
||||||
|
this->AddButton(BackButtonId, "Zurück", x + HorizontalInset, button_y, button_width, ButtonHeight);
|
||||||
|
this->SetButtonSelected(BackButtonId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirmwareNotSupportedMenu::Draw(NVGcontext *vg, u64 ns) {
|
||||||
|
const float window_height = WindowHeight + SubTextAreaHeight;
|
||||||
|
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
||||||
|
const float y = g_screen_height / 2.0f - window_height / 2.0f;
|
||||||
|
|
||||||
|
DrawWindow(vg, m_text, x, y, WindowWidth, window_height);
|
||||||
|
DrawTextBlock(vg, m_subtext, x + HorizontalInset, y + TitleGap, WindowWidth - HorizontalInset * 2.0f, SubTextAreaHeight);
|
||||||
|
this->DrawButtons(vg, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FirmwareNotSupportedMenu::Update(u64 ns) {
|
||||||
|
u64 k_down = padGetButtonsDown(&g_pad);
|
||||||
|
|
||||||
|
if (k_down & HidNpadButton_B) {
|
||||||
|
ReturnToPreviousMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (const Button *activated_button = this->GetActivatedButton(); activated_button != nullptr) {
|
||||||
|
if (activated_button->id == BackButtonId) {
|
||||||
|
ReturnToPreviousMenu();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->UpdateButtons();
|
||||||
|
|
||||||
|
if (const Button *selected_button = this->GetSelectedButton(); k_down && selected_button == nullptr) {
|
||||||
|
this->SetButtonSelected(BackButtonId, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MainMenu::MainMenu() : Menu(nullptr) {
|
MainMenu::MainMenu() : Menu(nullptr) {
|
||||||
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
||||||
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
||||||
|
|
||||||
this->AddButton(InstallButtonId, "Install", x + HorizontalInset, y + TitleGap, WindowWidth - HorizontalInset * 2, ButtonHeight);
|
this->AddButton(InstallButtonId, "Installieren", x + HorizontalInset, y + TitleGap, WindowWidth - HorizontalInset * 2, ButtonHeight);
|
||||||
this->AddButton(ExitButtonId, "Exit", x + HorizontalInset, y + TitleGap + ButtonHeight + VerticalGap, WindowWidth - HorizontalInset * 2, ButtonHeight);
|
this->AddButton(ExitButtonId, "Beenden", x + HorizontalInset, y + TitleGap + ButtonHeight + VerticalGap, WindowWidth - HorizontalInset * 2, ButtonHeight);
|
||||||
this->SetButtonSelected(InstallButtonId, true);
|
this->SetButtonSelected(InstallButtonId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,24 +561,24 @@ namespace dbk {
|
|||||||
u64 is_emummc;
|
u64 is_emummc;
|
||||||
|
|
||||||
if (R_FAILED(rc = splGetConfig(SplConfigItem_HardwareType, &hardware_type))) {
|
if (R_FAILED(rc = splGetConfig(SplConfigItem_HardwareType, &hardware_type))) {
|
||||||
ChangeMenu(std::make_shared<ErrorMenu>("An error has occurred", "Failed to get hardware type.", rc));
|
ChangeMenu(std::make_shared<ErrorMenu>("Ein Fehler ist aufgetreten", "Hardwaretyp konnte nicht ermittelt werden.", rc));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_FAILED(rc = splGetConfig(static_cast<SplConfigItem>(ExosphereHasRcmBugPatch), &has_rcm_bug_patch))) {
|
if (R_FAILED(rc = splGetConfig(static_cast<SplConfigItem>(ExosphereHasRcmBugPatch), &has_rcm_bug_patch))) {
|
||||||
ChangeMenu(std::make_shared<ErrorMenu>("An error has occurred", "Failed to check RCM bug status.", rc));
|
ChangeMenu(std::make_shared<ErrorMenu>("Ein Fehler ist aufgetreten", "RCM-Bug-Status konnte nicht geprüft werden.", rc));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (R_FAILED(rc = splGetConfig(static_cast<SplConfigItem>(ExosphereEmummcType), &is_emummc))) {
|
if (R_FAILED(rc = splGetConfig(static_cast<SplConfigItem>(ExosphereEmummcType), &is_emummc))) {
|
||||||
ChangeMenu(std::make_shared<ErrorMenu>("An error has occurred", "Failed to check emuMMC status.", rc));
|
ChangeMenu(std::make_shared<ErrorMenu>("Ein Fehler ist aufgetreten", "emuMMC-Status konnte nicht geprüft werden.", rc));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Warn if we're working with a patched unit. */
|
/* Warn if we're working with a patched unit. */
|
||||||
const bool is_erista = hardware_type == 0 || hardware_type == 1;
|
const bool is_erista = hardware_type == 0 || hardware_type == 1;
|
||||||
if (is_erista && has_rcm_bug_patch && !is_emummc) {
|
if (is_erista && has_rcm_bug_patch && !is_emummc) {
|
||||||
ChangeMenu(std::make_shared<WarningMenu>(g_current_menu, file_menu, "Warning: Patched unit detected", "You may burn fuses or render your switch inoperable."));
|
ChangeMenu(std::make_shared<WarningMenu>(g_current_menu, file_menu, "Warnung: Gepatchte Konsole erkannt", "Sicherungen können durchgebrannt werden oder die Konsole unbrauchbar gemacht werden."));
|
||||||
} else {
|
} else {
|
||||||
ChangeMenu(file_menu);
|
ChangeMenu(file_menu);
|
||||||
}
|
}
|
||||||
@@ -688,7 +774,7 @@ namespace dbk {
|
|||||||
snprintf(g_update_path, sizeof(g_update_path), "%s", current_path);
|
snprintf(g_update_path, sizeof(g_update_path), "%s", current_path);
|
||||||
|
|
||||||
/* Change the menu. */
|
/* Change the menu. */
|
||||||
ChangeMenu(std::make_shared<ValidateUpdateMenu>(g_current_menu));
|
ChangeMenu(CreateUpdateMenuAfterPathSelection(g_current_menu));
|
||||||
} else {
|
} else {
|
||||||
ChangeMenu(std::make_shared<FileMenu>(g_current_menu, current_path));
|
ChangeMenu(std::make_shared<FileMenu>(g_current_menu, current_path));
|
||||||
}
|
}
|
||||||
@@ -739,7 +825,7 @@ namespace dbk {
|
|||||||
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
||||||
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
||||||
|
|
||||||
DrawWindow(vg, "Select an update directory", x, y, WindowWidth, WindowHeight);
|
DrawWindow(vg, "Update-Ordner auswählen", x, y, WindowWidth, WindowHeight);
|
||||||
DrawTextBackground(vg, x + TextBackgroundOffset, y + TitleGap, WindowWidth - TextBackgroundOffset * 2.0f, (FileRowHeight + FileRowGap) * MaxFileRows + FileRowGap);
|
DrawTextBackground(vg, x + TextBackgroundOffset, y + TitleGap, WindowWidth - TextBackgroundOffset * 2.0f, (FileRowHeight + FileRowGap) * MaxFileRows + FileRowGap);
|
||||||
|
|
||||||
nvgSave(vg);
|
nvgSave(vg);
|
||||||
@@ -765,8 +851,8 @@ namespace dbk {
|
|||||||
const float button_width = (WindowWidth - HorizontalInset * 2.0f) / 2.0f - ButtonHorizontalGap;
|
const float button_width = (WindowWidth - HorizontalInset * 2.0f) / 2.0f - ButtonHorizontalGap;
|
||||||
|
|
||||||
/* Add buttons. */
|
/* Add buttons. */
|
||||||
this->AddButton(BackButtonId, "Back", x + HorizontalInset, y + WindowHeight - BottomInset - ButtonHeight, button_width, ButtonHeight);
|
this->AddButton(BackButtonId, "Zurück", x + HorizontalInset, y + WindowHeight - BottomInset - ButtonHeight, button_width, ButtonHeight);
|
||||||
this->AddButton(ContinueButtonId, "Continue", x + HorizontalInset + button_width + ButtonHorizontalGap, y + WindowHeight - BottomInset - ButtonHeight, button_width, ButtonHeight);
|
this->AddButton(ContinueButtonId, "Weiter", x + HorizontalInset + button_width + ButtonHorizontalGap, y + WindowHeight - BottomInset - ButtonHeight, button_width, ButtonHeight);
|
||||||
this->SetButtonEnabled(BackButtonId, false);
|
this->SetButtonEnabled(BackButtonId, false);
|
||||||
this->SetButtonEnabled(ContinueButtonId, false);
|
this->SetButtonEnabled(ContinueButtonId, false);
|
||||||
|
|
||||||
@@ -776,32 +862,33 @@ namespace dbk {
|
|||||||
this->SetButtonSelected(BackButtonId, true);
|
this->SetButtonSelected(BackButtonId, true);
|
||||||
} else {
|
} else {
|
||||||
/* Log this early so it is printed out before validation causes stalling. */
|
/* Log this early so it is printed out before validation causes stalling. */
|
||||||
this->LogText("Validating update, this may take a moment...\n");
|
this->LogText("Update wird geprüft, bitte warten...\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ValidateUpdateMenu::GetUpdateInformation() {
|
Result ValidateUpdateMenu::GetUpdateInformation() {
|
||||||
Result rc = 0;
|
Result rc = 0;
|
||||||
this->LogText("Directory %s\n", g_update_path);
|
this->LogText("Verzeichnis %s\n", g_update_path);
|
||||||
|
|
||||||
/* Attempt to get the update information. */
|
/* Attempt to get the update information. */
|
||||||
if (R_FAILED(rc = amssuGetUpdateInformation(&m_update_info, g_update_path))) {
|
if (R_FAILED(rc = amssuGetUpdateInformation(&m_update_info, g_update_path))) {
|
||||||
if (rc == 0x1a405) {
|
if (rc == 0x1a405) {
|
||||||
this->LogText("No update found in folder.\nEnsure your ncas are named correctly!\nResult: 0x%08x\n", rc);
|
this->LogText("Kein Update im Ordner gefunden.\nStelle sicher, dass die NCAs korrekt benannt sind!\nErgebnis: 0x%08x\n", rc);
|
||||||
} else {
|
} else {
|
||||||
this->LogText("Failed to get update information.\nResult: 0x%08x\n", rc);
|
this->LogText("Update-Informationen konnten nicht abgerufen werden.\nErgebnis: 0x%08x\n", rc);
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print update information. */
|
/* Print update information. */
|
||||||
this->LogText("- Version: %d.%d.%d\n", (m_update_info.version >> 26) & 0x1f, (m_update_info.version >> 20) & 0x1f, (m_update_info.version >> 16) & 0xf);
|
this->LogText("- Version: %d.%d.%d\n", (m_update_info.version >> 26) & 0x1f, (m_update_info.version >> 20) & 0x1f, (m_update_info.version >> 16) & 0xf);
|
||||||
|
this->LogText("- Von Atmosphere max. unterstützt: %d.%d.%d\n", (g_supported_version >> 24) & 0xff, (g_supported_version >> 16) & 0xff, (g_supported_version >> 8) & 0xff);
|
||||||
if (m_update_info.exfat_supported) {
|
if (m_update_info.exfat_supported) {
|
||||||
this->LogText("- exFAT: Supported\n");
|
this->LogText("- exFAT: Unterstützt\n");
|
||||||
} else {
|
} else {
|
||||||
this->LogText("- exFAT: Unsupported\n");
|
this->LogText("- exFAT: Nicht unterstützt\n");
|
||||||
}
|
}
|
||||||
this->LogText("- Firmware variations: %d\n", m_update_info.num_firmware_variations);
|
this->LogText("- Firmware-Varianten: %d\n", m_update_info.num_firmware_variations);
|
||||||
|
|
||||||
/* Mark as having obtained update info. */
|
/* Mark as having obtained update info. */
|
||||||
m_has_info = true;
|
m_has_info = true;
|
||||||
@@ -813,21 +900,21 @@ namespace dbk {
|
|||||||
|
|
||||||
/* Validate the update. */
|
/* Validate the update. */
|
||||||
if (R_FAILED(rc = amssuValidateUpdate(&m_validation_info, g_update_path))) {
|
if (R_FAILED(rc = amssuValidateUpdate(&m_validation_info, g_update_path))) {
|
||||||
this->LogText("Failed to validate update.\nResult: 0x%08x\n", rc);
|
this->LogText("Update konnte nicht validiert werden.\nErgebnis: 0x%08x\n", rc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the result. */
|
/* Check the result. */
|
||||||
if (R_SUCCEEDED(m_validation_info.result)) {
|
if (R_SUCCEEDED(m_validation_info.result)) {
|
||||||
this->LogText("Update is valid!\n");
|
this->LogText("Update ist gültig!\n");
|
||||||
|
|
||||||
if (R_FAILED(m_validation_info.exfat_result)) {
|
if (R_FAILED(m_validation_info.exfat_result)) {
|
||||||
const u32 version = m_validation_info.invalid_key.version;
|
const u32 version = m_validation_info.invalid_key.version;
|
||||||
this->LogText("exFAT Validation failed with result: 0x%08x\n", m_validation_info.exfat_result);
|
this->LogText("exFAT-Validierung fehlgeschlagen, Ergebnis: 0x%08x\n", m_validation_info.exfat_result);
|
||||||
this->LogText("Missing content:\n- Program id: %016lx\n- Version: %d.%d.%d\n", m_validation_info.invalid_key.id, (version >> 26) & 0x1f, (version >> 20) & 0x1f, (version >> 16) & 0xf);
|
this->LogText("Fehlender Inhalt:\n- Programm-ID: %016lx\n- Version: %d.%d.%d\n", m_validation_info.invalid_key.id, (version >> 26) & 0x1f, (version >> 20) & 0x1f, (version >> 16) & 0xf);
|
||||||
|
|
||||||
/* Log the missing content id. */
|
/* Log the missing content id. */
|
||||||
this->LogText("- Content id: ");
|
this->LogText("- Inhalts-ID: ");
|
||||||
for (size_t i = 0; i < sizeof(NcmContentId); i++) {
|
for (size_t i = 0; i < sizeof(NcmContentId); i++) {
|
||||||
this->LogText("%02x", m_validation_info.invalid_content_id.c[i]);
|
this->LogText("%02x", m_validation_info.invalid_content_id.c[i]);
|
||||||
}
|
}
|
||||||
@@ -841,11 +928,11 @@ namespace dbk {
|
|||||||
} else {
|
} else {
|
||||||
/* Log the missing content info. */
|
/* Log the missing content info. */
|
||||||
const u32 version = m_validation_info.invalid_key.version;
|
const u32 version = m_validation_info.invalid_key.version;
|
||||||
this->LogText("Validation failed with result: 0x%08x\n", m_validation_info.result);
|
this->LogText("Validierung fehlgeschlagen, Ergebnis: 0x%08x\n", m_validation_info.result);
|
||||||
this->LogText("Missing content:\n- Program id: %016lx\n- Version: %d.%d.%d\n", m_validation_info.invalid_key.id, (version >> 26) & 0x1f, (version >> 20) & 0x1f, (version >> 16) & 0xf);
|
this->LogText("Fehlender Inhalt:\n- Programm-ID: %016lx\n- Version: %d.%d.%d\n", m_validation_info.invalid_key.id, (version >> 26) & 0x1f, (version >> 20) & 0x1f, (version >> 16) & 0xf);
|
||||||
|
|
||||||
/* Log the missing content id. */
|
/* Log the missing content id. */
|
||||||
this->LogText("- Content id: ");
|
this->LogText("- Inhalts-ID: ");
|
||||||
for (size_t i = 0; i < sizeof(NcmContentId); i++) {
|
for (size_t i = 0; i < sizeof(NcmContentId); i++) {
|
||||||
this->LogText("%02x", m_validation_info.invalid_content_id.c[i]);
|
this->LogText("%02x", m_validation_info.invalid_content_id.c[i]);
|
||||||
}
|
}
|
||||||
@@ -897,13 +984,7 @@ namespace dbk {
|
|||||||
|
|
||||||
/* Warn the user if they're updating with exFAT supposed to be supported but not present/corrupted. */
|
/* Warn the user if they're updating with exFAT supposed to be supported but not present/corrupted. */
|
||||||
if (m_update_info.exfat_supported && R_FAILED(m_validation_info.exfat_result)) {
|
if (m_update_info.exfat_supported && R_FAILED(m_validation_info.exfat_result)) {
|
||||||
next_menu = std::make_shared<WarningMenu>(g_current_menu, next_menu, "Warning: exFAT firmware is missing or corrupt", "Are you sure you want to proceed?");
|
next_menu = std::make_shared<WarningMenu>(g_current_menu, next_menu, "Warnung: exFAT-Firmware fehlt oder ist beschädigt", "Möchtest du wirklich fortfahren?");
|
||||||
}
|
|
||||||
|
|
||||||
/* Warn the user if they're updating to a version higher than supported. */
|
|
||||||
const u32 version = m_validation_info.invalid_key.version;
|
|
||||||
if (EncodeVersion((version >> 26) & 0x1f, (version >> 20) & 0x1f, (version >> 16) & 0xf) > g_supported_version) {
|
|
||||||
next_menu = std::make_shared<WarningMenu>(g_current_menu, next_menu, "Warning: firmware is too new and not known to be supported", "Are you sure you want to proceed?");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Change to the next menu. */
|
/* Change to the next menu. */
|
||||||
@@ -919,7 +1000,7 @@ namespace dbk {
|
|||||||
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
||||||
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
||||||
|
|
||||||
DrawWindow(vg, "Update information", x, y, WindowWidth, WindowHeight);
|
DrawWindow(vg, "Update-Informationen", x, y, WindowWidth, WindowHeight);
|
||||||
DrawTextBackground(vg, x + HorizontalInset, y + TitleGap, WindowWidth - HorizontalInset * 2.0f, TextAreaHeight);
|
DrawTextBackground(vg, x + HorizontalInset, y + TitleGap, WindowWidth - HorizontalInset * 2.0f, TextAreaHeight);
|
||||||
DrawTextBlock(vg, m_log_buffer, x + HorizontalInset + TextHorizontalInset, y + TitleGap + TextVerticalInset, WindowWidth - (HorizontalInset + TextHorizontalInset) * 2.0f, TextAreaHeight - TextVerticalInset * 2.0f);
|
DrawTextBlock(vg, m_log_buffer, x + HorizontalInset + TextHorizontalInset, y + TitleGap + TextVerticalInset, WindowWidth - (HorizontalInset + TextHorizontalInset) * 2.0f, TextAreaHeight - TextVerticalInset * 2.0f);
|
||||||
|
|
||||||
@@ -933,8 +1014,8 @@ namespace dbk {
|
|||||||
const float button_width = (WindowWidth - HorizontalInset * 2.0f) / 2.0f - ButtonHorizontalGap;
|
const float button_width = (WindowWidth - HorizontalInset * 2.0f) / 2.0f - ButtonHorizontalGap;
|
||||||
|
|
||||||
/* Add buttons. */
|
/* Add buttons. */
|
||||||
this->AddButton(ResetToFactorySettingsButtonId, "Reset to factory settings", x + HorizontalInset, y + TitleGap, button_width, ButtonHeight);
|
this->AddButton(ResetToFactorySettingsButtonId, "Werkseinstellungen", x + HorizontalInset, y + TitleGap, button_width, ButtonHeight);
|
||||||
this->AddButton(PreserveSettingsButtonId, "Preserve settings", x + HorizontalInset + button_width + ButtonHorizontalGap, y + TitleGap, button_width, ButtonHeight);
|
this->AddButton(PreserveSettingsButtonId, "Einstellungen behalten", x + HorizontalInset + button_width + ButtonHorizontalGap, y + TitleGap, button_width, ButtonHeight);
|
||||||
this->SetButtonSelected(PreserveSettingsButtonId, true);
|
this->SetButtonSelected(PreserveSettingsButtonId, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -963,11 +1044,11 @@ namespace dbk {
|
|||||||
if (g_exfat_supported) {
|
if (g_exfat_supported) {
|
||||||
next_menu = std::make_shared<ChooseExfatMenu>(g_current_menu);
|
next_menu = std::make_shared<ChooseExfatMenu>(g_current_menu);
|
||||||
} else {
|
} else {
|
||||||
next_menu = std::make_shared<WarningMenu>(g_current_menu, std::make_shared<InstallUpdateMenu>(g_current_menu), "Ready to begin update installation", "Are you sure you want to proceed?");
|
next_menu = std::make_shared<WarningMenu>(g_current_menu, std::make_shared<InstallUpdateMenu>(g_current_menu), "Bereit zur Update-Installation", "Möchtest du wirklich fortfahren?");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_reset_to_factory) {
|
if (g_reset_to_factory) {
|
||||||
ChangeMenu(std::make_shared<WarningMenu>(g_current_menu, next_menu, "Warning: Factory reset selected", "Saves and installed games will be permanently deleted."));
|
ChangeMenu(std::make_shared<WarningMenu>(g_current_menu, next_menu, "Warnung: Werkseinstellungen ausgewählt", "Spielstände und installierte Spiele werden dauerhaft gelöscht."));
|
||||||
} else {
|
} else {
|
||||||
ChangeMenu(next_menu);
|
ChangeMenu(next_menu);
|
||||||
}
|
}
|
||||||
@@ -985,7 +1066,7 @@ namespace dbk {
|
|||||||
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
||||||
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
||||||
|
|
||||||
DrawWindow(vg, "Select settings mode", x, y, WindowWidth, WindowHeight);
|
DrawWindow(vg, "Einstellungsmodus wählen", x, y, WindowWidth, WindowHeight);
|
||||||
this->DrawButtons(vg, ns);
|
this->DrawButtons(vg, ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1029,7 +1110,7 @@ namespace dbk {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChangeMenu(std::make_shared<WarningMenu>(g_current_menu, std::make_shared<InstallUpdateMenu>(g_current_menu), "Ready to begin update installation", "Are you sure you want to proceed?"));
|
ChangeMenu(std::make_shared<WarningMenu>(g_current_menu, std::make_shared<InstallUpdateMenu>(g_current_menu), "Bereit zur Update-Installation", "Möchtest du wirklich fortfahren?"));
|
||||||
}
|
}
|
||||||
|
|
||||||
this->UpdateButtons();
|
this->UpdateButtons();
|
||||||
@@ -1044,7 +1125,7 @@ namespace dbk {
|
|||||||
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
||||||
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
||||||
|
|
||||||
DrawWindow(vg, "Select driver variant", x, y, WindowWidth, WindowHeight);
|
DrawWindow(vg, "Treibervariante wählen", x, y, WindowWidth, WindowHeight);
|
||||||
this->DrawButtons(vg, ns);
|
this->DrawButtons(vg, ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1054,8 +1135,8 @@ namespace dbk {
|
|||||||
const float button_width = (WindowWidth - HorizontalInset * 2.0f) / 2.0f - ButtonHorizontalGap;
|
const float button_width = (WindowWidth - HorizontalInset * 2.0f) / 2.0f - ButtonHorizontalGap;
|
||||||
|
|
||||||
/* Add buttons. */
|
/* Add buttons. */
|
||||||
this->AddButton(ShutdownButtonId, "Shutdown", x + HorizontalInset, y + WindowHeight - BottomInset - ButtonHeight, button_width, ButtonHeight);
|
this->AddButton(ShutdownButtonId, "Ausschalten", x + HorizontalInset, y + WindowHeight - BottomInset - ButtonHeight, button_width, ButtonHeight);
|
||||||
this->AddButton(RebootButtonId, "Reboot", x + HorizontalInset + button_width + ButtonHorizontalGap, y + WindowHeight - BottomInset - ButtonHeight, button_width, ButtonHeight);
|
this->AddButton(RebootButtonId, "Neustart", x + HorizontalInset + button_width + ButtonHorizontalGap, y + WindowHeight - BottomInset - ButtonHeight, button_width, ButtonHeight);
|
||||||
this->SetButtonEnabled(ShutdownButtonId, false);
|
this->SetButtonEnabled(ShutdownButtonId, false);
|
||||||
this->SetButtonEnabled(RebootButtonId, false);
|
this->SetButtonEnabled(RebootButtonId, false);
|
||||||
|
|
||||||
@@ -1075,34 +1156,34 @@ namespace dbk {
|
|||||||
if (m_install_state == InstallState::NeedsSetup) {
|
if (m_install_state == InstallState::NeedsSetup) {
|
||||||
/* Setup the update. */
|
/* Setup the update. */
|
||||||
if (R_FAILED(rc = amssuSetupUpdate(nullptr, UpdateTaskBufferSize, g_update_path, g_use_exfat))) {
|
if (R_FAILED(rc = amssuSetupUpdate(nullptr, UpdateTaskBufferSize, g_update_path, g_use_exfat))) {
|
||||||
this->LogText("Failed to setup update.\nResult: 0x%08x\n", rc);
|
this->LogText("Update-Einrichtung fehlgeschlagen.\nErgebnis: 0x%08x\n", rc);
|
||||||
this->MarkForReboot();
|
this->MarkForReboot();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Log setup completion. */
|
/* Log setup completion. */
|
||||||
this->LogText("Update setup complete.\n");
|
this->LogText("Update-Einrichtung abgeschlossen.\n");
|
||||||
m_install_state = InstallState::NeedsPrepare;
|
m_install_state = InstallState::NeedsPrepare;
|
||||||
} else if (m_install_state == InstallState::NeedsPrepare) {
|
} else if (m_install_state == InstallState::NeedsPrepare) {
|
||||||
/* Request update preparation. */
|
/* Request update preparation. */
|
||||||
if (R_FAILED(rc = amssuRequestPrepareUpdate(&m_prepare_result))) {
|
if (R_FAILED(rc = amssuRequestPrepareUpdate(&m_prepare_result))) {
|
||||||
this->LogText("Failed to request update preparation.\nResult: 0x%08x\n", rc);
|
this->LogText("Update-Vorbereitung konnte nicht angefordert werden.\nErgebnis: 0x%08x\n", rc);
|
||||||
this->MarkForReboot();
|
this->MarkForReboot();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Log awaiting prepare. */
|
/* Log awaiting prepare. */
|
||||||
this->LogText("Preparing update...\n");
|
this->LogText("Update wird vorbereitet...\n");
|
||||||
m_install_state = InstallState::AwaitingPrepare;
|
m_install_state = InstallState::AwaitingPrepare;
|
||||||
} else if (m_install_state == InstallState::AwaitingPrepare) {
|
} else if (m_install_state == InstallState::AwaitingPrepare) {
|
||||||
/* Check if preparation has a result. */
|
/* Check if preparation has a result. */
|
||||||
if (R_FAILED(rc = asyncResultWait(&m_prepare_result, 0)) && rc != 0xea01) {
|
if (R_FAILED(rc = asyncResultWait(&m_prepare_result, 0)) && rc != 0xea01) {
|
||||||
this->LogText("Failed to check update preparation result.\nResult: 0x%08x\n", rc);
|
this->LogText("Ergebnis der Update-Vorbereitung konnte nicht geprüft werden.\nErgebnis: 0x%08x\n", rc);
|
||||||
this->MarkForReboot();
|
this->MarkForReboot();
|
||||||
return rc;
|
return rc;
|
||||||
} else if (R_SUCCEEDED(rc)) {
|
} else if (R_SUCCEEDED(rc)) {
|
||||||
if (R_FAILED(rc = asyncResultGet(&m_prepare_result))) {
|
if (R_FAILED(rc = asyncResultGet(&m_prepare_result))) {
|
||||||
this->LogText("Failed to prepare update.\nResult: 0x%08x\n", rc);
|
this->LogText("Update konnte nicht vorbereitet werden.\nErgebnis: 0x%08x\n", rc);
|
||||||
this->MarkForReboot();
|
this->MarkForReboot();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1111,14 +1192,14 @@ namespace dbk {
|
|||||||
/* Check if the update has been prepared. */
|
/* Check if the update has been prepared. */
|
||||||
bool prepared;
|
bool prepared;
|
||||||
if (R_FAILED(rc = amssuHasPreparedUpdate(&prepared))) {
|
if (R_FAILED(rc = amssuHasPreparedUpdate(&prepared))) {
|
||||||
this->LogText("Failed to check if update has been prepared.\nResult: 0x%08x\n", rc);
|
this->LogText("Prüfung, ob das Update vorbereitet wurde, fehlgeschlagen.\nErgebnis: 0x%08x\n", rc);
|
||||||
this->MarkForReboot();
|
this->MarkForReboot();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark for application if preparation complete. */
|
/* Mark for application if preparation complete. */
|
||||||
if (prepared) {
|
if (prepared) {
|
||||||
this->LogText("Update preparation complete.\nApplying update...\n");
|
this->LogText("Update-Vorbereitung abgeschlossen.\nUpdate wird angewendet...\n");
|
||||||
m_install_state = InstallState::NeedsApply;
|
m_install_state = InstallState::NeedsApply;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1126,7 +1207,7 @@ namespace dbk {
|
|||||||
/* Check update progress. */
|
/* Check update progress. */
|
||||||
NsSystemUpdateProgress update_progress = {};
|
NsSystemUpdateProgress update_progress = {};
|
||||||
if (R_FAILED(rc = amssuGetPrepareUpdateProgress(&update_progress))) {
|
if (R_FAILED(rc = amssuGetPrepareUpdateProgress(&update_progress))) {
|
||||||
this->LogText("Failed to check update progress.\nResult: 0x%08x\n", rc);
|
this->LogText("Update-Fortschritt konnte nicht geprüft werden.\nErgebnis: 0x%08x\n", rc);
|
||||||
this->MarkForReboot();
|
this->MarkForReboot();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -1140,28 +1221,28 @@ namespace dbk {
|
|||||||
} else if (m_install_state == InstallState::NeedsApply) {
|
} else if (m_install_state == InstallState::NeedsApply) {
|
||||||
/* Apply the prepared update. */
|
/* Apply the prepared update. */
|
||||||
if (R_FAILED(rc = amssuApplyPreparedUpdate())) {
|
if (R_FAILED(rc = amssuApplyPreparedUpdate())) {
|
||||||
this->LogText("Failed to apply update.\nResult: 0x%08x\n", rc);
|
this->LogText("Update konnte nicht angewendet werden.\nErgebnis: 0x%08x\n", rc);
|
||||||
} else {
|
} else {
|
||||||
/* Log success. */
|
/* Log success. */
|
||||||
this->LogText("Update applied successfully.\n");
|
this->LogText("Update erfolgreich angewendet.\n");
|
||||||
|
|
||||||
if (g_reset_to_factory) {
|
if (g_reset_to_factory) {
|
||||||
if (R_FAILED(rc = nsResetToFactorySettingsForRefurbishment())) {
|
if (R_FAILED(rc = nsResetToFactorySettingsForRefurbishment())) {
|
||||||
/* Fallback on ResetToFactorySettings. */
|
/* Fallback on ResetToFactorySettings. */
|
||||||
if (rc == MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer)) {
|
if (rc == MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer)) {
|
||||||
if (R_FAILED(rc = nsResetToFactorySettings())) {
|
if (R_FAILED(rc = nsResetToFactorySettings())) {
|
||||||
this->LogText("Failed to reset to factory settings.\nResult: 0x%08x\n", rc);
|
this->LogText("Zurücksetzen auf Werkseinstellungen fehlgeschlagen.\nErgebnis: 0x%08x\n", rc);
|
||||||
this->MarkForReboot();
|
this->MarkForReboot();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this->LogText("Failed to reset to factory settings for refurbishment.\nResult: 0x%08x\n", rc);
|
this->LogText("Zurücksetzen für Aufbereitung fehlgeschlagen.\nErgebnis: 0x%08x\n", rc);
|
||||||
this->MarkForReboot();
|
this->MarkForReboot();
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->LogText("Successfully reset to factory settings.\n", rc);
|
this->LogText("Erfolgreich auf Werkseinstellungen zurückgesetzt.\n", rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1201,7 +1282,7 @@ namespace dbk {
|
|||||||
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
const float x = g_screen_width / 2.0f - WindowWidth / 2.0f;
|
||||||
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
const float y = g_screen_height / 2.0f - WindowHeight / 2.0f;
|
||||||
|
|
||||||
DrawWindow(vg, "Installing update", x, y, WindowWidth, WindowHeight);
|
DrawWindow(vg, "Update wird installiert", x, y, WindowWidth, WindowHeight);
|
||||||
DrawProgressText(vg, x + HorizontalInset, y + TitleGap, m_progress_percent);
|
DrawProgressText(vg, x + HorizontalInset, y + TitleGap, m_progress_percent);
|
||||||
DrawProgressBar(vg, x + HorizontalInset, y + TitleGap + ProgressTextHeight, WindowWidth - HorizontalInset * 2.0f, ProgressBarHeight, m_progress_percent);
|
DrawProgressBar(vg, x + HorizontalInset, y + TitleGap + ProgressTextHeight, WindowWidth - HorizontalInset * 2.0f, ProgressBarHeight, m_progress_percent);
|
||||||
DrawTextBackground(vg, x + HorizontalInset, y + TitleGap + ProgressTextHeight + ProgressBarHeight + VerticalGap, WindowWidth - HorizontalInset * 2.0f, TextAreaHeight);
|
DrawTextBackground(vg, x + HorizontalInset, y + TitleGap + ProgressTextHeight + ProgressBarHeight + VerticalGap, WindowWidth - HorizontalInset * 2.0f, TextAreaHeight);
|
||||||
@@ -1211,7 +1292,7 @@ namespace dbk {
|
|||||||
|
|
||||||
/* We have drawn now, allow setup to occur. */
|
/* We have drawn now, allow setup to occur. */
|
||||||
if (m_install_state == InstallState::NeedsDraw) {
|
if (m_install_state == InstallState::NeedsDraw) {
|
||||||
this->LogText("Beginning update setup...\n");
|
this->LogText("Update-Einrichtung wird gestartet...\n");
|
||||||
m_install_state = InstallState::NeedsSetup;
|
m_install_state = InstallState::NeedsSetup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1236,7 +1317,7 @@ namespace dbk {
|
|||||||
/* Attempt to get the exosphere version. */
|
/* Attempt to get the exosphere version. */
|
||||||
u64 version;
|
u64 version;
|
||||||
if (R_FAILED(rc = splGetConfig(static_cast<SplConfigItem>(ExosphereApiVersionConfigItem), &version))) {
|
if (R_FAILED(rc = splGetConfig(static_cast<SplConfigItem>(ExosphereApiVersionConfigItem), &version))) {
|
||||||
ChangeMenu(std::make_shared<ErrorMenu>("Atmosphere not found", "Daybreak requires Atmosphere to be installed.", rc));
|
ChangeMenu(std::make_shared<ErrorMenu>("Atmosphere nicht gefunden", "Daybreak benötigt eine installierte Atmosphere-Umgebung.", rc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1247,20 +1328,22 @@ namespace dbk {
|
|||||||
/* Validate the exosphere version. */
|
/* Validate the exosphere version. */
|
||||||
const bool ams_supports_sysupdate_api = EncodeVersion(version_major, version_minor, version_micro) >= EncodeVersion(0, 14, 0);
|
const bool ams_supports_sysupdate_api = EncodeVersion(version_major, version_minor, version_micro) >= EncodeVersion(0, 14, 0);
|
||||||
if (!ams_supports_sysupdate_api) {
|
if (!ams_supports_sysupdate_api) {
|
||||||
ChangeMenu(std::make_shared<ErrorMenu>("Outdated Atmosphere version", "Daybreak requires Atmosphere 0.14.0 or later.", rc));
|
ChangeMenu(std::make_shared<ErrorMenu>("Veraltete Atmosphere-Version", "Daybreak benötigt Atmosphere 0.14.0 oder neuer.", rc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure DayBreak is ran as a NRO. */
|
/* Ensure DayBreak is ran as a NRO. */
|
||||||
if (envIsNso()) {
|
if (envIsNso()) {
|
||||||
ChangeMenu(std::make_shared<ErrorMenu>("Unsupported Environment", "Please launch Daybreak via the Homebrew menu.", rc));
|
ChangeMenu(std::make_shared<ErrorMenu>("Nicht unterstützte Umgebung", "Bitte starte Daybreak über das Homebrew-Menü.", rc));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt to get the supported version. */
|
/* Get the maximum HOS version supported by this Atmosphere build (hos::Version_Max). */
|
||||||
if (R_SUCCEEDED(rc = splGetConfig(static_cast<SplConfigItem>(ExosphereSupportedHosVersion), &version))) {
|
if (R_FAILED(rc = splGetConfig(static_cast<SplConfigItem>(ExosphereSupportedHosVersion), &version))) {
|
||||||
g_supported_version = static_cast<u32>(version);
|
ChangeMenu(std::make_shared<ErrorMenu>("Atmosphere nicht gefunden", "Maximal unterstützte Firmware-Version konnte nicht ermittelt werden.", rc));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
g_supported_version = static_cast<u32>(version);
|
||||||
|
|
||||||
/* Initialize ams:su. */
|
/* Initialize ams:su. */
|
||||||
if (R_FAILED(rc = amssuInitialize())) {
|
if (R_FAILED(rc = amssuInitialize())) {
|
||||||
@@ -1280,7 +1363,7 @@ namespace dbk {
|
|||||||
strncpy(g_update_path, update_path, sizeof(g_update_path)-1);
|
strncpy(g_update_path, update_path, sizeof(g_update_path)-1);
|
||||||
|
|
||||||
/* Change the menu. */
|
/* Change the menu. */
|
||||||
ChangeMenu(std::make_shared<ValidateUpdateMenu>(g_current_menu));
|
ChangeMenu(CreateUpdateMenuAfterPathSelection(g_current_menu));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,17 @@ namespace dbk {
|
|||||||
virtual void Update(u64 ns) override;
|
virtual void Update(u64 ns) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FirmwareNotSupportedMenu : public AlertMenu {
|
||||||
|
private:
|
||||||
|
static constexpr u32 BackButtonId = 0;
|
||||||
|
static constexpr float SubTextAreaHeight = 72.0f;
|
||||||
|
public:
|
||||||
|
FirmwareNotSupportedMenu(std::shared_ptr<Menu> prev_menu, u32 update_ncm_version, u32 max_supported_hos_version);
|
||||||
|
|
||||||
|
virtual void Update(u64 ns) override;
|
||||||
|
virtual void Draw(NVGcontext *vg, u64 ns) override;
|
||||||
|
};
|
||||||
|
|
||||||
class MainMenu : public Menu {
|
class MainMenu : public Menu {
|
||||||
private:
|
private:
|
||||||
static constexpr u32 InstallButtonId = 0;
|
static constexpr u32 InstallButtonId = 0;
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ namespace dbk {
|
|||||||
|
|
||||||
void DrawProgressText(NVGcontext *vg, float x, float y, float progress) {
|
void DrawProgressText(NVGcontext *vg, float x, float y, float progress) {
|
||||||
char progress_text[32] = {};
|
char progress_text[32] = {};
|
||||||
snprintf(progress_text, sizeof(progress_text)-1, "%d%% complete", static_cast<int>(progress * 100.0f));
|
snprintf(progress_text, sizeof(progress_text)-1, "%d%% abgeschlossen", static_cast<int>(progress * 100.0f));
|
||||||
|
|
||||||
nvgFontSize(vg, 24.0f);
|
nvgFontSize(vg, 24.0f);
|
||||||
nvgFontFace(vg, SwitchStandardFont);
|
nvgFontFace(vg, SwitchStandardFont);
|
||||||
|
|||||||
Reference in New Issue
Block a user