diff options
| author | Rukai <rubickent@gmail.com> | 2016-02-29 19:52:15 +1100 |
|---|---|---|
| committer | Rukai <rubickent@gmail.com> | 2016-06-26 00:03:59 +1000 |
| commit | b5104a79f1d39d2d7d160f2bd984f604a5ae2797 (patch) | |
| tree | ac679b6a20266551a906b18f42729c7edd661a80 /Source/Core/DiscIO/VolumeGC.cpp | |
| parent | afa202738e54652e98e8388a5c6a1541d750e3e6 (diff) | |
GCVolume: supports reading all opening.bnr information
DQT2: Game properties dialog contains info tab giving information about the selected iso.
Diffstat (limited to 'Source/Core/DiscIO/VolumeGC.cpp')
| -rw-r--r-- | Source/Core/DiscIO/VolumeGC.cpp | 179 |
1 files changed, 84 insertions, 95 deletions
diff --git a/Source/Core/DiscIO/VolumeGC.cpp b/Source/Core/DiscIO/VolumeGC.cpp index 2930c6cd33..4c364b941b 100644 --- a/Source/Core/DiscIO/VolumeGC.cpp +++ b/Source/Core/DiscIO/VolumeGC.cpp @@ -100,48 +100,46 @@ std::string CVolumeGC::GetInternalName() const char name[0x60]; if (m_pReader != nullptr && Read(0x20, 0x60, (u8*)name)) return DecodeString(name); - else - return ""; + + return ""; } -std::map<IVolume::ELanguage, std::string> CVolumeGC::GetNames(bool prefer_long) const +std::map<IVolume::ELanguage, std::string> CVolumeGC::GetShortNames() const { - return ReadMultiLanguageStrings(false, prefer_long); + LoadBannerFile(); + return m_short_names; } -std::map<IVolume::ELanguage, std::string> CVolumeGC::GetDescriptions() const +std::map<IVolume::ELanguage, std::string> CVolumeGC::GetLongNames() const { - return ReadMultiLanguageStrings(true); + LoadBannerFile(); + return m_long_names; } -std::string CVolumeGC::GetCompany() const +std::map<IVolume::ELanguage, std::string> CVolumeGC::GetShortMakers() const { - if (!LoadBannerFile()) - return ""; - - std::string company = DecodeString(m_banner_file.comment[0].longMaker); + LoadBannerFile(); + return m_short_makers; +} - if (company.empty()) - company = DecodeString(m_banner_file.comment[0].shortMaker); +std::map<IVolume::ELanguage, std::string> CVolumeGC::GetLongMakers() const +{ + LoadBannerFile(); + return m_long_makers; +} - return company; +std::map<IVolume::ELanguage, std::string> CVolumeGC::GetDescriptions() const +{ + LoadBannerFile(); + return m_descriptions; } std::vector<u32> CVolumeGC::GetBanner(int* width, int* height) const { - if (!LoadBannerFile()) - { - *width = 0; - *height = 0; - return std::vector<u32>(); - } - - std::vector<u32> image_buffer(GC_BANNER_WIDTH * GC_BANNER_HEIGHT); - ColorUtil::decode5A3image(image_buffer.data(), m_banner_file.image, GC_BANNER_WIDTH, - GC_BANNER_HEIGHT); - *width = GC_BANNER_WIDTH; - *height = GC_BANNER_HEIGHT; - return image_buffer; + LoadBannerFile(); + *width = m_image_width; + *height = m_image_height; + return m_image_buffer; } u64 CVolumeGC::GetFSTSize() const @@ -201,102 +199,93 @@ IVolume::EPlatform CVolumeGC::GetVolumeType() const return GAMECUBE_DISC; } -// Returns true if the loaded banner file is valid, -// regardless of whether it was loaded by the current call -bool CVolumeGC::LoadBannerFile() const +void CVolumeGC::LoadBannerFile() const { - // The methods ReadMultiLanguageStrings, GetCompany and GetBanner - // need to access the opening.bnr file. These methods are - // usually called one after another. The file is cached in - // RAM to avoid reading it from the disc several times, but - // if none of these methods are called, the file is never loaded. - // If opening.bnr has been loaded already, return immediately - if (m_banner_file_type != BANNER_NOT_LOADED) - return m_banner_file_type != BANNER_INVALID; + if (m_banner_loaded) + return; + GCBanner banner_file; std::unique_ptr<IFileSystem> file_system(CreateFileSystem(this)); size_t file_size = (size_t)file_system->GetFileSize("opening.bnr"); - if (file_size == BNR1_SIZE || file_size == BNR2_SIZE) + + constexpr int BNR1_MAGIC = 0x31524e42; + constexpr int BNR2_MAGIC = 0x32524e42; + if (file_size != BNR1_SIZE && file_size != BNR2_SIZE) { - file_system->ReadFile("opening.bnr", reinterpret_cast<u8*>(&m_banner_file), file_size); - - if (file_size == BNR1_SIZE && m_banner_file.id == 0x31524e42) // "BNR1" - { - m_banner_file_type = BANNER_BNR1; - } - else if (file_size == BNR2_SIZE && m_banner_file.id == 0x32524e42) // "BNR2" - { - m_banner_file_type = BANNER_BNR2; - } - else - { - m_banner_file_type = BANNER_INVALID; - WARN_LOG(DISCIO, "Invalid opening.bnr. Type: %0x Size: %0zx", m_banner_file.id, file_size); - } + WARN_LOG(DISCIO, "Invalid opening.bnr. Size: %0zx", file_size); + return; + } + + file_system->ReadFile("opening.bnr", reinterpret_cast<u8*>(&banner_file), file_size); + + bool is_bnr1; + if (banner_file.id == BNR1_MAGIC && file_size == BNR1_SIZE) + { + is_bnr1 = true; + } + else if (banner_file.id == BNR2_MAGIC && file_size == BNR2_SIZE) + { + is_bnr1 = false; } else { - m_banner_file_type = BANNER_INVALID; - WARN_LOG(DISCIO, "Invalid opening.bnr. Size: %0zx", file_size); + WARN_LOG(DISCIO, "Invalid opening.bnr. Type: %0x Size: %0zx", banner_file.id, file_size); + return; } - return m_banner_file_type != BANNER_INVALID; + ExtractBannerInformation(banner_file, is_bnr1); + m_banner_loaded = true; } -std::map<IVolume::ELanguage, std::string> -CVolumeGC::ReadMultiLanguageStrings(bool description, bool prefer_long) const +void CVolumeGC::ExtractBannerInformation(const GCBanner& banner_file, bool is_bnr1) const { - std::map<ELanguage, std::string> strings; - - if (!LoadBannerFile()) - return strings; - u32 number_of_languages = 0; ELanguage start_language = LANGUAGE_UNKNOWN; bool is_japanese = GetCountry() == ECountry::COUNTRY_JAPAN; - switch (m_banner_file_type) + if (is_bnr1) // NTSC { - case BANNER_BNR1: // NTSC number_of_languages = 1; start_language = is_japanese ? ELanguage::LANGUAGE_JAPANESE : ELanguage::LANGUAGE_ENGLISH; - break; - - case BANNER_BNR2: // PAL + } + else // PAL + { number_of_languages = 6; start_language = ELanguage::LANGUAGE_ENGLISH; - break; - - // Shouldn't happen - case BANNER_INVALID: - case BANNER_NOT_LOADED: - break; } + m_image_width = GC_BANNER_WIDTH; + m_image_height = GC_BANNER_HEIGHT; + m_image_buffer = std::vector<u32>(m_image_width * m_image_height); + ColorUtil::decode5A3image(m_image_buffer.data(), banner_file.image, m_image_width, + m_image_height); + for (u32 i = 0; i < number_of_languages; ++i) { - const GCBannerComment& comment = m_banner_file.comment[i]; - std::string string; - - if (description) - { - string = DecodeString(comment.comment); - } - else // Title - { - if (prefer_long) - string = DecodeString(comment.longTitle); - - if (string.empty()) - string = DecodeString(comment.shortTitle); - } - - if (!string.empty()) - strings[(ELanguage)(start_language + i)] = string; - } + const GCBannerInformation& info = banner_file.information[i]; + ELanguage language = static_cast<ELanguage>(start_language + i); + + std::string description = DecodeString(info.description); + if (!description.empty()) + m_descriptions[language] = description; - return strings; + std::string short_name = DecodeString(info.short_name); + if (!short_name.empty()) + m_short_names[language] = short_name; + + std::string long_name = DecodeString(info.long_name); + if (!long_name.empty()) + m_long_names[language] = long_name; + + std::string short_maker = DecodeString(info.short_maker); + if (!short_maker.empty()) + m_short_makers[language] = short_maker; + + std::string long_maker = DecodeString(info.long_maker); + if (!long_maker.empty()) + m_long_makers[language] = long_maker; + } } } // namespace |
