diff --git a/src/core/file_sys/title_metadata.cpp b/src/core/file_sys/title_metadata.cpp index 8fed6f0..41d818b 100644 --- a/src/core/file_sys/title_metadata.cpp +++ b/src/core/file_sys/title_metadata.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "common/alignment.h" #include "common/assert.h" #include "common/file_util.h" @@ -164,6 +165,12 @@ u16 TitleMetadata::GetTitleVersion() const { return tmd_body.title_version; } +std::string TitleMetadata::GetTitleVersionString() const { + const auto title_version = static_cast(tmd_body.title_version); + return fmt::format("{}.{}.{}", (title_version >> 10) & 0x3F, (title_version >> 4) & 0x3F, + title_version & 0xF); +} + u64 TitleMetadata::GetSystemVersion() const { return tmd_body.system_version; } diff --git a/src/core/file_sys/title_metadata.h b/src/core/file_sys/title_metadata.h index 01a6937..e21d012 100644 --- a/src/core/file_sys/title_metadata.h +++ b/src/core/file_sys/title_metadata.h @@ -90,6 +90,7 @@ public: u64 GetTitleID() const; u32 GetTitleType() const; u16 GetTitleVersion() const; + std::string GetTitleVersionString() const; u64 GetSystemVersion() const; std::size_t GetContentCount() const; u32 GetBootContentID() const; diff --git a/src/core/importer.cpp b/src/core/importer.cpp index dd8ed5e..a0c8c26 100644 --- a/src/core/importer.cpp +++ b/src/core/importer.cpp @@ -601,13 +601,13 @@ static std::string GetTitleFileName(NCCHContainer& ncch) { if (!ncch.LoadSectionExeFS("icon", smdh_buffer) || smdh_buffer.size() != sizeof(SMDH)) { LOG_WARNING(Core, "Failed to load icon in ExeFS or size incorrect"); return NormalizeFilename( - fmt::format("{:016x} {} ({})", program_id, codeset_name, product_code)); + fmt::format("{:016X} {} ({})", program_id, codeset_name, product_code)); } else { SMDH smdh; std::memcpy(&smdh, smdh_buffer.data(), smdh_buffer.size()); const auto short_title = Common::UTF16BufferToUTF8(smdh.GetShortTitle(SMDH::TitleLanguage::English)); - return NormalizeFilename(fmt::format("{:016x} {} ({}) ({})", program_id, short_title, + return NormalizeFilename(fmt::format("{:016X} {} ({}) ({})", program_id, short_title, product_code, smdh.GetRegionString())); } } @@ -699,10 +699,10 @@ bool SDMCImporter::BuildCIA(CIABuildType build_type, const ContentSpecifier& spe : fmt::format("{}title/{:08x}/{:08x}/content/", config.sdmc_path, (specifier.id >> 32), (specifier.id & 0xFFFFFFFF)); - static constexpr std::array BuildTypeSuffixes{{ - ".standard.cia", - ".pirate-legit.cia", - ".legit.cia", + static constexpr std::array BuildTypeExts{{ + "standard.cia", + "piratelegit.cia", + "legit.cia", }}; if (auto_filename) { if (destination.back() != '/' && destination.back() != '\\') { @@ -710,16 +710,17 @@ bool SDMCImporter::BuildCIA(CIABuildType build_type, const ContentSpecifier& spe } const auto boot_content_path = fmt::format("{}{:08x}.app", physical_path, tmd.GetBootContentID()); + NCCHContainer ncch; if (is_nand) { - NCCHContainer ncch(std::make_shared(boot_content_path, "rb")); - destination.append(GetTitleFileName(ncch)) - .append(BuildTypeSuffixes.at(static_cast(build_type))); + ncch.OpenFile(std::make_shared(boot_content_path, "rb")); } else { const auto relative_path = boot_content_path.substr(config.sdmc_path.size() - 1); - NCCHContainer ncch(std::make_shared(config.sdmc_path, relative_path, "rb")); - destination.append(GetTitleFileName(ncch)) - .append(BuildTypeSuffixes.at(static_cast(build_type))); + ncch.OpenFile(std::make_shared(config.sdmc_path, relative_path, "rb")); } + const auto filename = + fmt::format("{} (v{}).{}", GetTitleFileName(ncch), tmd.GetTitleVersionString(), + BuildTypeExts.at(static_cast(build_type))); + destination.append(filename); } bool ret = cia_builder->Init(build_type, destination, tmd, specifier.maximum_size, callback);