summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2018-09-28 17:04:16 +0200
committerJosJuice <josjuice@gmail.com>2020-06-17 13:43:51 +0200
commit8da5d0c4fee307b3a195dc5ef55c86dfbb40df34 (patch)
tree3a50d85d5afb614ab91950ea39eed5423ef7e52a /Source
parent0bc7dcd172716f48639419bc4e6ddc415d0f368a (diff)
Add an early version of WIABlobReader
It can currently only read the first 0x80 bytes of a disc image, which is enough for identifying it but not for doing anything else.
Diffstat (limited to 'Source')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java2
-rw-r--r--Source/Core/Core/Boot/Boot.cpp2
-rw-r--r--Source/Core/DiscIO/Blob.cpp3
-rw-r--r--Source/Core/DiscIO/Blob.h3
-rw-r--r--Source/Core/DiscIO/CMakeLists.txt2
-rw-r--r--Source/Core/DiscIO/DiscIO.vcxproj2
-rw-r--r--Source/Core/DiscIO/DiscIO.vcxproj.filters6
-rw-r--r--Source/Core/DiscIO/WIABlob.cpp92
-rw-r--r--Source/Core/DiscIO/WIABlob.h102
-rw-r--r--Source/Core/DolphinQt/GameList/GameTracker.cpp4
-rw-r--r--Source/Core/DolphinQt/Info.plist.in1
-rw-r--r--Source/Core/DolphinQt/MainWindow.cpp4
-rw-r--r--Source/Core/DolphinQt/Settings/PathPane.cpp2
-rw-r--r--Source/Core/UICommon/GameFileCache.cpp2
14 files changed, 218 insertions, 9 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
index 96658720c7..a27b2f2e05 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
@@ -22,7 +22,7 @@ import java.util.List;
public final class FileBrowserHelper
{
public static final HashSet<String> GAME_EXTENSIONS = new HashSet<>(Arrays.asList(
- "gcm", "tgc", "iso", "ciso", "gcz", "wbfs", "wad", "dol", "elf", "dff"));
+ "gcm", "tgc", "iso", "ciso", "gcz", "wbfs", "wia", "wad", "dol", "elf", "dff"));
public static final HashSet<String> RAW_EXTENSION = new HashSet<>(Collections.singletonList(
"raw"));
diff --git a/Source/Core/Core/Boot/Boot.cpp b/Source/Core/Core/Boot/Boot.cpp
index a4f85208e3..f06c1077f9 100644
--- a/Source/Core/Core/Boot/Boot.cpp
+++ b/Source/Core/Core/Boot/Boot.cpp
@@ -159,7 +159,7 @@ BootParameters::GenerateFromFile(std::vector<std::string> paths,
paths.clear();
static const std::unordered_set<std::string> disc_image_extensions = {
- {".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz", ".dol", ".elf"}};
+ {".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz", ".wia", ".dol", ".elf"}};
if (disc_image_extensions.find(extension) != disc_image_extensions.end() || is_drive)
{
std::unique_ptr<DiscIO::VolumeDisc> disc = DiscIO::CreateDisc(path);
diff --git a/Source/Core/DiscIO/Blob.cpp b/Source/Core/DiscIO/Blob.cpp
index 20fe23e9ca..97e48eb047 100644
--- a/Source/Core/DiscIO/Blob.cpp
+++ b/Source/Core/DiscIO/Blob.cpp
@@ -20,6 +20,7 @@
#include "DiscIO/DriveBlob.h"
#include "DiscIO/FileBlob.h"
#include "DiscIO/TGCBlob.h"
+#include "DiscIO/WIABlob.h"
#include "DiscIO/WbfsBlob.h"
namespace DiscIO
@@ -205,6 +206,8 @@ std::unique_ptr<BlobReader> CreateBlobReader(const std::string& filename)
return TGCFileReader::Create(std::move(file));
case WBFS_MAGIC:
return WbfsFileReader::Create(std::move(file), filename);
+ case WIA_MAGIC:
+ return WIAFileReader::Create(std::move(file), filename);
default:
if (auto directory_blob = DirectoryBlobReader::Create(filename))
return std::move(directory_blob);
diff --git a/Source/Core/DiscIO/Blob.h b/Source/Core/DiscIO/Blob.h
index e8846753d1..5371478d65 100644
--- a/Source/Core/DiscIO/Blob.h
+++ b/Source/Core/DiscIO/Blob.h
@@ -34,7 +34,8 @@ enum class BlobType
GCZ,
CISO,
WBFS,
- TGC
+ TGC,
+ WIA
};
class BlobReader
diff --git a/Source/Core/DiscIO/CMakeLists.txt b/Source/Core/DiscIO/CMakeLists.txt
index 6437bf35d1..1e234bea4d 100644
--- a/Source/Core/DiscIO/CMakeLists.txt
+++ b/Source/Core/DiscIO/CMakeLists.txt
@@ -42,6 +42,8 @@ add_library(discio
VolumeWii.h
WbfsBlob.cpp
WbfsBlob.h
+ WIABlob.cpp
+ WIABlob.h
WiiEncryptionCache.cpp
WiiEncryptionCache.h
WiiSaveBanner.cpp
diff --git a/Source/Core/DiscIO/DiscIO.vcxproj b/Source/Core/DiscIO/DiscIO.vcxproj
index ee1d2ecd36..9c2c9f7954 100644
--- a/Source/Core/DiscIO/DiscIO.vcxproj
+++ b/Source/Core/DiscIO/DiscIO.vcxproj
@@ -65,6 +65,7 @@
<ClCompile Include="VolumeWad.cpp" />
<ClCompile Include="VolumeWii.cpp" />
<ClCompile Include="WbfsBlob.cpp" />
+ <ClCompile Include="WIABlob.cpp" />
<ClCompile Include="WiiEncryptionCache.cpp" />
<ClCompile Include="WiiSaveBanner.cpp" />
</ItemGroup>
@@ -91,6 +92,7 @@
<ClInclude Include="VolumeWad.h" />
<ClInclude Include="VolumeWii.h" />
<ClInclude Include="WbfsBlob.h" />
+ <ClInclude Include="WIABlob.h" />
<ClInclude Include="WiiEncryptionCache.h" />
<ClInclude Include="WiiSaveBanner.h" />
</ItemGroup>
diff --git a/Source/Core/DiscIO/DiscIO.vcxproj.filters b/Source/Core/DiscIO/DiscIO.vcxproj.filters
index 43cf82fa03..b7990b19d6 100644
--- a/Source/Core/DiscIO/DiscIO.vcxproj.filters
+++ b/Source/Core/DiscIO/DiscIO.vcxproj.filters
@@ -90,6 +90,9 @@
<ClCompile Include="ScrubbedBlob.cpp">
<Filter>Volume\Blob</Filter>
</ClCompile>
+ <ClCompile Include="WIABlob.cpp">
+ <Filter>Volume\Blob</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="DiscScrubber.h">
@@ -164,6 +167,9 @@
<ClInclude Include="MultithreadedCompressor.h">
<Filter>Volume\Blob</Filter>
</ClInclude>
+ <ClInclude Include="WIABlob.h">
+ <Filter>Volume\Blob</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="CMakeLists.txt" />
diff --git a/Source/Core/DiscIO/WIABlob.cpp b/Source/Core/DiscIO/WIABlob.cpp
new file mode 100644
index 0000000000..85f7f8ce38
--- /dev/null
+++ b/Source/Core/DiscIO/WIABlob.cpp
@@ -0,0 +1,92 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include "DiscIO/WIABlob.h"
+
+#include <memory>
+
+#include "Common/CommonTypes.h"
+#include "Common/File.h"
+#include "Common/Logging/Log.h"
+#include "Common/StringUtil.h"
+#include "Common/Swap.h"
+
+#include "DiscIO/VolumeWii.h"
+
+namespace DiscIO
+{
+WIAFileReader::WIAFileReader(File::IOFile file, const std::string& path) : m_file(std::move(file))
+{
+ m_valid = Initialize(path);
+}
+
+WIAFileReader::~WIAFileReader() = default;
+
+bool WIAFileReader::Initialize(const std::string& path)
+{
+ if (!m_file.Seek(0, SEEK_SET) || !m_file.ReadArray(&m_header_1, 1))
+ return false;
+
+ if (m_header_1.magic != WIA_MAGIC)
+ return false;
+
+ const u32 version = Common::swap32(m_header_1.version);
+ const u32 version_compatible = Common::swap32(m_header_1.version_compatible);
+ if (WIA_VERSION < version_compatible || WIA_VERSION_READ_COMPATIBLE > version)
+ {
+ ERROR_LOG(DISCIO, "Unsupported WIA version %s in %s", VersionToString(version).c_str(),
+ path.c_str());
+ return false;
+ }
+
+ if (Common::swap64(m_header_1.wia_file_size) != m_file.GetSize())
+ {
+ ERROR_LOG(DISCIO, "File size is incorrect for %s", path.c_str());
+ return false;
+ }
+
+ if (Common::swap32(m_header_1.header_2_size) < sizeof(WIAHeader2))
+ return false;
+
+ if (!m_file.ReadArray(&m_header_2, 1))
+ return false;
+
+ const u32 chunk_size = Common::swap32(m_header_2.chunk_size);
+ if (chunk_size % VolumeWii::GROUP_TOTAL_SIZE != 0)
+ return false;
+
+ return true;
+}
+
+std::unique_ptr<WIAFileReader> WIAFileReader::Create(File::IOFile file, const std::string& path)
+{
+ std::unique_ptr<WIAFileReader> blob(new WIAFileReader(std::move(file), path));
+ return blob->m_valid ? std::move(blob) : nullptr;
+}
+
+bool WIAFileReader::Read(u64 offset, u64 size, u8* out_ptr)
+{
+ if (offset + size <= sizeof(WIAHeader2::disc_header))
+ {
+ std::memcpy(out_ptr, m_header_2.disc_header.data() + offset, size);
+ return true;
+ }
+
+ // Not implemented
+ return false;
+}
+
+std::string WIAFileReader::VersionToString(u32 version)
+{
+ const u8 a = version >> 24;
+ const u8 b = (version >> 16) & 0xff;
+ const u8 c = (version >> 8) & 0xff;
+ const u8 d = version & 0xff;
+
+ if (d == 0 || d == 0xff)
+ return StringFromFormat("%u.%02x.%02x", a, b, c);
+ else
+ return StringFromFormat("%u.%02x.%02x.beta%u", a, b, c, d);
+}
+} // namespace DiscIO
diff --git a/Source/Core/DiscIO/WIABlob.h b/Source/Core/DiscIO/WIABlob.h
new file mode 100644
index 0000000000..edd7d0b776
--- /dev/null
+++ b/Source/Core/DiscIO/WIABlob.h
@@ -0,0 +1,102 @@
+// Copyright 2018 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <array>
+#include <memory>
+
+#include "Common/CommonTypes.h"
+#include "Common/File.h"
+#include "Common/Swap.h"
+#include "DiscIO/Blob.h"
+
+namespace DiscIO
+{
+constexpr u32 WIA_MAGIC = 0x01414957; // "WIA\x1" (byteswapped to little endian)
+
+class WIAFileReader : public BlobReader
+{
+public:
+ ~WIAFileReader();
+
+ static std::unique_ptr<WIAFileReader> Create(File::IOFile file, const std::string& path);
+
+ BlobType GetBlobType() const override { return BlobType::WIA; }
+
+ u64 GetRawSize() const override { return Common::swap64(m_header_1.wia_file_size); }
+ u64 GetDataSize() const override { return Common::swap64(m_header_1.iso_file_size); }
+ bool IsDataSizeAccurate() const override { return true; }
+
+ u64 GetBlockSize() const override { return Common::swap32(m_header_2.chunk_size); }
+ bool HasFastRandomAccessInBlock() const override { return false; }
+
+ bool Read(u64 offset, u64 size, u8* out_ptr) override;
+
+private:
+ explicit WIAFileReader(File::IOFile file, const std::string& path);
+ bool Initialize(const std::string& path);
+
+ static std::string VersionToString(u32 version);
+
+ using SHA1 = std::array<u8, 20>;
+
+#pragma pack(push, 1)
+ struct WIAHeader1
+ {
+ u32 magic;
+ u32 version;
+ u32 version_compatible;
+ u32 header_2_size;
+ SHA1 header_2_hash;
+ u64 iso_file_size;
+ u64 wia_file_size;
+ SHA1 header_1_hash;
+ };
+#pragma pack(pop)
+ static_assert(sizeof(WIAHeader1) == 0x48, "Wrong size for WIA header 1");
+
+#pragma pack(push, 1)
+ struct WIAHeader2
+ {
+ u32 disc_type;
+ u32 compression_type;
+ u32 compression_level; // Informative only
+ u32 chunk_size;
+
+ std::array<u8, 0x80> disc_header;
+
+ u32 number_of_partitions_entries;
+ u32 partition_entry_size;
+ u64 partition_entries_offset;
+ SHA1 partition_entries_hash;
+
+ u32 number_of_raw_data_entries;
+ u64 raw_data_entries_offset;
+ u32 raw_data_entries_size;
+
+ u32 number_of_group_entries;
+ u64 group_entries_offset;
+ u32 group_entries_size;
+ };
+#pragma pack(pop)
+ static_assert(sizeof(WIAHeader2) == 0xd4, "Wrong size for WIA header 2");
+
+ bool m_valid;
+
+ File::IOFile m_file;
+
+ WIAHeader1 m_header_1;
+ WIAHeader2 m_header_2;
+
+ static constexpr u32 WIA_VERSION = 0x01000000;
+ static constexpr u32 WIA_VERSION_WRITE_COMPATIBLE = 0x01000000;
+ static constexpr u32 WIA_VERSION_READ_COMPATIBLE = 0x00080000;
+
+ // Perhaps we could set WIA_VERSION_WRITE_COMPATIBLE to 0.9, but WIA version 0.9 was never in
+ // any official release of wit, and interim versions (either source or binaries) are hard to find.
+ // Since we've been unable to check if we're write compatible with 0.9, we set it 1.0 to be safe.
+};
+
+} // namespace DiscIO
diff --git a/Source/Core/DolphinQt/GameList/GameTracker.cpp b/Source/Core/DolphinQt/GameList/GameTracker.cpp
index 4caf643dd5..4aa930140c 100644
--- a/Source/Core/DolphinQt/GameList/GameTracker.cpp
+++ b/Source/Core/DolphinQt/GameList/GameTracker.cpp
@@ -24,8 +24,8 @@ static const QStringList game_filters{
QStringLiteral("*.[gG][cC][mM]"), QStringLiteral("*.[iI][sS][oO]"),
QStringLiteral("*.[tT][gG][cC]"), QStringLiteral("*.[cC][iI][sS][oO]"),
QStringLiteral("*.[gG][cC][zZ]"), QStringLiteral("*.[wW][bB][fF][sS]"),
- QStringLiteral("*.[wW][aA][dD]"), QStringLiteral("*.[eE][lL][fF]"),
- QStringLiteral("*.[dD][oO][lL]")};
+ QStringLiteral("*.[wW][iI][aA]"), QStringLiteral("*.[wW][aA][dD]"),
+ QStringLiteral("*.[eE][lL][fF]"), QStringLiteral("*.[dD][oO][lL]")};
GameTracker::GameTracker(QObject* parent) : QFileSystemWatcher(parent)
{
diff --git a/Source/Core/DolphinQt/Info.plist.in b/Source/Core/DolphinQt/Info.plist.in
index 7fd60fa8e0..979f5f7348 100644
--- a/Source/Core/DolphinQt/Info.plist.in
+++ b/Source/Core/DolphinQt/Info.plist.in
@@ -16,6 +16,7 @@
<string>m3u</string>
<string>tgc</string>
<string>wad</string>
+ <string>wia</string>
<string>wbfs</string>
</array>
<key>CFBundleTypeIconFile</key>
diff --git a/Source/Core/DolphinQt/MainWindow.cpp b/Source/Core/DolphinQt/MainWindow.cpp
index 8b8eb37f40..508b822427 100644
--- a/Source/Core/DolphinQt/MainWindow.cpp
+++ b/Source/Core/DolphinQt/MainWindow.cpp
@@ -686,8 +686,8 @@ QStringList MainWindow::PromptFileNames()
QStringList paths = QFileDialog::getOpenFileNames(
this, tr("Select a File"),
settings.value(QStringLiteral("mainwindow/lastdir"), QString{}).toString(),
- tr("All GC/Wii files (*.elf *.dol *.gcm *.iso *.tgc *.wbfs *.ciso *.gcz *.wad *.dff *.m3u);;"
- "All Files (*)"));
+ tr("All GC/Wii files (*.elf *.dol *.gcm *.iso *.tgc *.wbfs *.ciso *.gcz *.wia *.wad *.dff "
+ "*.m3u);;All Files (*)"));
if (!paths.isEmpty())
{
diff --git a/Source/Core/DolphinQt/Settings/PathPane.cpp b/Source/Core/DolphinQt/Settings/PathPane.cpp
index ab59f185cc..e77f4d09c3 100644
--- a/Source/Core/DolphinQt/Settings/PathPane.cpp
+++ b/Source/Core/DolphinQt/Settings/PathPane.cpp
@@ -44,7 +44,7 @@ void PathPane::BrowseDefaultGame()
{
QString file = QDir::toNativeSeparators(QFileDialog::getOpenFileName(
this, tr("Select a Game"), Settings::Instance().GetDefaultGame(),
- tr("All GC/Wii files (*.elf *.dol *.gcm *.iso *.tgc *.wbfs *.ciso *.gcz *.wad *.m3u);;"
+ tr("All GC/Wii files (*.elf *.dol *.gcm *.iso *.tgc *.wbfs *.ciso *.gcz *.wia *.wad *.m3u);;"
"All Files (*)")));
if (!file.isEmpty())
diff --git a/Source/Core/UICommon/GameFileCache.cpp b/Source/Core/UICommon/GameFileCache.cpp
index 9b2729407e..bb12eb3ccd 100644
--- a/Source/Core/UICommon/GameFileCache.cpp
+++ b/Source/Core/UICommon/GameFileCache.cpp
@@ -33,7 +33,7 @@ std::vector<std::string> FindAllGamePaths(const std::vector<std::string>& direct
bool recursive_scan)
{
static const std::vector<std::string> search_extensions = {
- ".gcm", ".tgc", ".iso", ".ciso", ".gcz", ".wbfs", ".wad", ".dol", ".elf"};
+ ".gcm", ".tgc", ".iso", ".ciso", ".gcz", ".wbfs", ".wia", ".wad", ".dol", ".elf"};
// TODO: We could process paths iteratively as they are found
return Common::DoFileSearch(directories_to_scan, search_extensions, recursive_scan);