diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index 01dbd3cfd3..b61d273388 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -36,6 +36,8 @@ VolumeGC::VolumeGC(std::unique_ptr reader) : m_pReader(std::move(rea auto file_system = std::make_unique(this, PARTITION_NONE); return file_system->IsValid() ? std::move(file_system) : nullptr; }; + + m_converted_banner = [this] { return LoadBannerFile(); }; } VolumeGC::~VolumeGC() @@ -125,40 +127,34 @@ std::string VolumeGC::GetInternalName(const Partition& partition) const std::map VolumeGC::GetShortNames() const { - LoadBannerFile(); - return m_short_names; + return m_converted_banner->short_names; } std::map VolumeGC::GetLongNames() const { - LoadBannerFile(); - return m_long_names; + return m_converted_banner->long_names; } std::map VolumeGC::GetShortMakers() const { - LoadBannerFile(); - return m_short_makers; + return m_converted_banner->short_makers; } std::map VolumeGC::GetLongMakers() const { - LoadBannerFile(); - return m_long_makers; + return m_converted_banner->long_makers; } std::map VolumeGC::GetDescriptions() const { - LoadBannerFile(); - return m_descriptions; + return m_converted_banner->descriptions; } std::vector VolumeGC::GetBanner(int* width, int* height) const { - LoadBannerFile(); - *width = m_image_width; - *height = m_image_height; - return m_image_buffer; + *width = m_converted_banner->image_width; + *height = m_converted_banner->image_height; + return m_converted_banner->image_buffer; } std::string VolumeGC::GetApploaderDate(const Partition& partition) const @@ -195,21 +191,15 @@ Platform VolumeGC::GetVolumeType() const return Platform::GAMECUBE_DISC; } -void VolumeGC::LoadBannerFile() const +VolumeGC::ConvertedGCBanner VolumeGC::LoadBannerFile() const { - // If opening.bnr has been loaded already, return immediately - if (m_banner_loaded) - return; - - m_banner_loaded = true; - GCBanner banner_file; const u64 file_size = ReadFile(*this, PARTITION_NONE, "opening.bnr", reinterpret_cast(&banner_file), sizeof(GCBanner)); if (file_size < 4) { WARN_LOG(DISCIO, "Could not read opening.bnr."); - return; // Return early so that we don't access the uninitialized banner_file.id + return {}; // Return early so that we don't access the uninitialized banner_file.id } constexpr u32 BNR1_MAGIC = 0x31524e42; @@ -226,14 +216,17 @@ void VolumeGC::LoadBannerFile() const else { WARN_LOG(DISCIO, "Invalid opening.bnr. Type: %0x Size: %0zx", banner_file.id, file_size); - return; + return {}; } - ExtractBannerInformation(banner_file, is_bnr1); + return ExtractBannerInformation(banner_file, is_bnr1); } -void VolumeGC::ExtractBannerInformation(const GCBanner& banner_file, bool is_bnr1) const +VolumeGC::ConvertedGCBanner VolumeGC::ExtractBannerInformation(const GCBanner& banner_file, + bool is_bnr1) const { + ConvertedGCBanner banner; + u32 number_of_languages = 0; Language start_language = Language::LANGUAGE_UNKNOWN; @@ -249,11 +242,11 @@ void VolumeGC::ExtractBannerInformation(const GCBanner& banner_file, bool is_bnr start_language = Language::LANGUAGE_ENGLISH; } - m_image_width = GC_BANNER_WIDTH; - m_image_height = GC_BANNER_HEIGHT; - m_image_buffer = std::vector(m_image_width * m_image_height); - ColorUtil::decode5A3image(m_image_buffer.data(), banner_file.image, m_image_width, - m_image_height); + banner.image_width = GC_BANNER_WIDTH; + banner.image_height = GC_BANNER_HEIGHT; + banner.image_buffer = std::vector(GC_BANNER_WIDTH * GC_BANNER_HEIGHT); + ColorUtil::decode5A3image(banner.image_buffer.data(), banner_file.image, GC_BANNER_WIDTH, + GC_BANNER_HEIGHT); for (u32 i = 0; i < number_of_languages; ++i) { @@ -262,24 +255,26 @@ void VolumeGC::ExtractBannerInformation(const GCBanner& banner_file, bool is_bnr std::string description = DecodeString(info.description); if (!description.empty()) - m_descriptions[language] = description; + banner.descriptions.emplace(language, description); std::string short_name = DecodeString(info.short_name); if (!short_name.empty()) - m_short_names[language] = short_name; + banner.short_names.emplace(language, short_name); std::string long_name = DecodeString(info.long_name); if (!long_name.empty()) - m_long_names[language] = long_name; + banner.long_names.emplace(language, long_name); std::string short_maker = DecodeString(info.short_maker); if (!short_maker.empty()) - m_short_makers[language] = short_maker; + banner.short_makers.emplace(language, short_maker); std::string long_maker = DecodeString(info.long_maker); if (!long_maker.empty()) - m_long_makers[language] = long_maker; + banner.long_makers.emplace(language, long_maker); } + + return banner; } } // namespace diff --git a/Source/Core/DiscIO/VolumeGC.h b/Source/Core/DiscIO/VolumeGC.h index 846c01731c..3ba9fdb6fc 100644 --- a/Source/Core/DiscIO/VolumeGC.h +++ b/Source/Core/DiscIO/VolumeGC.h @@ -79,23 +79,26 @@ private: // (only one for BNR1 type) }; - void LoadBannerFile() const; - void ExtractBannerInformation(const GCBanner& banner_file, bool is_bnr1) const; + struct ConvertedGCBanner + { + std::map short_names; + std::map long_names; + std::map short_makers; + std::map long_makers; + std::map descriptions; + + std::vector image_buffer; + int image_height = 0; + int image_width = 0; + }; + + ConvertedGCBanner LoadBannerFile() const; + ConvertedGCBanner ExtractBannerInformation(const GCBanner& banner_file, bool is_bnr1) const; static const size_t BNR1_SIZE = sizeof(GCBanner) - sizeof(GCBannerInformation) * 5; static const size_t BNR2_SIZE = sizeof(GCBanner); - mutable std::map m_short_names; - - mutable std::map m_long_names; - mutable std::map m_short_makers; - mutable std::map m_long_makers; - mutable std::map m_descriptions; - - mutable bool m_banner_loaded = false; - mutable std::vector m_image_buffer; - mutable int m_image_height = 0; - mutable int m_image_width = 0; + Common::Lazy m_converted_banner; Common::Lazy> m_file_system; diff --git a/Source/Core/DolphinQt2/Config/FilesystemWidget.cpp b/Source/Core/DolphinQt2/Config/FilesystemWidget.cpp index efb67a2fa7..0b9fc9e0e6 100644 --- a/Source/Core/DolphinQt2/Config/FilesystemWidget.cpp +++ b/Source/Core/DolphinQt2/Config/FilesystemWidget.cpp @@ -85,8 +85,7 @@ void FilesystemWidget::PopulateView() for (size_t i = 0; i < partitions.size(); i++) { - std::unique_ptr file_system( - DiscIO::CreateFileSystem(m_volume.get(), partitions[i])); + const DiscIO::FileSystem* file_system = m_volume->GetFileSystem(partitions[i]); auto* item = new QStandardItem(tr("Partition %1").arg(i)); item->setEditable(false); @@ -104,10 +103,7 @@ void FilesystemWidget::PopulateView() } if (partitions.empty()) - { - PopulateDirectory(-1, disc, - DiscIO::CreateFileSystem(m_volume.get(), DiscIO::PARTITION_NONE)->GetRoot()); - } + PopulateDirectory(-1, disc, m_volume->GetFileSystem(DiscIO::PARTITION_NONE)->GetRoot()); } void FilesystemWidget::PopulateDirectory(int partition_id, QStandardItem* root, @@ -237,9 +233,7 @@ void FilesystemWidget::ExtractSystemData(const DiscIO::Partition& partition, con void FilesystemWidget::ExtractDirectory(const DiscIO::Partition& partition, const QString path, const QString& out) { - std::unique_ptr filesystem( - DiscIO::CreateFileSystem(m_volume.get(), partition)); - + const DiscIO::FileSystem* filesystem = m_volume->GetFileSystem(partition); std::unique_ptr info = filesystem->FindFileInfo(path.toStdString()); u32 size = info->GetTotalChildren(); @@ -251,7 +245,7 @@ void FilesystemWidget::ExtractDirectory(const DiscIO::Partition& partition, cons bool all = path.isEmpty(); DiscIO::ExportDirectory( - *m_volume, filesystem->GetPartition(), *info, true, path.toStdString(), out.toStdString(), + *m_volume, partition, *info, true, path.toStdString(), out.toStdString(), [all, dialog](const std::string& current) { dialog->setLabelText( (all ? QObject::tr("Extracting All Files...") : QObject::tr("Extracting Directory...")) @@ -268,8 +262,7 @@ void FilesystemWidget::ExtractDirectory(const DiscIO::Partition& partition, cons void FilesystemWidget::ExtractFile(const DiscIO::Partition& partition, const QString& path, const QString& out) { - std::unique_ptr filesystem( - DiscIO::CreateFileSystem(m_volume.get(), partition)); + const DiscIO::FileSystem* filesystem = m_volume->GetFileSystem(partition); bool success = DiscIO::ExportFile( *m_volume, partition, filesystem->FindFileInfo(path.toStdString()).get(), out.toStdString());