From 318bf7c8e3a31d444fa0308804b4c1cf0c2470be Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 15 Jan 2019 15:56:32 -0500 Subject: [PATCH 1/2] content_archive: Add getter for logo section of NCA --- src/core/file_sys/content_archive.cpp | 6 ++++++ src/core/file_sys/content_archive.h | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 19b6f8600..5aa3b600b 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -359,6 +359,8 @@ bool NCA::ReadPFS0Section(const NCASectionHeader& section, const NCASectionTable dirs.push_back(std::move(npfs)); if (IsDirectoryExeFS(dirs.back())) exefs = dirs.back(); + else if (IsDirectoryLogoPartition(dirs.back())) + logo = dirs.back(); } else { if (has_rights_id) status = Loader::ResultStatus::ErrorIncorrectTitlekeyOrTitlekek; @@ -546,4 +548,8 @@ u64 NCA::GetBaseIVFCOffset() const { return ivfc_offset; } +VirtualDir NCA::GetLogoPartition() const { + return logo; +} + } // namespace FileSys diff --git a/src/core/file_sys/content_archive.h b/src/core/file_sys/content_archive.h index 99294cbb4..5d4d05c82 100644 --- a/src/core/file_sys/content_archive.h +++ b/src/core/file_sys/content_archive.h @@ -74,6 +74,13 @@ inline bool IsDirectoryExeFS(const std::shared_ptr& pfs) { return pfs->GetFile("main") != nullptr && pfs->GetFile("main.npdm") != nullptr; } +inline bool IsDirectoryLogoPartition(const VirtualDir& pfs) { + // NintendoLogo is the static image in the top left corner while StartupMovie is the animation + // in the bottom right corner. + return pfs->GetFile("NintendoLogo.png") != nullptr && + pfs->GetFile("StartupMovie.gif") != nullptr; +} + // An implementation of VfsDirectory that represents a Nintendo Content Archive (NCA) conatiner. // After construction, use GetStatus to determine if the file is valid and ready to be used. class NCA : public ReadOnlyVfsDirectory { @@ -102,6 +109,8 @@ public: // Returns the base ivfc offset used in BKTR patching. u64 GetBaseIVFCOffset() const; + VirtualDir GetLogoPartition() const; + private: bool CheckSupportedNCA(const NCAHeader& header); bool HandlePotentialHeaderDecryption(); @@ -122,6 +131,7 @@ private: VirtualFile romfs = nullptr; VirtualDir exefs = nullptr; + VirtualDir logo = nullptr; VirtualFile file; VirtualFile bktr_base_romfs; u64 ivfc_offset = 0; From b273b195762433ab015ec015061414aac4b9683e Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 15 Jan 2019 15:56:52 -0500 Subject: [PATCH 2/2] loader: Propagate NCA logo section to ReadBanner and ReadLogo --- src/core/loader/loader.h | 4 ++++ src/core/loader/nax.cpp | 9 +++++++++ src/core/loader/nax.h | 3 +++ src/core/loader/nca.cpp | 19 +++++++++++++++++++ src/core/loader/nca.h | 3 +++ src/core/loader/nsp.cpp | 9 +++++++++ src/core/loader/nsp.h | 3 +++ src/core/loader/xci.cpp | 8 ++++++++ src/core/loader/xci.h | 3 +++ 9 files changed, 61 insertions(+) diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 01f984098..bb925f4a6 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -178,6 +178,8 @@ public: /** * Get the banner (typically banner section) of the application + * In the context of NX, this is the animation that displays in the bottom right of the screen + * when a game boots. Stored in GIF format. * @param buffer Reference to buffer to store data * @return ResultStatus result of function */ @@ -187,6 +189,8 @@ public: /** * Get the logo (typically logo section) of the application + * In the context of NX, this is the static image that displays in the top left of the screen + * when a game boots. Stored in JPEG format. * @param buffer Reference to buffer to store data * @return ResultStatus result of function */ diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp index a093e3d36..93a970d10 100644 --- a/src/core/loader/nax.cpp +++ b/src/core/loader/nax.cpp @@ -79,4 +79,13 @@ u64 AppLoader_NAX::ReadRomFSIVFCOffset() const { ResultStatus AppLoader_NAX::ReadProgramId(u64& out_program_id) { return nca_loader->ReadProgramId(out_program_id); } + +ResultStatus AppLoader_NAX::ReadBanner(std::vector& buffer) { + return nca_loader->ReadBanner(buffer); +} + +ResultStatus AppLoader_NAX::ReadLogo(std::vector& buffer) { + return nca_loader->ReadLogo(buffer); +} + } // namespace Loader diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h index 0a97511b8..f40079574 100644 --- a/src/core/loader/nax.h +++ b/src/core/loader/nax.h @@ -39,6 +39,9 @@ public: u64 ReadRomFSIVFCOffset() const override; ResultStatus ReadProgramId(u64& out_program_id) override; + ResultStatus ReadBanner(std::vector& buffer) override; + ResultStatus ReadLogo(std::vector& buffer) override; + private: std::unique_ptr nax; std::unique_ptr nca_loader; diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 7e1b0d84f..ce8196fcf 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -84,4 +84,23 @@ ResultStatus AppLoader_NCA::ReadProgramId(u64& out_program_id) { return ResultStatus::Success; } +ResultStatus AppLoader_NCA::ReadBanner(std::vector& buffer) { + if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) + return ResultStatus::ErrorNotInitialized; + const auto logo = nca->GetLogoPartition(); + if (logo == nullptr) + return ResultStatus::ErrorNoIcon; + buffer = logo->GetFile("StartupMovie.gif")->ReadAllBytes(); + return ResultStatus::Success; +} + +ResultStatus AppLoader_NCA::ReadLogo(std::vector& buffer) { + if (nca == nullptr || nca->GetStatus() != ResultStatus::Success) + return ResultStatus::ErrorNotInitialized; + const auto logo = nca->GetLogoPartition(); + if (logo == nullptr) + return ResultStatus::ErrorNoIcon; + buffer = logo->GetFile("NintendoLogo.png")->ReadAllBytes(); + return ResultStatus::Success; +} } // namespace Loader diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index cbbe701d2..b9f077468 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -39,6 +39,9 @@ public: u64 ReadRomFSIVFCOffset() const override; ResultStatus ReadProgramId(u64& out_program_id) override; + ResultStatus ReadBanner(std::vector& buffer) override; + ResultStatus ReadLogo(std::vector& buffer) override; + private: std::unique_ptr nca; std::unique_ptr directory_loader; diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 7fcb12aa2..7da1f8960 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -166,4 +166,13 @@ ResultStatus AppLoader_NSP::ReadManualRomFS(FileSys::VirtualFile& file) { file = nca->GetRomFS(); return file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success; } + +ResultStatus AppLoader_NSP::ReadBanner(std::vector& buffer) { + return secondary_loader->ReadBanner(buffer); +} + +ResultStatus AppLoader_NSP::ReadLogo(std::vector& buffer) { + return secondary_loader->ReadLogo(buffer); +} + } // namespace Loader diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index b6b309400..953a1b508 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -46,6 +46,9 @@ public: ResultStatus ReadControlData(FileSys::NACP& nacp) override; ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) override; + ResultStatus ReadBanner(std::vector& buffer) override; + ResultStatus ReadLogo(std::vector& buffer) override; + private: std::unique_ptr nsp; std::unique_ptr secondary_loader; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index ff60a3756..89f7bbf77 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -137,4 +137,12 @@ ResultStatus AppLoader_XCI::ReadManualRomFS(FileSys::VirtualFile& file) { return file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success; } +ResultStatus AppLoader_XCI::ReadBanner(std::vector& buffer) { + return nca_loader->ReadBanner(buffer); +} + +ResultStatus AppLoader_XCI::ReadLogo(std::vector& buffer) { + return nca_loader->ReadLogo(buffer); +} + } // namespace Loader diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index e18531c93..d6995b61e 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -46,6 +46,9 @@ public: ResultStatus ReadControlData(FileSys::NACP& control) override; ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) override; + ResultStatus ReadBanner(std::vector& buffer) override; + ResultStatus ReadLogo(std::vector& buffer) override; + private: std::unique_ptr xci; std::unique_ptr nca_loader;