From 162e3be82bcfde1f5fc2cd304b70765c342dac2f Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 7 Jun 2020 14:11:00 +0200 Subject: [PATCH] Show an OSD message when running a disc image with a large block size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is intended to catch WIA files which have been created using wit's default parameters (40 MiB block size), once the WIA PR is merged. The check does however also work for GCZ files – not that I think anyone has a GCZ file with a block size that large. --- Source/Core/Core/HW/DVD/DVDInterface.cpp | 12 ++++++++++++ Source/Core/DiscIO/Blob.h | 3 ++- Source/Core/DiscIO/CISOBlob.h | 1 + Source/Core/DiscIO/CompressedBlob.h | 6 ++++++ Source/Core/DiscIO/DirectoryBlob.h | 4 ++++ Source/Core/DiscIO/DriveBlob.h | 1 + Source/Core/DiscIO/FileBlob.h | 5 +++++ Source/Core/DiscIO/ScrubbedBlob.h | 6 ++++++ Source/Core/DiscIO/TGCBlob.h | 5 +++++ Source/Core/DiscIO/Volume.h | 2 ++ Source/Core/DiscIO/VolumeFileBlobReader.cpp | 10 ++++++++++ Source/Core/DiscIO/VolumeFileBlobReader.h | 5 +++++ Source/Core/DiscIO/VolumeGC.cpp | 5 +++++ Source/Core/DiscIO/VolumeGC.h | 1 + Source/Core/DiscIO/VolumeWad.cpp | 5 +++++ Source/Core/DiscIO/VolumeWad.h | 1 + Source/Core/DiscIO/VolumeWii.cpp | 5 +++++ Source/Core/DiscIO/VolumeWii.h | 1 + Source/Core/DiscIO/WbfsBlob.h | 1 + 19 files changed, 78 insertions(+), 1 deletion(-) 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;