VolumeDisc.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // Copyright 2020 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include "DiscIO/VolumeDisc.h"
  4. #include <memory>
  5. #include <optional>
  6. #include <string>
  7. #include <vector>
  8. #include "Common/CommonTypes.h"
  9. #include "Common/Crypto/SHA1.h"
  10. #include "DiscIO/DiscUtils.h"
  11. #include "DiscIO/Enums.h"
  12. #include "DiscIO/Filesystem.h"
  13. namespace DiscIO
  14. {
  15. std::string VolumeDisc::GetGameID(const Partition& partition) const
  16. {
  17. char id[6];
  18. if (!Read(0, sizeof(id), reinterpret_cast<u8*>(id), partition))
  19. return std::string();
  20. return DecodeString(id);
  21. }
  22. Country VolumeDisc::GetCountry(const Partition& partition) const
  23. {
  24. // The 0 that we use as a default value is mapped to Country::Unknown and Region::Unknown
  25. const u8 country_byte = ReadSwapped<u8>(3, partition).value_or(0);
  26. const Region region = GetRegion();
  27. const std::optional<u16> revision = GetRevision();
  28. if (CountryCodeToRegion(country_byte, GetVolumeType(), region, revision) != region)
  29. return TypicalCountryForRegion(region);
  30. return CountryCodeToCountry(country_byte, GetVolumeType(), region, revision);
  31. }
  32. Region VolumeDisc::RegionCodeToRegion(std::optional<u32> region_code) const
  33. {
  34. if (!region_code)
  35. return Region::Unknown;
  36. const Region region = static_cast<Region>(*region_code);
  37. return region <= Region::NTSC_K ? region : Region::Unknown;
  38. }
  39. std::string VolumeDisc::GetMakerID(const Partition& partition) const
  40. {
  41. char maker_id[2];
  42. if (!Read(0x4, sizeof(maker_id), reinterpret_cast<u8*>(&maker_id), partition))
  43. return std::string();
  44. return DecodeString(maker_id);
  45. }
  46. std::optional<u16> VolumeDisc::GetRevision(const Partition& partition) const
  47. {
  48. std::optional<u8> revision = ReadSwapped<u8>(7, partition);
  49. return revision ? *revision : std::optional<u16>();
  50. }
  51. std::string VolumeDisc::GetInternalName(const Partition& partition) const
  52. {
  53. char name[0x60];
  54. if (!Read(0x20, sizeof(name), reinterpret_cast<u8*>(&name), partition))
  55. return std::string();
  56. return DecodeString(name);
  57. }
  58. std::string VolumeDisc::GetApploaderDate(const Partition& partition) const
  59. {
  60. char date[16];
  61. if (!Read(0x2440, sizeof(date), reinterpret_cast<u8*>(&date), partition))
  62. return std::string();
  63. return DecodeString(date);
  64. }
  65. std::optional<u8> VolumeDisc::GetDiscNumber(const Partition& partition) const
  66. {
  67. return ReadSwapped<u8>(6, partition);
  68. }
  69. bool VolumeDisc::IsNKit() const
  70. {
  71. constexpr u32 NKIT_MAGIC = 0x4E4B4954; // "NKIT"
  72. return ReadSwapped<u32>(0x200, PARTITION_NONE) == NKIT_MAGIC;
  73. }
  74. void VolumeDisc::AddGamePartitionToSyncHash(Common::SHA1::Context* context) const
  75. {
  76. const Partition partition = GetGamePartition();
  77. // All headers at the beginning of the partition, plus the apploader
  78. ReadAndAddToSyncHash(context, 0, 0x2440 + GetApploaderSize(*this, partition).value_or(0),
  79. partition);
  80. // Boot DOL (may be missing if this is a Datel disc)
  81. const std::optional<u64> dol_offset = GetBootDOLOffset(*this, partition);
  82. if (dol_offset)
  83. {
  84. ReadAndAddToSyncHash(context, *dol_offset,
  85. GetBootDOLSize(*this, partition, *dol_offset).value_or(0), partition);
  86. }
  87. // File system
  88. const std::optional<u64> fst_offset = GetFSTOffset(*this, partition);
  89. if (fst_offset)
  90. ReadAndAddToSyncHash(context, *fst_offset, GetFSTSize(*this, partition).value_or(0), partition);
  91. // opening.bnr (name and banner)
  92. const FileSystem* file_system = GetFileSystem(partition);
  93. if (file_system)
  94. {
  95. std::unique_ptr<FileInfo> file_info = file_system->FindFileInfo("opening.bnr");
  96. if (file_info && !file_info->IsDirectory())
  97. ReadAndAddToSyncHash(context, file_info->GetOffset(), file_info->GetSize(), partition);
  98. }
  99. }
  100. } // namespace DiscIO