VolumeWad.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // Copyright 2009 Dolphin Emulator Project
  2. // Licensed under GPLv2+
  3. // Refer to the license.txt file included.
  4. #include <cstddef>
  5. #include <map>
  6. #include <string>
  7. #include <vector>
  8. #include "Common/CommonTypes.h"
  9. #include "Common/MathUtil.h"
  10. #include "Common/StringUtil.h"
  11. #include "DiscIO/Blob.h"
  12. #include "DiscIO/Volume.h"
  13. #include "DiscIO/VolumeWad.h"
  14. #define ALIGN_40(x) ROUND_UP(Common::swap32(x), 0x40)
  15. namespace DiscIO
  16. {
  17. CVolumeWAD::CVolumeWAD(IBlobReader* _pReader)
  18. : m_pReader(_pReader), m_offset(0), m_tmd_offset(0), m_opening_bnr_offset(0),
  19. m_hdr_size(0), m_cert_size(0), m_tick_size(0), m_tmd_size(0), m_data_size(0)
  20. {
  21. // Source: http://wiibrew.org/wiki/WAD_files
  22. Read(0x00, 4, (u8*)&m_hdr_size);
  23. Read(0x08, 4, (u8*)&m_cert_size);
  24. Read(0x10, 4, (u8*)&m_tick_size);
  25. Read(0x14, 4, (u8*)&m_tmd_size);
  26. Read(0x18, 4, (u8*)&m_data_size);
  27. m_offset = ALIGN_40(m_hdr_size) + ALIGN_40(m_cert_size);
  28. m_tmd_offset = ALIGN_40(m_hdr_size) + ALIGN_40(m_cert_size) + ALIGN_40(m_tick_size);
  29. m_opening_bnr_offset = m_tmd_offset + ALIGN_40(m_tmd_size) + ALIGN_40(m_data_size);
  30. }
  31. CVolumeWAD::~CVolumeWAD()
  32. {
  33. }
  34. bool CVolumeWAD::Read(u64 _Offset, u64 _Length, u8* _pBuffer, bool decrypt) const
  35. {
  36. if (decrypt)
  37. PanicAlertT("Tried to decrypt data from a non-Wii volume");
  38. if (m_pReader == nullptr)
  39. return false;
  40. return m_pReader->Read(_Offset, _Length, _pBuffer);
  41. }
  42. IVolume::ECountry CVolumeWAD::GetCountry() const
  43. {
  44. if (!m_pReader)
  45. return COUNTRY_UNKNOWN;
  46. // read the last digit of the titleID in the ticket
  47. u8 country_code;
  48. Read(m_tmd_offset + 0x0193, 1, &country_code);
  49. if (country_code == 2) // SYSMENU
  50. {
  51. u16 title_version = 0;
  52. Read(m_tmd_offset + 0x01dc, 2, (u8*)&title_version);
  53. country_code = GetSysMenuRegion(Common::swap16(title_version));
  54. }
  55. return CountrySwitch(country_code);
  56. }
  57. std::string CVolumeWAD::GetUniqueID() const
  58. {
  59. std::string temp = GetMakerID();
  60. char GameCode[8];
  61. if (!Read(m_offset + 0x01E0, 4, (u8*)GameCode))
  62. return "0";
  63. GameCode[4] = temp.at(0);
  64. GameCode[5] = temp.at(1);
  65. GameCode[6] = 0;
  66. return GameCode;
  67. }
  68. std::string CVolumeWAD::GetMakerID() const
  69. {
  70. char temp[3] = {1};
  71. // Some weird channels use 0x0000 in place of the MakerID, so we need a check there
  72. if (!Read(0x198 + m_tmd_offset, 2, (u8*)temp) || temp[0] == 0 || temp[1] == 0)
  73. return "00";
  74. temp[2] = 0;
  75. return temp;
  76. }
  77. bool CVolumeWAD::GetTitleID(u8* _pBuffer) const
  78. {
  79. if (!Read(m_offset + 0x01DC, 8, _pBuffer))
  80. return false;
  81. return true;
  82. }
  83. u16 CVolumeWAD::GetRevision() const
  84. {
  85. u16 revision;
  86. if (!m_pReader->Read(m_tmd_offset + 0x1dc, 2, (u8*)&revision))
  87. return 0;
  88. return Common::swap16(revision);
  89. }
  90. IVolume::EPlatform CVolumeWAD::GetVolumeType() const
  91. {
  92. return WII_WAD;
  93. }
  94. std::map<IVolume::ELanguage, std::string> CVolumeWAD::GetNames(bool prefer_long) const
  95. {
  96. std::vector<u8> name_data(NAMES_TOTAL_BYTES);
  97. if (!Read(m_opening_bnr_offset + 0x9C, NAMES_TOTAL_BYTES, name_data.data()))
  98. return std::map<IVolume::ELanguage, std::string>();
  99. return ReadWiiNames(name_data);
  100. }
  101. u64 CVolumeWAD::GetSize() const
  102. {
  103. if (m_pReader)
  104. return m_pReader->GetDataSize();
  105. else
  106. return 0;
  107. }
  108. u64 CVolumeWAD::GetRawSize() const
  109. {
  110. if (m_pReader)
  111. return m_pReader->GetRawSize();
  112. else
  113. return 0;
  114. }
  115. } // namespace