diff options
Diffstat (limited to 'src/core/file_sys/registered_cache.cpp')
| -rw-r--r-- | src/core/file_sys/registered_cache.cpp | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp index 9e9db0ed4d..83f5e265dd 100644 --- a/src/core/file_sys/registered_cache.cpp +++ b/src/core/file_sys/registered_cache.cpp @@ -567,20 +567,45 @@ VirtualFile RegisteredCache::GetFileAtID(NcaID id) const { } static std::optional<NcaID> CheckMapForContentRecord(const ankerl::unordered_dense::map<u64, CNMT>& map, u64 title_id, ContentRecordType type) { - const auto cmnt_iter = map.find(title_id); + auto cmnt_iter = map.find(title_id); + u8 id_offset = 0; + if (cmnt_iter == map.cend()) { - return std::nullopt; + const auto program_index = title_id & AOC_TITLE_ID_MASK; + if (program_index == 0) { + return std::nullopt; + } + + cmnt_iter = map.find(title_id & ~AOC_TITLE_ID_MASK); + if (cmnt_iter == map.cend()) { + return std::nullopt; + } + + id_offset = static_cast<u8>(program_index); } const auto& cnmt = cmnt_iter->second; const auto& content_records = cnmt.GetContentRecords(); const auto iter = std::find_if(content_records.cbegin(), content_records.cend(), - [type](const ContentRecord& rec) { return rec.type == type; }); - if (iter == content_records.cend()) { + [type, id_offset](const ContentRecord& rec) { + return rec.type == type && rec.id_offset == id_offset; + }); + if (iter != content_records.cend()) { + return std::make_optional(iter->nca_id); + } + + if (id_offset != 0) { + return std::nullopt; + } + + const auto fallback_iter = + std::find_if(content_records.cbegin(), content_records.cend(), + [type](const ContentRecord& rec) { return rec.type == type; }); + if (fallback_iter == content_records.cend()) { return std::nullopt; } - return std::make_optional(iter->nca_id); + return std::make_optional(fallback_iter->nca_id); } std::optional<NcaID> RegisteredCache::GetNcaIDFromMetadata(u64 title_id, |
