diff --git a/Source/Core/Core/HW/DVD/DVDInterface.cpp b/Source/Core/Core/HW/DVD/DVDInterface.cpp index ff4d623fa4..679cbd48dc 100644 --- a/Source/Core/Core/HW/DVD/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVD/DVDInterface.cpp @@ -36,6 +36,7 @@ #include "Core/IOS/IOS.h" #include "Core/Movie.h" +#include "DiscIO/Blob.h" #include "DiscIO/Enums.h" #include "DiscIO/Volume.h" #include "DiscIO/VolumeWii.h" @@ -426,6 +427,17 @@ void SetDisc(std::unique_ptr disc, bool had_disc = IsDiscInside(); bool has_disc = static_cast(disc); + if (has_disc) + { + const DiscIO::BlobReader& blob = disc->GetBlobReader(); + if (!blob.HasFastRandomAccessInBlock() && blob.GetBlockSize() > 0x200000) + { + OSD::AddMessage("You are running a disc image with a very large block size.", 60000); + OSD::AddMessage("This will likely lead to performance problems.", 60000); + OSD::AddMessage("You can use Dolphin's convert feature to reduce the block size.", 60000); + } + } + if (auto_disc_change_paths) { ASSERT_MSG(DISCIO, (*auto_disc_change_paths).size() != 1, diff --git a/Source/Core/DiscIO/Blob.h b/Source/Core/DiscIO/Blob.h index 1d23d7b6b0..e8846753d1 100644 --- a/Source/Core/DiscIO/Blob.h +++ b/Source/Core/DiscIO/Blob.h @@ -49,7 +49,8 @@ public: virtual bool IsDataSizeAccurate() const = 0; // Returns 0 if the format does not use blocks - virtual u64 GetBlockSize() const { return 0; } + virtual u64 GetBlockSize() const = 0; + virtual bool HasFastRandomAccessInBlock() const = 0; // NOT thread-safe - can't call this from multiple threads. virtual bool Read(u64 offset, u64 size, u8* out_ptr) = 0; diff --git a/Source/Core/DiscIO/CISOBlob.h b/Source/Core/DiscIO/CISOBlob.h index 66f950f074..40d44aaa9d 100644 --- a/Source/Core/DiscIO/CISOBlob.h +++ b/Source/Core/DiscIO/CISOBlob.h @@ -45,6 +45,7 @@ public: bool IsDataSizeAccurate() const override { return false; } u64 GetBlockSize() const override { return m_block_size; } + bool HasFastRandomAccessInBlock() const override { return true; } bool Read(u64 offset, u64 nbytes, u8* out_ptr) override; diff --git a/Source/Core/DiscIO/CompressedBlob.h b/Source/Core/DiscIO/CompressedBlob.h index 8c63aa68d6..602d21d91a 100644 --- a/Source/Core/DiscIO/CompressedBlob.h +++ b/Source/Core/DiscIO/CompressedBlob.h @@ -47,12 +47,18 @@ public: static std::unique_ptr Create(File::IOFile file, const std::string& filename); ~CompressedBlobReader(); + const CompressedBlobHeader& GetHeader() const { return m_header; } + BlobType GetBlobType() const override { return BlobType::GCZ; } + u64 GetRawSize() const override { return m_file_size; } u64 GetDataSize() const override { return m_header.data_size; } bool IsDataSizeAccurate() const override { return true; } + u64 GetBlockSize() const override { return m_header.block_size; } + bool HasFastRandomAccessInBlock() const override { return false; } + u64 GetBlockCompressedSize(u64 block_num) const; bool GetBlock(u64 block_num, u8* out_ptr) override; diff --git a/Source/Core/DiscIO/DirectoryBlob.h b/Source/Core/DiscIO/DirectoryBlob.h index 3a23f19a0c..d526c26ea2 100644 --- a/Source/Core/DiscIO/DirectoryBlob.h +++ b/Source/Core/DiscIO/DirectoryBlob.h @@ -161,10 +161,14 @@ public: bool ReadWiiDecrypted(u64 offset, u64 size, u8* buffer, u64 partition_data_offset) override; BlobType GetBlobType() const override; + u64 GetRawSize() const override; u64 GetDataSize() const override; bool IsDataSizeAccurate() const override { return true; } + u64 GetBlockSize() const override { return 0; } + bool HasFastRandomAccessInBlock() const override { return true; } + private: struct PartitionWithType { diff --git a/Source/Core/DiscIO/DriveBlob.h b/Source/Core/DiscIO/DriveBlob.h index 46c141b1d3..65356feb41 100644 --- a/Source/Core/DiscIO/DriveBlob.h +++ b/Source/Core/DiscIO/DriveBlob.h @@ -31,6 +31,7 @@ public: bool IsDataSizeAccurate() const override { return true; } u64 GetBlockSize() const override { return ECC_BLOCK_SIZE; } + bool HasFastRandomAccessInBlock() const override { return false; } private: DriveReader(const std::string& drive); diff --git a/Source/Core/DiscIO/FileBlob.h b/Source/Core/DiscIO/FileBlob.h index a0703c7a46..bb97cea7e4 100644 --- a/Source/Core/DiscIO/FileBlob.h +++ b/Source/Core/DiscIO/FileBlob.h @@ -20,9 +20,14 @@ public: static std::unique_ptr Create(File::IOFile file); BlobType GetBlobType() const override { return BlobType::PLAIN; } + u64 GetRawSize() const override { return m_size; } u64 GetDataSize() const override { return m_size; } bool IsDataSizeAccurate() const override { return true; } + + u64 GetBlockSize() const override { return 0; } + bool HasFastRandomAccessInBlock() const override { return true; } + bool Read(u64 offset, u64 nbytes, u8* out_ptr) override; private: diff --git a/Source/Core/DiscIO/ScrubbedBlob.h b/Source/Core/DiscIO/ScrubbedBlob.h index b98b78681e..badeb457f8 100644 --- a/Source/Core/DiscIO/ScrubbedBlob.h +++ b/Source/Core/DiscIO/ScrubbedBlob.h @@ -20,10 +20,16 @@ public: static std::unique_ptr Create(const std::string& path); BlobType GetBlobType() const override { return m_blob_reader->GetBlobType(); } + u64 GetRawSize() const override { return m_blob_reader->GetRawSize(); } u64 GetDataSize() const override { return m_blob_reader->GetDataSize(); } bool IsDataSizeAccurate() const override { return m_blob_reader->IsDataSizeAccurate(); } + u64 GetBlockSize() const override { return m_blob_reader->GetBlockSize(); } + bool HasFastRandomAccessInBlock() const override + { + return m_blob_reader->HasFastRandomAccessInBlock(); + } bool Read(u64 offset, u64 size, u8* out_ptr) override; diff --git a/Source/Core/DiscIO/TGCBlob.h b/Source/Core/DiscIO/TGCBlob.h index 47d3492744..b76a282d6e 100644 --- a/Source/Core/DiscIO/TGCBlob.h +++ b/Source/Core/DiscIO/TGCBlob.h @@ -43,9 +43,14 @@ public: static std::unique_ptr Create(File::IOFile file); BlobType GetBlobType() const override { return BlobType::TGC; } + u64 GetRawSize() const override { return m_size; } u64 GetDataSize() const override; bool IsDataSizeAccurate() const override { return true; } + + u64 GetBlockSize() const override { return 0; } + bool HasFastRandomAccessInBlock() const override { return true; } + bool Read(u64 offset, u64 nbytes, u8* out_ptr) override; private: diff --git a/Source/Core/DiscIO/Volume.h b/Source/Core/DiscIO/Volume.h index 925c41e230..ab251d6763 100644 --- a/Source/Core/DiscIO/Volume.h +++ b/Source/Core/DiscIO/Volume.h @@ -20,6 +20,7 @@ namespace DiscIO { +class BlobReader; enum class BlobType; class FileSystem; class VolumeWAD; @@ -132,6 +133,7 @@ public: virtual bool IsSizeAccurate() const = 0; // Size on disc (compressed size) virtual u64 GetRawSize() const = 0; + virtual const BlobReader& GetBlobReader() const = 0; protected: template diff --git a/Source/Core/DiscIO/VolumeFileBlobReader.cpp b/Source/Core/DiscIO/VolumeFileBlobReader.cpp index 336fecad4c..eb80003adc 100644 --- a/Source/Core/DiscIO/VolumeFileBlobReader.cpp +++ b/Source/Core/DiscIO/VolumeFileBlobReader.cpp @@ -44,6 +44,16 @@ u64 VolumeFileBlobReader::GetRawSize() const return GetDataSize(); } +u64 VolumeFileBlobReader::GetBlockSize() const +{ + return m_volume.GetBlobReader().GetBlockSize(); +} + +bool VolumeFileBlobReader::HasFastRandomAccessInBlock() const +{ + return m_volume.GetBlobReader().HasFastRandomAccessInBlock(); +} + bool VolumeFileBlobReader::Read(u64 offset, u64 length, u8* out_ptr) { if (offset + length > m_file_info->GetSize()) diff --git a/Source/Core/DiscIO/VolumeFileBlobReader.h b/Source/Core/DiscIO/VolumeFileBlobReader.h index bbc75d61b6..8e227ece63 100644 --- a/Source/Core/DiscIO/VolumeFileBlobReader.h +++ b/Source/Core/DiscIO/VolumeFileBlobReader.h @@ -23,9 +23,14 @@ public: Create(const Volume& volume, const Partition& partition, std::string_view file_path); BlobType GetBlobType() const override { return BlobType::PLAIN; } + u64 GetRawSize() const override; u64 GetDataSize() const override; bool IsDataSizeAccurate() const override { return true; } + + u64 GetBlockSize() const override; + bool HasFastRandomAccessInBlock() const override; + bool Read(u64 offset, u64 length, u8* out_ptr) override; private: diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index 9ecb8bb266..74b612f647 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -188,6 +188,11 @@ u64 VolumeGC::GetRawSize() const return m_reader->GetRawSize(); } +const BlobReader& VolumeGC::GetBlobReader() const +{ + return *m_reader; +} + std::optional VolumeGC::GetDiscNumber(const Partition& partition) const { return ReadSwapped(6, partition); diff --git a/Source/Core/DiscIO/VolumeGC.h b/Source/Core/DiscIO/VolumeGC.h index ad950919cf..b9da441270 100644 --- a/Source/Core/DiscIO/VolumeGC.h +++ b/Source/Core/DiscIO/VolumeGC.h @@ -54,6 +54,7 @@ public: u64 GetSize() const override; bool IsSizeAccurate() const override; u64 GetRawSize() const override; + const BlobReader& GetBlobReader() const; private: static const u32 GC_BANNER_WIDTH = 96; diff --git a/Source/Core/DiscIO/VolumeWad.cpp b/Source/Core/DiscIO/VolumeWad.cpp index 584ae3b5b7..7681d3932c 100644 --- a/Source/Core/DiscIO/VolumeWad.cpp +++ b/Source/Core/DiscIO/VolumeWad.cpp @@ -327,4 +327,9 @@ u64 VolumeWAD::GetRawSize() const return m_reader->GetRawSize(); } +const BlobReader& VolumeWAD::GetBlobReader() const +{ + return *m_reader; +} + } // namespace DiscIO diff --git a/Source/Core/DiscIO/VolumeWad.h b/Source/Core/DiscIO/VolumeWad.h index 85df789228..5bb885023f 100644 --- a/Source/Core/DiscIO/VolumeWad.h +++ b/Source/Core/DiscIO/VolumeWad.h @@ -66,6 +66,7 @@ public: u64 GetSize() const override; bool IsSizeAccurate() const override; u64 GetRawSize() const override; + const BlobReader& GetBlobReader() const; private: std::unique_ptr m_reader; diff --git a/Source/Core/DiscIO/VolumeWii.cpp b/Source/Core/DiscIO/VolumeWii.cpp index df6cfebee1..3bbe347211 100644 --- a/Source/Core/DiscIO/VolumeWii.cpp +++ b/Source/Core/DiscIO/VolumeWii.cpp @@ -434,6 +434,11 @@ u64 VolumeWii::GetRawSize() const return m_reader->GetRawSize(); } +const BlobReader& VolumeWii::GetBlobReader() const +{ + return *m_reader; +} + bool VolumeWii::CheckH3TableIntegrity(const Partition& partition) const { auto it = m_partitions.find(partition); diff --git a/Source/Core/DiscIO/VolumeWii.h b/Source/Core/DiscIO/VolumeWii.h index f82e919130..4def1a9393 100644 --- a/Source/Core/DiscIO/VolumeWii.h +++ b/Source/Core/DiscIO/VolumeWii.h @@ -95,6 +95,7 @@ public: u64 GetSize() const override; bool IsSizeAccurate() const override; u64 GetRawSize() const override; + const BlobReader& GetBlobReader() const; static bool EncryptGroup(u64 offset, u64 partition_data_offset, u64 partition_data_decrypted_size, const std::array& key, BlobReader* blob, diff --git a/Source/Core/DiscIO/WbfsBlob.h b/Source/Core/DiscIO/WbfsBlob.h index 0283b1c98b..0f985fe3d4 100644 --- a/Source/Core/DiscIO/WbfsBlob.h +++ b/Source/Core/DiscIO/WbfsBlob.h @@ -33,6 +33,7 @@ public: bool IsDataSizeAccurate() const override { return false; } u64 GetBlockSize() const override { return m_wbfs_sector_size; } + bool HasFastRandomAccessInBlock() const override { return true; } bool Read(u64 offset, u64 nbytes, u8* out_ptr) override;