From 3f9eec9ae4d7d4285811ec5cea016f3edb418143 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 8 Jun 2017 18:43:52 +0200 Subject: [PATCH] DirectoryBlob: Use DiscContent for ReadNonPartition too ReadPartition and ReadNonPartition are now unified into ReadInternal, with a parameter controlling whether the read is in a partition or not. --- Source/Core/DiscIO/DirectoryBlob.cpp | 75 +++++++--------------------- Source/Core/DiscIO/DirectoryBlob.h | 8 +-- 2 files changed, 20 insertions(+), 63 deletions(-) diff --git a/Source/Core/DiscIO/DirectoryBlob.cpp b/Source/Core/DiscIO/DirectoryBlob.cpp index 39b0595987..fa573d8d34 100644 --- a/Source/Core/DiscIO/DirectoryBlob.cpp +++ b/Source/Core/DiscIO/DirectoryBlob.cpp @@ -172,22 +172,32 @@ DirectoryBlobReader::DirectoryBlobReader(File::IOFile dol_file, const std::strin m_virtual_disc.emplace(APPLOADER_ADDRESS, m_apploader.size(), m_apploader.data()); m_virtual_disc.emplace(m_dol_address, m_dol.size(), m_dol.data()); m_virtual_disc.emplace(m_fst_address, m_fst_data.size(), m_fst_data.data()); + + if (m_is_wii) + { + m_nonpartition_contents.emplace(DISKHEADER_ADDRESS, DISKHEADERINFO_ADDRESS, + m_disk_header.data()); + m_nonpartition_contents.emplace(PARTITION_TABLE_ADDRESS, PARTITION_TABLE.size() * sizeof(u32), + reinterpret_cast(PARTITION_TABLE.data())); + // TODO: TMDs, tickets, more headers, the raw partition contents... + } } -bool DirectoryBlobReader::ReadPartition(u64 offset, u64 length, u8* buffer) +bool DirectoryBlobReader::ReadInternal(u64 offset, u64 length, u8* buffer, + const std::set& contents) { - if (m_virtual_disc.empty()) + if (contents.empty()) return true; // Determine which DiscContent the offset refers to - std::set::const_iterator it = m_virtual_disc.lower_bound(DiscContent(offset)); - if (it->GetOffset() > offset && it != m_virtual_disc.begin()) + std::set::const_iterator it = contents.lower_bound(DiscContent(offset)); + if (it->GetOffset() > offset && it != contents.begin()) --it; // zero fill to start of file data PadToAddress(it->GetOffset(), &offset, &length, &buffer); - while (it != m_virtual_disc.end() && length > 0) + while (it != contents.end() && length > 0) { _dbg_assert_(DVDINTERFACE, it->GetOffset() <= offset); if (!it->Read(&offset, &length, &buffer)) @@ -195,7 +205,7 @@ bool DirectoryBlobReader::ReadPartition(u64 offset, u64 length, u8* buffer) ++it; - if (it != m_virtual_disc.end()) + if (it != contents.end()) { _dbg_assert_(DVDINTERFACE, it->GetOffset() >= offset); PadToAddress(it->GetOffset(), &offset, &length, &buffer); @@ -205,35 +215,9 @@ bool DirectoryBlobReader::ReadPartition(u64 offset, u64 length, u8* buffer) return true; } -bool DirectoryBlobReader::ReadNonPartition(u64 offset, u64 length, u8* buffer) -{ - // header - if (offset < DISKHEADERINFO_ADDRESS) - { - WriteToBuffer(DISKHEADER_ADDRESS, DISKHEADERINFO_ADDRESS, m_disk_header.data(), &offset, - &length, &buffer); - } - if (offset >= 0x40000) - { - WriteToBuffer(PARTITION_TABLE_ADDRESS, PARTITION_TABLE.size() * sizeof(u32), - reinterpret_cast(PARTITION_TABLE.data()), &offset, &length, &buffer); - } - - // TODO: TMDs, tickets, more headers, the partition contents... - - if (length > 0) - { - ERROR_LOG(DISCIO, "Unsupported raw read in DirectoryBlob at 0x%" PRIx64, offset); - return false; - } - - return true; -} - bool DirectoryBlobReader::Read(u64 offset, u64 length, u8* buffer) { - return m_is_wii ? ReadNonPartition(offset, length, buffer) : - ReadPartition(offset, length, buffer); + return ReadInternal(offset, length, buffer, m_is_wii ? m_nonpartition_contents : m_virtual_disc); } bool DirectoryBlobReader::SupportsReadWiiDecrypted() const @@ -246,7 +230,7 @@ bool DirectoryBlobReader::ReadWiiDecrypted(u64 offset, u64 size, u8* buffer, u64 if (!m_is_wii || partition_offset != GAME_PARTITION_ADDRESS) return false; - return ReadPartition(offset, size, buffer); + return ReadInternal(offset, size, buffer, m_virtual_disc); } void DirectoryBlobReader::SetGameID(const std::string& id) @@ -386,29 +370,6 @@ void DirectoryBlobReader::BuildFST() Write32((u32)(m_fst_data.size() >> m_address_shift), 0x042c, &m_disk_header); } -void DirectoryBlobReader::WriteToBuffer(u64 source_start_address, u64 source_length, - const u8* source, u64* address, u64* length, - u8** buffer) const -{ - if (*length == 0) - return; - - _dbg_assert_(DVDINTERFACE, *address >= source_start_address); - - u64 source_offset = *address - source_start_address; - - if (source_offset < source_length) - { - size_t bytes_to_read = std::min(source_length - source_offset, *length); - - memcpy(*buffer, source + source_offset, bytes_to_read); - - *length -= bytes_to_read; - *buffer += bytes_to_read; - *address += bytes_to_read; - } -} - void DirectoryBlobReader::PadToAddress(u64 start_address, u64* address, u64* length, u8** buffer) const { diff --git a/Source/Core/DiscIO/DirectoryBlob.h b/Source/Core/DiscIO/DirectoryBlob.h index f3879c97f6..0d0a196be9 100644 --- a/Source/Core/DiscIO/DirectoryBlob.h +++ b/Source/Core/DiscIO/DirectoryBlob.h @@ -75,8 +75,7 @@ public: private: DirectoryBlobReader(File::IOFile dol_file, const std::string& root_directory); - bool ReadPartition(u64 offset, u64 length, u8* buffer); - bool ReadNonPartition(u64 offset, u64 length, u8* buffer); + bool ReadInternal(u64 offset, u64 length, u8* buffer, const std::set& contents); void SetDiskTypeWii(); void SetDiskTypeGC(); @@ -89,10 +88,6 @@ private: void BuildFST(); - // writing to read buffer - void WriteToBuffer(u64 source_start_address, u64 source_length, const u8* source, u64* address, - u64* length, u8** buffer) const; - void PadToAddress(u64 start_address, u64* address, u64* length, u8** buffer) const; void Write32(u32 data, u32 offset, std::vector* const buffer); @@ -107,6 +102,7 @@ private: std::string m_root_directory; std::set m_virtual_disc; + std::set m_nonpartition_contents; bool m_is_wii = false;