Compare commits
33 Commits
22_support
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 5cb085b00c | |||
|
|
2c7e2bfaae | ||
|
|
e655fd4b01 | ||
|
|
022000f668 | ||
|
|
d04c20a049 | ||
|
|
252f8685b4 | ||
|
|
020ed307b1 | ||
|
|
d9e1d799ab | ||
|
|
80bd459516 | ||
|
|
931e3c37fd | ||
|
|
4b4db91341 | ||
|
|
e3fc339fe5 | ||
|
|
a051c3c723 | ||
|
|
9a1ea02c8c | ||
|
|
bae1ad22ec | ||
|
|
cd1503a9ca | ||
|
|
72e3b0dd34 | ||
|
|
ac120cf84b | ||
|
|
97ffad2ab6 | ||
|
|
c8d68a3a8a | ||
|
|
8987d642d1 | ||
|
|
7ffb1da2ac | ||
|
|
5c426bf90d | ||
|
|
31ca20f3b7 | ||
|
|
174da786e4 | ||
|
|
4a8f7628c2 | ||
|
|
9d16ee6a74 | ||
|
|
3b9ee08c69 | ||
|
|
2694f31eb3 | ||
|
|
f3f1fa46ed | ||
|
|
5dd9816e3c | ||
|
|
5a5d9b206b | ||
|
|
f8a5a6c015 |
@@ -15,6 +15,13 @@
|
|||||||
# Desc: Controls whether userland has access to the PMU registers.
|
# Desc: Controls whether userland has access to the PMU registers.
|
||||||
# NOTE: It is unknown what effects this has on official code.
|
# NOTE: It is unknown what effects this has on official code.
|
||||||
|
|
||||||
|
# Key: enable_mem_mode, default: 0.
|
||||||
|
# Desc: Controls whether boot config memory mode is taken into account
|
||||||
|
# for retail units. This does not affect development units.
|
||||||
|
# NOTE: On retail units max ram size is capped to 4GB.
|
||||||
|
# Enabling this will use the boot config memory mode parameter,
|
||||||
|
# which by default is auto and size gets set based on physical size.
|
||||||
|
|
||||||
# Key: blank_prodinfo_sysmmc, default: 0.
|
# Key: blank_prodinfo_sysmmc, default: 0.
|
||||||
# Desc: Controls whether PRODINFO should be blanked in sysmmc.
|
# Desc: Controls whether PRODINFO should be blanked in sysmmc.
|
||||||
# This will cause the system to see dummied out keys and
|
# This will cause the system to see dummied out keys and
|
||||||
@@ -51,6 +58,7 @@ debugmode=1
|
|||||||
debugmode_user=0
|
debugmode_user=0
|
||||||
disable_user_exception_handlers=0
|
disable_user_exception_handlers=0
|
||||||
enable_user_pmu_access=0
|
enable_user_pmu_access=0
|
||||||
|
enable_mem_mode=0
|
||||||
blank_prodinfo_sysmmc=0
|
blank_prodinfo_sysmmc=0
|
||||||
blank_prodinfo_emummc=0
|
blank_prodinfo_emummc=0
|
||||||
allow_writing_to_cal_sysmmc=0
|
allow_writing_to_cal_sysmmc=0
|
||||||
|
|||||||
@@ -1,4 +1,25 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
## 1.11.1
|
||||||
|
+ Basic support was added for 22.1.0.
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
## 1.11.0
|
||||||
|
+ Support was added for 22.0.0.
|
||||||
|
+ Special thanks to @alula for handling a large chunk of the necessary kernel, loader and erpt changes.
|
||||||
|
+ The console should boot and atmosphère should be fully functional.
|
||||||
|
+ **Please note**: A change in how applications/applets' lifespan is managed broke the homebrew ecosystem.
|
||||||
|
+ All applications and applets are expected to perform a clean exit by calling the relevant IPC commands.
|
||||||
|
+ Homebrew compiled with libnx and hbmenu itself explicitly avoid exiting so it can keep using the same process.
|
||||||
|
+ Properly fixing this would require a re-design of how homebrew is launched and terminated.
|
||||||
|
+ As a temporary solution, patches to the `am` sysmodule are now included which allow restoring the previous behavior and regain homebrew compatibility without any further changes.
|
||||||
|
+ Nonetheless, please report any issues you may face when testing homebrew to ensure no edge cases have been missed.
|
||||||
|
+ `exosphère` was updated to reflect the latest official secure monitor behavior.
|
||||||
|
+ `mesosphère` was updated to reflect the latest official kernel behavior.
|
||||||
|
+ `loader` was updated to reflect the latest official behavior.
|
||||||
|
+ `erpt` was updated to reflect the latest official behavior.
|
||||||
|
+ `pgl` was updated to fix a few issues.
|
||||||
|
+ Support was added for memory modes above 4GB (thanks @CTCaer).
|
||||||
|
+ A build time option to configure Joy-Con rails as UART for debugging was added (thanks @alula).
|
||||||
|
+ General system stability improvements to enhance the user's experience.
|
||||||
## 1.10.2
|
## 1.10.2
|
||||||
+ Basic support was added for 21.2.0.
|
+ Basic support was added for 21.2.0.
|
||||||
+ General system stability improvements to enhance the user's experience.
|
+ General system stability improvements to enhance the user's experience.
|
||||||
|
|||||||
6
emummc/.gitrepo
vendored
6
emummc/.gitrepo
vendored
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/m4xw/emummc
|
remote = https://github.com/m4xw/emummc
|
||||||
branch = develop
|
branch = develop
|
||||||
commit = 8ab963b0b1c24b68de8e0c98c62c7822a9765bf3
|
commit = 3726bfd659600cdafd138277054568a3edba60a6
|
||||||
parent = 1e88f37892555da4c38ca6c95f43c56cc6bb87e6
|
parent = 80bd459516e813fc6f10268ca31dd72a053a4ef3
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.9
|
||||||
|
|||||||
2
emummc/source/FS/offsets/2200.h
vendored
2
emummc/source/FS/offsets/2200.h
vendored
@@ -31,7 +31,7 @@
|
|||||||
#define FS_OFFSET_2200_CLKRST_SET_MIN_V_CLK_RATE 0x1CF260
|
#define FS_OFFSET_2200_CLKRST_SET_MIN_V_CLK_RATE 0x1CF260
|
||||||
|
|
||||||
// Misc funcs
|
// Misc funcs
|
||||||
#define FS_OFFSET_2200_LOCK_MUTEX 0x1CF260
|
#define FS_OFFSET_2200_LOCK_MUTEX 0x1A4EF0
|
||||||
#define FS_OFFSET_2200_UNLOCK_MUTEX 0x1A4F40
|
#define FS_OFFSET_2200_UNLOCK_MUTEX 0x1A4F40
|
||||||
|
|
||||||
#define FS_OFFSET_2200_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AC0B0
|
#define FS_OFFSET_2200_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1AC0B0
|
||||||
|
|||||||
2
emummc/source/FS/offsets/2200_exfat.h
vendored
2
emummc/source/FS/offsets/2200_exfat.h
vendored
@@ -31,7 +31,7 @@
|
|||||||
#define FS_OFFSET_2200_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1DA450
|
#define FS_OFFSET_2200_EXFAT_CLKRST_SET_MIN_V_CLK_RATE 0x1DA450
|
||||||
|
|
||||||
// Misc funcs
|
// Misc funcs
|
||||||
#define FS_OFFSET_2200_EXFAT_LOCK_MUTEX 0x1DA450
|
#define FS_OFFSET_2200_EXFAT_LOCK_MUTEX 0x1B00E0
|
||||||
#define FS_OFFSET_2200_EXFAT_UNLOCK_MUTEX 0x1B0130
|
#define FS_OFFSET_2200_EXFAT_UNLOCK_MUTEX 0x1B0130
|
||||||
|
|
||||||
#define FS_OFFSET_2200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1B72A0
|
#define FS_OFFSET_2200_EXFAT_SDMMC_WRAPPER_CONTROLLER_OPEN 0x1B72A0
|
||||||
|
|||||||
@@ -132,10 +132,13 @@ namespace ams::secmon::smc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 GetMemoryMode() {
|
u32 GetMemoryMode() {
|
||||||
/* Unless development function is enabled, we're 4 GB. */
|
/* Unless development function or forced boot config memory size is enabled, we're 4 GB. */
|
||||||
u32 memory_mode = pkg1::MemoryMode_4GB;
|
u32 memory_mode = pkg1::MemoryMode_4GB;
|
||||||
|
|
||||||
if (const auto &bcd = GetBootConfig().data; bcd.IsDevelopmentFunctionEnabled()) {
|
const auto &bcd = GetBootConfig().data;
|
||||||
|
const auto &sc = GetSecmonConfiguration(); /* Exosphere extensions */
|
||||||
|
|
||||||
|
if (bcd.IsDevelopmentFunctionEnabled() || sc.IsBootConfigMemoryModeEnabled()) {
|
||||||
memory_mode = GetMemoryMode(bcd.GetMemoryMode());
|
memory_mode = GetMemoryMode(bcd.GetMemoryMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,17 +149,19 @@ namespace ams::secmon::smc {
|
|||||||
pkg1::MemorySize memory_size = pkg1::MemorySize_4GB;
|
pkg1::MemorySize memory_size = pkg1::MemorySize_4GB;
|
||||||
util::BitPack32 value = {};
|
util::BitPack32 value = {};
|
||||||
|
|
||||||
if (const auto &bcd = GetBootConfig().data; bcd.IsDevelopmentFunctionEnabled()) {
|
const auto &bcd = GetBootConfig().data;
|
||||||
memory_size = GetMemorySize(GetMemoryMode(bcd.GetMemoryMode()));
|
const auto &sc = GetSecmonConfiguration(); /* Exosphere extensions */
|
||||||
|
|
||||||
|
if (bcd.IsDevelopmentFunctionEnabled()) {
|
||||||
value.Set<KernelConfiguration::Flags1>(bcd.GetKernelFlags1());
|
value.Set<KernelConfiguration::Flags1>(bcd.GetKernelFlags1());
|
||||||
value.Set<KernelConfiguration::Flags0>(bcd.GetKernelFlags0());
|
value.Set<KernelConfiguration::Flags0>(bcd.GetKernelFlags0());
|
||||||
}
|
}
|
||||||
|
|
||||||
value.Set<KernelConfiguration::PhysicalMemorySize>(memory_size);
|
if (bcd.IsDevelopmentFunctionEnabled() || sc.IsBootConfigMemoryModeEnabled()) {
|
||||||
|
memory_size = GetMemorySize(GetMemoryMode(bcd.GetMemoryMode()));
|
||||||
|
}
|
||||||
|
|
||||||
/* Exosphere extensions. */
|
value.Set<KernelConfiguration::PhysicalMemorySize>(memory_size);
|
||||||
const auto &sc = GetSecmonConfiguration();
|
|
||||||
|
|
||||||
if (!sc.DisableUserModeExceptionHandlers()) {
|
if (!sc.DisableUserModeExceptionHandlers()) {
|
||||||
value.Set<KernelConfiguration::EnableUserExceptionHandlers>(true);
|
value.Set<KernelConfiguration::EnableUserExceptionHandlers>(true);
|
||||||
@@ -169,6 +174,27 @@ namespace ams::secmon::smc {
|
|||||||
return value.value;
|
return value.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fuse::DramId GetDramIdAdjusted() {
|
||||||
|
const auto dram_id = fuse::GetDramId();
|
||||||
|
AMS_ABORT_UNLESS(dram_id < fuse::DramId_Count);
|
||||||
|
|
||||||
|
const auto fuse_mem_size = DramIdToMemorySize[dram_id];
|
||||||
|
const auto phys_mem_size = GetPhysicalMemorySize();
|
||||||
|
|
||||||
|
AMS_ABORT_UNLESS(fuse_mem_size <= phys_mem_size);
|
||||||
|
|
||||||
|
if (fuse_mem_size == phys_mem_size) {
|
||||||
|
return dram_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Adjust Dram ID to match density/ranks. */
|
||||||
|
if (GetSocType() == fuse::SocType_Erista) {
|
||||||
|
return fuse::DramId_IcosaSamsung6GB;
|
||||||
|
} else { /* fuse::SocType_Mariko */
|
||||||
|
return fuse::DramId_IowaSamsung1y8GBX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constinit u64 g_payload_address = 0;
|
constinit u64 g_payload_address = 0;
|
||||||
constinit bool g_set_true_target_firmware = false;
|
constinit bool g_set_true_target_firmware = false;
|
||||||
|
|
||||||
@@ -178,7 +204,7 @@ namespace ams::secmon::smc {
|
|||||||
args.r[1] = GetBootConfig().signed_data.IsProgramVerificationDisabled();
|
args.r[1] = GetBootConfig().signed_data.IsProgramVerificationDisabled();
|
||||||
break;
|
break;
|
||||||
case ConfigItem::DramId:
|
case ConfigItem::DramId:
|
||||||
args.r[1] = fuse::GetDramId();
|
args.r[1] = GetDramIdAdjusted(); /* Nintendo: fuse::GetDramId() */
|
||||||
break;
|
break;
|
||||||
case ConfigItem::SecurityEngineInterruptNumber:
|
case ConfigItem::SecurityEngineInterruptNumber:
|
||||||
args.r[1] = SecurityEngineUserInterruptId;
|
args.r[1] = SecurityEngineUserInterruptId;
|
||||||
@@ -471,9 +497,18 @@ namespace ams::secmon::smc {
|
|||||||
|
|
||||||
/* For exosphere's usage. */
|
/* For exosphere's usage. */
|
||||||
pkg1::MemorySize GetPhysicalMemorySize() {
|
pkg1::MemorySize GetPhysicalMemorySize() {
|
||||||
const auto dram_id = fuse::GetDramId();
|
const uintptr_t MC = secmon::MemoryRegionVirtualDeviceMemoryController.GetAddress();
|
||||||
AMS_ABORT_UNLESS(dram_id < fuse::DramId_Count);
|
const u32 mem_size = reg::Read(MC + MC_EMEM_CFG) & 0x3FFF;
|
||||||
return DramIdToMemorySize[dram_id];
|
|
||||||
|
switch (mem_size >> 10) {
|
||||||
|
case 4:
|
||||||
|
default:
|
||||||
|
return pkg1::MemorySize_4GB;
|
||||||
|
case 6:
|
||||||
|
return pkg1::MemorySize_6GB;
|
||||||
|
case 8:
|
||||||
|
return pkg1::MemorySize_8GB;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -545,6 +545,12 @@ namespace ams::nxboot {
|
|||||||
} else {
|
} else {
|
||||||
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess;
|
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_EnableUserModePerformanceCounterAccess;
|
||||||
}
|
}
|
||||||
|
} else if (std::strcmp(entry.key, "enable_mem_mode") == 0) {
|
||||||
|
if (entry.value[0] == '1') {
|
||||||
|
storage_ctx.flags[0] |= secmon::SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled;
|
||||||
|
} else {
|
||||||
|
storage_ctx.flags[0] &= ~secmon::SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled;
|
||||||
|
}
|
||||||
} else if (std::strcmp(entry.key, "blank_prodinfo_sysmmc") == 0) {
|
} else if (std::strcmp(entry.key, "blank_prodinfo_sysmmc") == 0) {
|
||||||
if (!emummc_enabled) {
|
if (!emummc_enabled) {
|
||||||
if (entry.value[0] == '1') {
|
if (entry.value[0] == '1') {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
[subrepo]
|
[subrepo]
|
||||||
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
remote = https://github.com/Atmosphere-NX/Atmosphere-libs
|
||||||
branch = master
|
branch = master
|
||||||
commit = 9a8703e710760be8c88147d15414a1c581711625
|
commit = 82f1553c4c7e68364f7e630b1c68f2aee8681dee
|
||||||
parent = eb34f9789c62745d87f37e76761b14d946bac300
|
parent = 252f8685b493d0dfd428e9439b0296109776b935
|
||||||
method = merge
|
method = merge
|
||||||
cmdver = 0.4.1
|
cmdver = 0.4.9
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace ams::secmon {
|
|||||||
SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5),
|
SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary = (1u << 5),
|
||||||
SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6),
|
SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc = (1u << 6),
|
||||||
SecureMonitorConfigurationFlag_ForceEnableUsb30 = (1u << 7),
|
SecureMonitorConfigurationFlag_ForceEnableUsb30 = (1u << 7),
|
||||||
|
SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled = (1u << 8),
|
||||||
|
|
||||||
SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel,
|
SecureMonitorConfigurationFlag_Default = SecureMonitorConfigurationFlag_IsDevelopmentFunctionEnabledForKernel,
|
||||||
};
|
};
|
||||||
@@ -103,6 +104,7 @@ namespace ams::secmon {
|
|||||||
constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; }
|
constexpr bool ShouldUseBlankCalibrationBinary() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ShouldUseBlankCalibrationBinary) != 0; }
|
||||||
constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; }
|
constexpr bool AllowWritingToCalibrationBinarySysmmc() const { return (this->flags[0] & SecureMonitorConfigurationFlag_AllowWritingToCalibrationBinarySysmmc) != 0; }
|
||||||
constexpr bool IsUsb30ForceEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ForceEnableUsb30) != 0; }
|
constexpr bool IsUsb30ForceEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_ForceEnableUsb30) != 0; }
|
||||||
|
constexpr bool IsBootConfigMemoryModeEnabled() const { return (this->flags[0] & SecureMonitorConfigurationFlag_BootConfigMemoryModeEnabled) != 0; }
|
||||||
|
|
||||||
constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); }
|
constexpr bool IsDevelopmentFunctionEnabled(bool for_kern) const { return for_kern ? this->IsDevelopmentFunctionEnabledForKernel() : this->IsDevelopmentFunctionEnabledForUser(); }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,6 +111,7 @@ namespace ams::erpt {
|
|||||||
|
|
||||||
struct CreateReportOptionFlag {
|
struct CreateReportOptionFlag {
|
||||||
using SubmitFsInfo = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>::Flag<0>;
|
using SubmitFsInfo = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>::Flag<0>;
|
||||||
|
using Unknown0x20000 = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>::Flag<17>; /* TODO: What is this, it's checked in Reporter::CreateReport or below */
|
||||||
};
|
};
|
||||||
|
|
||||||
using CreateReportOptionFlagSet = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>;
|
using CreateReportOptionFlagSet = util::BitFlagSet<BITSIZEOF(u32), CreateReportOptionFlag>;
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ namespace ams::fs {
|
|||||||
|
|
||||||
struct GameCardErrorReportInfo {
|
struct GameCardErrorReportInfo {
|
||||||
u16 game_card_crc_error_num;
|
u16 game_card_crc_error_num;
|
||||||
u16 reserved1;
|
u8 last_deactivate_reason;
|
||||||
|
u8 reserved1;
|
||||||
u16 asic_crc_error_num;
|
u16 asic_crc_error_num;
|
||||||
u16 reserved2;
|
u16 reserved2;
|
||||||
u16 refresh_num;
|
u16 refresh_num;
|
||||||
@@ -73,7 +74,8 @@ namespace ams::fs {
|
|||||||
u32 awaken_count;
|
u32 awaken_count;
|
||||||
u32 read_count_from_insert;
|
u32 read_count_from_insert;
|
||||||
u32 read_count_from_awaken;
|
u32 read_count_from_awaken;
|
||||||
u8 reserved5[8];
|
u32 last_deactivate_reason_result;
|
||||||
|
u32 reserved5;
|
||||||
};
|
};
|
||||||
static_assert(util::is_pod<GameCardErrorReportInfo>::value);
|
static_assert(util::is_pod<GameCardErrorReportInfo>::value);
|
||||||
static_assert(sizeof(GameCardErrorReportInfo) == 0x40);
|
static_assert(sizeof(GameCardErrorReportInfo) == 0x40);
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ namespace ams::hos {
|
|||||||
Version_21_1_0 = ::ams::TargetFirmware_21_1_0,
|
Version_21_1_0 = ::ams::TargetFirmware_21_1_0,
|
||||||
Version_21_2_0 = ::ams::TargetFirmware_21_2_0,
|
Version_21_2_0 = ::ams::TargetFirmware_21_2_0,
|
||||||
Version_22_0_0 = ::ams::TargetFirmware_22_0_0,
|
Version_22_0_0 = ::ams::TargetFirmware_22_0_0,
|
||||||
|
Version_22_1_0 = ::ams::TargetFirmware_22_1_0,
|
||||||
|
|
||||||
Version_Current = ::ams::TargetFirmware_Current,
|
Version_Current = ::ams::TargetFirmware_Current,
|
||||||
|
|
||||||
|
|||||||
@@ -19,5 +19,6 @@
|
|||||||
namespace ams::erpt::srv {
|
namespace ams::erpt::srv {
|
||||||
|
|
||||||
Result SubmitFsInfo();
|
Result SubmitFsInfo();
|
||||||
|
void ClearFsInfo();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -363,6 +363,8 @@ namespace ams::erpt::srv {
|
|||||||
R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromAwaken, ei.read_count_from_awaken));
|
R_ABORT_UNLESS(record->Add(FieldId_GameCardReadCountFromAwaken, ei.read_count_from_awaken));
|
||||||
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageAddress, ei.last_read_error_page_address));
|
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageAddress, ei.last_read_error_page_address));
|
||||||
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageCount, ei.last_read_error_page_count));
|
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastReadErrorPageCount, ei.last_read_error_page_count));
|
||||||
|
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastDeactivateReasonResult, ei.last_deactivate_reason_result));
|
||||||
|
R_ABORT_UNLESS(record->Add(FieldId_GameCardLastDeactivateReason, ei.last_deactivate_reason));
|
||||||
|
|
||||||
/* Submit the record. */
|
/* Submit the record. */
|
||||||
R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record)));
|
R_ABORT_UNLESS(Context::SubmitContextRecord(std::move(record)));
|
||||||
@@ -496,4 +498,27 @@ namespace ams::erpt::srv {
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClearFsInfo() {
|
||||||
|
Context::ClearContext(CategoryId_NANDTypeInfo);
|
||||||
|
Context::ClearContext(CategoryId_NANDSpeedModeInfo);
|
||||||
|
Context::ClearContext(CategoryId_NANDExtendedCsd);
|
||||||
|
Context::ClearContext(CategoryId_NANDPatrolInfo);
|
||||||
|
Context::ClearContext(CategoryId_NANDErrorInfo);
|
||||||
|
Context::ClearContext(CategoryId_NANDDriverLog);
|
||||||
|
Context::ClearContext(CategoryId_MicroSDTypeInfo);
|
||||||
|
Context::ClearContext(CategoryId_MicroSDSpeedModeInfo);
|
||||||
|
Context::ClearContext(CategoryId_SdCardSizeSpec);
|
||||||
|
Context::ClearContext(CategoryId_SdCardActivationInfo);
|
||||||
|
Context::ClearContext(CategoryId_SdCardErrorInfo);
|
||||||
|
Context::ClearContext(CategoryId_SdCardDriverLog);
|
||||||
|
Context::ClearContext(CategoryId_GameCardCIDInfo);
|
||||||
|
Context::ClearContext(CategoryId_GameCardErrorInfo);
|
||||||
|
Context::ClearContext(CategoryId_GameCardDetailedErrorInfo);
|
||||||
|
Context::ClearContext(CategoryId_GameCardLogInfo);
|
||||||
|
Context::ClearContext(CategoryId_FsProxyErrorInfo);
|
||||||
|
Context::ClearContext(CategoryId_FsProxyErrorInfo2);
|
||||||
|
Context::ClearContext(CategoryId_FsProxyErrorInfo3);
|
||||||
|
Context::ClearContext(CategoryId_FsMemoryInfo);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -423,7 +423,11 @@ namespace ams::erpt::srv {
|
|||||||
|
|
||||||
auto report = std::make_unique<Report>(record.get(), redirect_new_reports);
|
auto report = std::make_unique<Report>(record.get(), redirect_new_reports);
|
||||||
R_UNLESS(report != nullptr, erpt::ResultOutOfMemory());
|
R_UNLESS(report != nullptr, erpt::ResultOutOfMemory());
|
||||||
auto report_guard = SCOPE_GUARD { const auto delete_res = report->Delete(); R_ASSERT(delete_res); AMS_UNUSED(delete_res); };
|
auto report_guard = SCOPE_GUARD {
|
||||||
|
const auto delete_res = report->Delete();
|
||||||
|
R_ASSERT(delete_res);
|
||||||
|
AMS_UNUSED(delete_res);
|
||||||
|
};
|
||||||
|
|
||||||
R_TRY(Context::WriteContextsToReport(report.get()));
|
R_TRY(Context::WriteContextsToReport(report.get()));
|
||||||
R_TRY(report->GetSize(std::addressof(record->m_info.report_size)));
|
R_TRY(report->GetSize(std::addressof(record->m_info.report_size)));
|
||||||
@@ -434,7 +438,7 @@ namespace ams::erpt::srv {
|
|||||||
} else {
|
} else {
|
||||||
/* If we are redirecting new reports, we don't want to store the report in the journal. */
|
/* If we are redirecting new reports, we don't want to store the report in the journal. */
|
||||||
/* We should take this opportunity to delete any attachments associated with the report. */
|
/* We should take this opportunity to delete any attachments associated with the report. */
|
||||||
R_ABORT_UNLESS(JournalForAttachments::DeleteAttachments(report_id));
|
R_TRY(JournalForAttachments::DeleteAttachments(report_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
R_TRY(Journal::Commit());
|
R_TRY(Journal::Commit());
|
||||||
@@ -489,6 +493,20 @@ namespace ams::erpt::srv {
|
|||||||
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfo));
|
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfo));
|
||||||
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfoAuto));
|
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfoAuto));
|
||||||
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfoDefaults));
|
static_cast<void>(Context::ClearContext(CategoryId_ErrorInfoDefaults));
|
||||||
|
|
||||||
|
#if defined(ATMOSPHERE_OS_HORIZON)
|
||||||
|
/* TODO: What else is missing? */
|
||||||
|
if (hos::GetVersion() >= hos::Version_17_0_0 && flags.Test<CreateReportOptionFlag::SubmitFsInfo>()) {
|
||||||
|
ClearFsInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if (erpt::ResultInvalidPowerState::Includes(...)) {
|
||||||
|
* Nintendo ignores this and sends "power_state_violation" play report if this error happens.
|
||||||
|
* } else {
|
||||||
|
* Nintendo sends "write_failure" play report if any other error happens.
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get the context entry pointer. */
|
/* Get the context entry pointer. */
|
||||||
|
|||||||
@@ -75,15 +75,15 @@ namespace ams::pgl::srv {
|
|||||||
NON_COPYABLE(HostPackageReader);
|
NON_COPYABLE(HostPackageReader);
|
||||||
NON_MOVEABLE(HostPackageReader);
|
NON_MOVEABLE(HostPackageReader);
|
||||||
private:
|
private:
|
||||||
char m_content_path[fs::EntryNameLengthMax] = {};
|
char m_content_path[fs::EntryNameLengthMax] = {};
|
||||||
ExtensionType m_extension_type = ExtensionType::None;
|
ExtensionType m_extension_type = ExtensionType::None;
|
||||||
char m_mount_name[fs::MountNameLengthMax] = {};
|
char m_mount_name[fs::MountNameLengthMax + 1] = {};
|
||||||
bool m_is_mounted = false;
|
bool m_is_mounted = false;
|
||||||
ncm::AutoBuffer m_content_meta_buffer;
|
ncm::AutoBuffer m_content_meta_buffer;
|
||||||
ncm::ProgramId m_program_id = ncm::InvalidProgramId;
|
ncm::ProgramId m_program_id = ncm::InvalidProgramId;
|
||||||
u32 m_program_version = 0;
|
u32 m_program_version = 0;
|
||||||
ncm::ContentMetaType m_content_meta_type = static_cast<ncm::ContentMetaType>(0);
|
ncm::ContentMetaType m_content_meta_type = static_cast<ncm::ContentMetaType>(0);
|
||||||
u8 m_program_index = 0;
|
u8 m_program_index = 0;
|
||||||
public:
|
public:
|
||||||
HostPackageReader() : m_content_meta_buffer() { /* ... */ }
|
HostPackageReader() : m_content_meta_buffer() { /* ... */ }
|
||||||
~HostPackageReader() {
|
~HostPackageReader() {
|
||||||
|
|||||||
@@ -17,10 +17,10 @@
|
|||||||
|
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
|
#define ATMOSPHERE_RELEASE_VERSION_MAJOR 1
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MINOR 11
|
#define ATMOSPHERE_RELEASE_VERSION_MINOR 11
|
||||||
#define ATMOSPHERE_RELEASE_VERSION_MICRO 0
|
#define ATMOSPHERE_RELEASE_VERSION_MICRO 1
|
||||||
|
|
||||||
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
|
#define ATMOSPHERE_RELEASE_VERSION ATMOSPHERE_RELEASE_VERSION_MAJOR, ATMOSPHERE_RELEASE_VERSION_MINOR, ATMOSPHERE_RELEASE_VERSION_MICRO
|
||||||
|
|
||||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 22
|
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MAJOR 22
|
||||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 0
|
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MINOR 1
|
||||||
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0
|
#define ATMOSPHERE_SUPPORTED_HOS_VERSION_MICRO 0
|
||||||
|
|||||||
@@ -99,8 +99,9 @@
|
|||||||
#define ATMOSPHERE_TARGET_FIRMWARE_21_1_0 ATMOSPHERE_TARGET_FIRMWARE(21, 1, 0)
|
#define ATMOSPHERE_TARGET_FIRMWARE_21_1_0 ATMOSPHERE_TARGET_FIRMWARE(21, 1, 0)
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_21_2_0 ATMOSPHERE_TARGET_FIRMWARE(21, 2, 0)
|
#define ATMOSPHERE_TARGET_FIRMWARE_21_2_0 ATMOSPHERE_TARGET_FIRMWARE(21, 2, 0)
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_22_0_0 ATMOSPHERE_TARGET_FIRMWARE(22, 0, 0)
|
#define ATMOSPHERE_TARGET_FIRMWARE_22_0_0 ATMOSPHERE_TARGET_FIRMWARE(22, 0, 0)
|
||||||
|
#define ATMOSPHERE_TARGET_FIRMWARE_22_1_0 ATMOSPHERE_TARGET_FIRMWARE(22, 1, 0)
|
||||||
|
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_22_0_0
|
#define ATMOSPHERE_TARGET_FIRMWARE_CURRENT ATMOSPHERE_TARGET_FIRMWARE_22_1_0
|
||||||
|
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
|
#define ATMOSPHERE_TARGET_FIRMWARE_MIN ATMOSPHERE_TARGET_FIRMWARE(0, 0, 0)
|
||||||
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
#define ATMOSPHERE_TARGET_FIRMWARE_MAX ATMOSPHERE_TARGET_FIRMWARE_CURRENT
|
||||||
@@ -192,6 +193,7 @@ namespace ams {
|
|||||||
TargetFirmware_21_1_0 = ATMOSPHERE_TARGET_FIRMWARE_21_1_0,
|
TargetFirmware_21_1_0 = ATMOSPHERE_TARGET_FIRMWARE_21_1_0,
|
||||||
TargetFirmware_21_2_0 = ATMOSPHERE_TARGET_FIRMWARE_21_2_0,
|
TargetFirmware_21_2_0 = ATMOSPHERE_TARGET_FIRMWARE_21_2_0,
|
||||||
TargetFirmware_22_0_0 = ATMOSPHERE_TARGET_FIRMWARE_22_0_0,
|
TargetFirmware_22_0_0 = ATMOSPHERE_TARGET_FIRMWARE_22_0_0,
|
||||||
|
TargetFirmware_22_1_0 = ATMOSPHERE_TARGET_FIRMWARE_22_1_0,
|
||||||
|
|
||||||
TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,
|
TargetFirmware_Current = ATMOSPHERE_TARGET_FIRMWARE_CURRENT,
|
||||||
|
|
||||||
|
|||||||
@@ -452,6 +452,9 @@ namespace ams::result::impl {
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Explicitly discards the result returned by an expression.
|
||||||
|
#define R_DISCARD(res_expr) (static_cast<void>(res_expr))
|
||||||
|
|
||||||
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX) && defined(ATMOSPHERE_IS_STRATOSPHERE) && !defined(AMS_ENABLE_DETAILED_ASSERTIONS) && !defined(AMS_BUILD_FOR_DEBUGGING) && !defined(AMS_BUILD_FOR_AUDITING)
|
#if defined(ATMOSPHERE_BOARD_NINTENDO_NX) && defined(ATMOSPHERE_IS_STRATOSPHERE) && !defined(AMS_ENABLE_DETAILED_ASSERTIONS) && !defined(AMS_BUILD_FOR_DEBUGGING) && !defined(AMS_BUILD_FOR_AUDITING)
|
||||||
#define AMS_CALL_ON_RESULT_ASSERTION_IMPL(cond, val) do { ::ams::diag::impl::FatalErrorByResultForNx(val); AMS_INFINITE_LOOP(); AMS_ASSUME(false); } while (false)
|
#define AMS_CALL_ON_RESULT_ASSERTION_IMPL(cond, val) do { ::ams::diag::impl::FatalErrorByResultForNx(val); AMS_INFINITE_LOOP(); AMS_ASSUME(false); } while (false)
|
||||||
#define AMS_CALL_ON_RESULT_ABORT_IMPL(cond, val) do { ::ams::diag::impl::FatalErrorByResultForNx(val); AMS_INFINITE_LOOP(); AMS_ASSUME(false); } while (false)
|
#define AMS_CALL_ON_RESULT_ABORT_IMPL(cond, val) do { ::ams::diag::impl::FatalErrorByResultForNx(val); AMS_INFINITE_LOOP(); AMS_ASSUME(false); } while (false)
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ namespace ams::mitm::fs {
|
|||||||
};
|
};
|
||||||
|
|
||||||
constexpr const ApplicationWithDynamicHeapInfo ApplicationsWithDynamicHeap[] = {
|
constexpr const ApplicationWithDynamicHeapInfo ApplicationsWithDynamicHeap[] = {
|
||||||
|
/* Until Then. */
|
||||||
|
/* Requirement ~34 MB. */
|
||||||
|
/* No particular heap sensitivity. */
|
||||||
|
{ 0x010019C023004000, 16_MB, 0_MB },
|
||||||
|
|
||||||
/* Trails in the Sky 1st Chapter. */
|
/* Trails in the Sky 1st Chapter. */
|
||||||
/* Requirement ? MB. 16 MB stolen heap fixes a crash, though. */
|
/* Requirement ? MB. 16 MB stolen heap fixes a crash, though. */
|
||||||
/* Unknown heap sensitivity. */
|
/* Unknown heap sensitivity. */
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) Atmosphère-NX
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms and conditions of the GNU General Public License,
|
|
||||||
* version 2, as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
* more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define AMS_ZSTD_IMPLEMENTATION
|
|
||||||
#include <stratosphere/util/util_zbic_for_loader.hpp>
|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
"filesystem_access": {
|
"filesystem_access": {
|
||||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||||
},
|
},
|
||||||
"service_access": ["erpt:c", "fatal:u", "fsp-srv", "ldr:shel", "lm", "lr", "pm:shell", "set", "set:sys"],
|
"service_access": ["fatal:u", "fsp-srv", "ldr:shel", "lr", "pm:shell", "set:sys"],
|
||||||
"service_host": ["pgl"],
|
"service_host": ["pgl"],
|
||||||
"kernel_capabilities": [{
|
"kernel_capabilities": [{
|
||||||
"type": "kernel_flags",
|
"type": "kernel_flags",
|
||||||
|
|||||||
@@ -31,12 +31,13 @@ namespace ams {
|
|||||||
fs::SetAllocator(pgl::srv::Allocate, pgl::srv::Deallocate);
|
fs::SetAllocator(pgl::srv::Allocate, pgl::srv::Deallocate);
|
||||||
fs::SetEnabledAutoAbort(false);
|
fs::SetEnabledAutoAbort(false);
|
||||||
|
|
||||||
|
/* Initialize lr. */
|
||||||
|
lr::Initialize();
|
||||||
|
|
||||||
/* Initialize other services we need. */
|
/* Initialize other services we need. */
|
||||||
R_ABORT_UNLESS(setInitialize());
|
|
||||||
R_ABORT_UNLESS(setsysInitialize());
|
R_ABORT_UNLESS(setsysInitialize());
|
||||||
R_ABORT_UNLESS(pmshellInitialize());
|
R_ABORT_UNLESS(pmshellInitialize());
|
||||||
R_ABORT_UNLESS(ldrShellInitialize());
|
R_ABORT_UNLESS(ldrShellInitialize());
|
||||||
R_ABORT_UNLESS(lrInitialize());
|
|
||||||
|
|
||||||
/* Verify that we can sanely execute. */
|
/* Verify that we can sanely execute. */
|
||||||
ams::CheckApiVersion();
|
ams::CheckApiVersion();
|
||||||
@@ -58,3 +59,36 @@ namespace ams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Override operator new. */
|
||||||
|
void *operator new(size_t size) {
|
||||||
|
return ams::pgl::srv::Allocate(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new(size_t size, const std::nothrow_t &) {
|
||||||
|
return ams::pgl::srv::Allocate(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void *p) {
|
||||||
|
return ams::pgl::srv::Deallocate(p, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void *p, size_t size) {
|
||||||
|
return ams::pgl::srv::Deallocate(p, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](size_t size) {
|
||||||
|
return ams::pgl::srv::Allocate(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](size_t size, const std::nothrow_t &) {
|
||||||
|
return ams::pgl::srv::Allocate(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void *p) {
|
||||||
|
return ams::pgl::srv::Deallocate(p, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete[](void *p, size_t size) {
|
||||||
|
return ams::pgl::srv::Deallocate(p, size);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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