mirror of
https://github.com/izzy2lost/dolphin.git
synced 2026-06-19 01:16:48 -07:00
Merge pull request #5573 from JosJuice/directory-blob
Turn VolumeDirectory into DirectoryBlob
This commit is contained in:
@@ -63,35 +63,34 @@ std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::stri
|
||||
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
|
||||
|
||||
static const std::unordered_set<std::string> disc_image_extensions = {
|
||||
{".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz"}};
|
||||
{".gcm", ".iso", ".tgc", ".wbfs", ".ciso", ".gcz", ".dol", ".elf"}};
|
||||
if (disc_image_extensions.find(extension) != disc_image_extensions.end() || is_drive)
|
||||
{
|
||||
auto volume = DiscIO::CreateVolumeFromFilename(path);
|
||||
if (!volume)
|
||||
std::unique_ptr<DiscIO::Volume> volume = DiscIO::CreateVolumeFromFilename(path);
|
||||
if (volume)
|
||||
return std::make_unique<BootParameters>(Disc{path, std::move(volume)});
|
||||
|
||||
if (extension == ".elf")
|
||||
return std::make_unique<BootParameters>(Executable{path, std::make_unique<ElfReader>(path)});
|
||||
|
||||
if (extension == ".dol")
|
||||
return std::make_unique<BootParameters>(Executable{path, std::make_unique<DolReader>(path)});
|
||||
|
||||
if (is_drive)
|
||||
{
|
||||
if (is_drive)
|
||||
{
|
||||
PanicAlertT("Could not read \"%s\". "
|
||||
"There is no disc in the drive or it is not a GameCube/Wii backup. "
|
||||
"Please note that Dolphin cannot play games directly from the original "
|
||||
"GameCube and Wii discs.",
|
||||
path.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.", path.c_str());
|
||||
}
|
||||
return {};
|
||||
PanicAlertT("Could not read \"%s\". "
|
||||
"There is no disc in the drive or it is not a GameCube/Wii backup. "
|
||||
"Please note that Dolphin cannot play games directly from the original "
|
||||
"GameCube and Wii discs.",
|
||||
path.c_str());
|
||||
}
|
||||
return std::make_unique<BootParameters>(Disc{path, std::move(volume)});
|
||||
else
|
||||
{
|
||||
PanicAlertT("\"%s\" is an invalid GCM/ISO file, or is not a GC/Wii ISO.", path.c_str());
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
if (extension == ".elf")
|
||||
return std::make_unique<BootParameters>(Executable{path, std::make_unique<ElfReader>(path)});
|
||||
|
||||
if (extension == ".dol")
|
||||
return std::make_unique<BootParameters>(Executable{path, std::make_unique<DolReader>(path)});
|
||||
|
||||
if (extension == ".dff")
|
||||
return std::make_unique<BootParameters>(DFF{path});
|
||||
|
||||
@@ -133,44 +132,6 @@ bool CBoot::DVDRead(const DiscIO::Volume& volume, u64 dvd_offset, u32 output_add
|
||||
return true;
|
||||
}
|
||||
|
||||
void CBoot::Load_FST(bool is_wii, const DiscIO::Volume* volume)
|
||||
{
|
||||
if (!volume)
|
||||
return;
|
||||
|
||||
const DiscIO::Partition partition = volume->GetGamePartition();
|
||||
|
||||
// copy first 32 bytes of disc to start of Mem 1
|
||||
DVDRead(*volume, /*offset*/ 0, /*address*/ 0, /*length*/ 0x20, DiscIO::PARTITION_NONE);
|
||||
|
||||
// copy of game id
|
||||
Memory::Write_U32(Memory::Read_U32(0x0000), 0x3180);
|
||||
|
||||
u32 shift = 0;
|
||||
if (is_wii)
|
||||
shift = 2;
|
||||
|
||||
const std::optional<u32> fst_offset = volume->ReadSwapped<u32>(0x0424, partition);
|
||||
const std::optional<u32> fst_size = volume->ReadSwapped<u32>(0x0428, partition);
|
||||
const std::optional<u32> max_fst_size = volume->ReadSwapped<u32>(0x042c, partition);
|
||||
if (!fst_offset || !fst_size || !max_fst_size)
|
||||
return;
|
||||
|
||||
u32 arena_high = Common::AlignDown(0x817FFFFF - (*max_fst_size << shift), 0x20);
|
||||
Memory::Write_U32(arena_high, 0x00000034);
|
||||
|
||||
// load FST
|
||||
DVDRead(*volume, *fst_offset << shift, arena_high, *fst_size << shift, partition);
|
||||
Memory::Write_U32(arena_high, 0x00000038);
|
||||
Memory::Write_U32(*max_fst_size << shift, 0x0000003c);
|
||||
|
||||
if (is_wii)
|
||||
{
|
||||
// the apploader changes IOS MEM1_ARENA_END too
|
||||
Memory::Write_U32(arena_high, 0x00003110);
|
||||
}
|
||||
}
|
||||
|
||||
void CBoot::UpdateDebugger_MapLoaded()
|
||||
{
|
||||
Host_NotifyMapLoaded();
|
||||
@@ -309,15 +270,11 @@ bool CBoot::Load_BS2(const std::string& boot_rom_filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
static const DiscIO::Volume* SetDefaultDisc()
|
||||
static void SetDefaultDisc()
|
||||
{
|
||||
const SConfig& config = SConfig::GetInstance();
|
||||
// load default image or create virtual drive from directory
|
||||
if (!config.m_strDVDRoot.empty())
|
||||
return SetDisc(DiscIO::CreateVolumeFromDirectory(config.m_strDVDRoot, config.bWii));
|
||||
if (!config.m_strDefaultISO.empty())
|
||||
return SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
|
||||
return nullptr;
|
||||
SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
|
||||
}
|
||||
|
||||
// Third boot step after BootManager and Core. See Call schedule in BootManager.cpp
|
||||
@@ -359,34 +316,14 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
|
||||
if (!executable.reader->IsValid())
|
||||
return false;
|
||||
|
||||
const DiscIO::Volume* volume = nullptr;
|
||||
// VolumeDirectory only works with DOLs.
|
||||
if (StringEndsWith(executable.path, ".dol"))
|
||||
{
|
||||
if (!config.m_strDVDRoot.empty())
|
||||
{
|
||||
NOTICE_LOG(BOOT, "Setting DVDRoot %s", config.m_strDVDRoot.c_str());
|
||||
volume = SetDisc(DiscIO::CreateVolumeFromDirectory(
|
||||
config.m_strDVDRoot, config.bWii, config.m_strApploader, executable.path));
|
||||
}
|
||||
else if (!config.m_strDefaultISO.empty())
|
||||
{
|
||||
NOTICE_LOG(BOOT, "Loading default ISO %s", config.m_strDefaultISO.c_str());
|
||||
volume = SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
volume = SetDefaultDisc();
|
||||
}
|
||||
|
||||
if (!executable.reader->LoadIntoMemory())
|
||||
{
|
||||
PanicAlertT("Failed to load the executable to memory.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Poor man's bootup
|
||||
SetDefaultDisc();
|
||||
|
||||
if (config.bWii)
|
||||
{
|
||||
HID4.SBE = 1;
|
||||
@@ -394,14 +331,13 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
|
||||
SetupBAT(config.bWii);
|
||||
// Because there is no TMD to get the requested system (IOS) version from,
|
||||
// we default to IOS58, which is the version used by the Homebrew Channel.
|
||||
SetupWiiMemory(volume, 0x000000010000003a);
|
||||
SetupWiiMemory(nullptr, 0x000000010000003a);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmulatedBS2_GC(volume, true);
|
||||
EmulatedBS2_GC(nullptr, true);
|
||||
}
|
||||
|
||||
Load_FST(config.bWii, volume);
|
||||
PC = executable.reader->GetEntryPoint();
|
||||
|
||||
if (executable.reader->LoadSymbols() || LoadMapFromFilename())
|
||||
@@ -465,8 +401,13 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
|
||||
}
|
||||
|
||||
BootExecutableReader::BootExecutableReader(const std::string& file_name)
|
||||
: BootExecutableReader(File::IOFile{file_name, "rb"})
|
||||
{
|
||||
File::IOFile file{file_name, "rb"};
|
||||
}
|
||||
|
||||
BootExecutableReader::BootExecutableReader(File::IOFile file)
|
||||
{
|
||||
file.Seek(0, SEEK_SET);
|
||||
m_bytes.resize(file.GetSize());
|
||||
file.ReadBytes(m_bytes.data(), m_bytes.size());
|
||||
}
|
||||
|
||||
@@ -15,6 +15,11 @@
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
|
||||
namespace File
|
||||
{
|
||||
class IOFile;
|
||||
}
|
||||
|
||||
struct RegionSetting
|
||||
{
|
||||
const std::string area;
|
||||
@@ -101,7 +106,6 @@ private:
|
||||
static bool EmulatedBS2_Wii(const DiscIO::Volume* volume);
|
||||
static bool EmulatedBS2(bool is_wii, const DiscIO::Volume* volume);
|
||||
static bool Load_BS2(const std::string& boot_rom_filename);
|
||||
static void Load_FST(bool is_wii, const DiscIO::Volume* volume);
|
||||
|
||||
static bool SetupWiiMemory(const DiscIO::Volume* volume, u64 ios_title_id);
|
||||
};
|
||||
@@ -110,6 +114,7 @@ class BootExecutableReader
|
||||
{
|
||||
public:
|
||||
explicit BootExecutableReader(const std::string& file_name);
|
||||
explicit BootExecutableReader(File::IOFile file);
|
||||
explicit BootExecutableReader(const std::vector<u8>& buffer);
|
||||
virtual ~BootExecutableReader();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/File.h"
|
||||
@@ -18,6 +19,11 @@ DolReader::DolReader(const std::vector<u8>& buffer) : BootExecutableReader(buffe
|
||||
m_is_valid = Initialize(buffer);
|
||||
}
|
||||
|
||||
DolReader::DolReader(File::IOFile file) : BootExecutableReader(std::move(file))
|
||||
{
|
||||
m_is_valid = Initialize(m_bytes);
|
||||
}
|
||||
|
||||
DolReader::DolReader(const std::string& filename) : BootExecutableReader(filename)
|
||||
{
|
||||
m_is_valid = Initialize(m_bytes);
|
||||
|
||||
@@ -10,10 +10,16 @@
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/Boot/Boot.h"
|
||||
|
||||
namespace File
|
||||
{
|
||||
class IOFile;
|
||||
}
|
||||
|
||||
class DolReader final : public BootExecutableReader
|
||||
{
|
||||
public:
|
||||
explicit DolReader(const std::string& filename);
|
||||
explicit DolReader(File::IOFile file);
|
||||
explicit DolReader(const std::vector<u8>& buffer);
|
||||
~DolReader();
|
||||
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
#include "Core/Boot/ElfReader.h"
|
||||
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Common/MsgHandler.h"
|
||||
#include "Common/Swap.h"
|
||||
@@ -71,6 +73,11 @@ ElfReader::ElfReader(const std::vector<u8>& buffer) : BootExecutableReader(buffe
|
||||
Initialize(m_bytes.data());
|
||||
}
|
||||
|
||||
ElfReader::ElfReader(File::IOFile file) : BootExecutableReader(std::move(file))
|
||||
{
|
||||
Initialize(m_bytes.data());
|
||||
}
|
||||
|
||||
ElfReader::ElfReader(const std::string& filename) : BootExecutableReader(filename)
|
||||
{
|
||||
Initialize(m_bytes.data());
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
#include "Core/Boot/Boot.h"
|
||||
#include "Core/Boot/ElfTypes.h"
|
||||
|
||||
namespace File
|
||||
{
|
||||
class IOFile;
|
||||
}
|
||||
|
||||
enum KnownElfTypes
|
||||
{
|
||||
KNOWNELF_PSP = 0,
|
||||
@@ -22,6 +27,7 @@ class ElfReader final : public BootExecutableReader
|
||||
{
|
||||
public:
|
||||
explicit ElfReader(const std::string& filename);
|
||||
explicit ElfReader(File::IOFile file);
|
||||
explicit ElfReader(const std::vector<u8>& buffer);
|
||||
~ElfReader();
|
||||
u32 Read32(int off) const { return base32[off >> 2]; }
|
||||
|
||||
@@ -252,8 +252,6 @@ void SConfig::SaveCoreSettings(IniFile& ini)
|
||||
core->Set("FPRF", bFPRF);
|
||||
core->Set("AccurateNaNs", bAccurateNaNs);
|
||||
core->Set("DefaultISO", m_strDefaultISO);
|
||||
core->Set("DVDRoot", m_strDVDRoot);
|
||||
core->Set("Apploader", m_strApploader);
|
||||
core->Set("EnableCheats", bEnableCheats);
|
||||
core->Set("SelectedLanguage", SelectedLanguage);
|
||||
core->Set("OverrideGCLang", bOverrideGCLanguage);
|
||||
@@ -568,8 +566,6 @@ void SConfig::LoadCoreSettings(IniFile& ini)
|
||||
core->Get("CPUThread", &bCPUThread, true);
|
||||
core->Get("SyncOnSkipIdle", &bSyncGPUOnSkipIdleHack, true);
|
||||
core->Get("DefaultISO", &m_strDefaultISO);
|
||||
core->Get("DVDRoot", &m_strDVDRoot);
|
||||
core->Get("Apploader", &m_strApploader);
|
||||
core->Get("EnableCheats", &bEnableCheats, false);
|
||||
core->Get("SelectedLanguage", &SelectedLanguage, 0);
|
||||
core->Get("OverrideGCLang", &bOverrideGCLanguage, false);
|
||||
|
||||
@@ -197,8 +197,6 @@ struct SConfig : NonCopyable
|
||||
std::string m_strBootROM;
|
||||
std::string m_strSRAM;
|
||||
std::string m_strDefaultISO;
|
||||
std::string m_strDVDRoot;
|
||||
std::string m_strApploader;
|
||||
std::string m_strWiiSDCardPath;
|
||||
|
||||
std::string m_perfDir;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "DiscIO/Blob.h"
|
||||
#include "DiscIO/CISOBlob.h"
|
||||
#include "DiscIO/CompressedBlob.h"
|
||||
#include "DiscIO/DirectoryBlob.h"
|
||||
#include "DiscIO/DriveBlob.h"
|
||||
#include "DiscIO/FileBlob.h"
|
||||
#include "DiscIO/TGCBlob.h"
|
||||
@@ -183,12 +184,13 @@ std::unique_ptr<BlobReader> CreateBlobReader(const std::string& filename)
|
||||
if (!file.ReadArray(&magic, 1))
|
||||
return nullptr;
|
||||
|
||||
// Conveniently, every supported file format (except for plain disc images) starts
|
||||
// with a 4-byte magic number that identifies the format, so we just need a simple
|
||||
// switch statement to create the right blob type. If the magic number doesn't
|
||||
// match any known magic number, we assume it's a plain disc image. If that
|
||||
// assumption is wrong, the volume code that runs later will notice the error
|
||||
// because the blob won't provide valid data when reading the GC/Wii disc header.
|
||||
// Conveniently, every supported file format (except for plain disc images and
|
||||
// extracted discs) starts with a 4-byte magic number that identifies the format,
|
||||
// so we just need a simple switch statement to create the right blob type. If the
|
||||
// magic number doesn't match any known magic number and the directory structure
|
||||
// doesn't match the directory blob format, we assume it's a plain disc image. If
|
||||
// that assumption is wrong, the volume code that runs later will notice the error
|
||||
// because the blob won't provide the right data when reading the GC/Wii disc header.
|
||||
|
||||
switch (magic)
|
||||
{
|
||||
@@ -201,6 +203,9 @@ std::unique_ptr<BlobReader> CreateBlobReader(const std::string& filename)
|
||||
case WBFS_MAGIC:
|
||||
return WbfsFileReader::Create(std::move(file), filename);
|
||||
default:
|
||||
if (auto directory_blob = DirectoryBlobReader::Create(filename))
|
||||
return std::move(directory_blob);
|
||||
|
||||
return PlainFileReader::Create(std::move(file));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,12 @@ public:
|
||||
return Common::FromBigEndian(temp);
|
||||
}
|
||||
|
||||
virtual bool SupportsReadWiiDecrypted() const { return false; }
|
||||
virtual bool ReadWiiDecrypted(u64 offset, u64 size, u8* out_ptr, u64 partition_offset)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
BlobReader() {}
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ set(SRCS
|
||||
CISOBlob.cpp
|
||||
WbfsBlob.cpp
|
||||
CompressedBlob.cpp
|
||||
DirectoryBlob.cpp
|
||||
DiscExtractor.cpp
|
||||
DiscScrubber.cpp
|
||||
DriveBlob.cpp
|
||||
@@ -14,7 +15,6 @@ set(SRCS
|
||||
NANDImporter.cpp
|
||||
TGCBlob.cpp
|
||||
Volume.cpp
|
||||
VolumeDirectory.cpp
|
||||
VolumeGC.cpp
|
||||
VolumeWad.cpp
|
||||
VolumeWii.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,169 @@
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "DiscIO/Blob.h"
|
||||
|
||||
namespace File
|
||||
{
|
||||
struct FSTEntry;
|
||||
class IOFile;
|
||||
}
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
enum class PartitionType : u32;
|
||||
|
||||
// Returns true if the path is inside a DirectoryBlob and doesn't represent the DirectoryBlob itself
|
||||
bool ShouldHideFromGameList(const std::string& volume_path);
|
||||
|
||||
class DiscContent
|
||||
{
|
||||
public:
|
||||
using ContentSource = std::variant<std::string, const u8*>;
|
||||
|
||||
DiscContent(u64 offset, u64 size, const std::string& path);
|
||||
DiscContent(u64 offset, u64 size, const u8* data);
|
||||
|
||||
// Provided because it's convenient when searching for DiscContent in an std::set
|
||||
explicit DiscContent(u64 offset);
|
||||
|
||||
u64 GetOffset() const;
|
||||
u64 GetSize() const;
|
||||
bool Read(u64* offset, u64* length, u8** buffer) const;
|
||||
|
||||
bool operator==(const DiscContent& other) const { return m_offset == other.m_offset; }
|
||||
bool operator!=(const DiscContent& other) const { return !(*this == other); }
|
||||
bool operator<(const DiscContent& other) const { return m_offset < other.m_offset; }
|
||||
bool operator>(const DiscContent& other) const { return other < *this; }
|
||||
bool operator<=(const DiscContent& other) const { return !(*this < other); }
|
||||
bool operator>=(const DiscContent& other) const { return !(*this > other); }
|
||||
private:
|
||||
u64 m_offset;
|
||||
u64 m_size = 0;
|
||||
std::string m_path;
|
||||
ContentSource m_content_source;
|
||||
};
|
||||
|
||||
class DirectoryBlobPartition
|
||||
{
|
||||
public:
|
||||
DirectoryBlobPartition() = default;
|
||||
DirectoryBlobPartition(const std::string& root_directory, std::optional<bool> is_wii);
|
||||
|
||||
// We do not allow copying, because it might mess up the pointers inside DiscContents
|
||||
DirectoryBlobPartition(const DirectoryBlobPartition&) = delete;
|
||||
DirectoryBlobPartition& operator=(const DirectoryBlobPartition&) = delete;
|
||||
DirectoryBlobPartition(DirectoryBlobPartition&&) = default;
|
||||
DirectoryBlobPartition& operator=(DirectoryBlobPartition&&) = default;
|
||||
|
||||
bool IsWii() const { return m_is_wii; }
|
||||
u64 GetDataSize() const { return m_data_size; }
|
||||
const std::string& GetRootDirectory() const { return m_root_directory; }
|
||||
const std::vector<u8>& GetHeader() const { return m_disc_header; }
|
||||
const std::set<DiscContent>& GetContents() const { return m_contents; }
|
||||
private:
|
||||
void SetDiscHeaderAndDiscType(std::optional<bool> is_wii);
|
||||
void SetBI2();
|
||||
|
||||
// Returns DOL address
|
||||
u64 SetApploader();
|
||||
// Returns FST address
|
||||
u64 SetDOL(u64 dol_address);
|
||||
|
||||
void BuildFST(u64 fst_address);
|
||||
|
||||
// FST creation
|
||||
void WriteEntryData(u32* entry_offset, u8 type, u32 name_offset, u64 data_offset, u64 length,
|
||||
u32 address_shift);
|
||||
void WriteEntryName(u32* name_offset, const std::string& name, u64 name_table_offset);
|
||||
void WriteDirectory(const File::FSTEntry& parent_entry, u32* fst_offset, u32* name_offset,
|
||||
u64* data_offset, u32 parent_entry_index, u64 name_table_offset);
|
||||
|
||||
std::set<DiscContent> m_contents;
|
||||
std::vector<u8> m_disc_header;
|
||||
std::vector<u8> m_bi2;
|
||||
std::vector<u8> m_apploader;
|
||||
std::vector<u8> m_fst_data;
|
||||
|
||||
std::string m_root_directory;
|
||||
bool m_is_wii = false;
|
||||
// GameCube has no shift, Wii has 2 bit shift
|
||||
u32 m_address_shift = 0;
|
||||
|
||||
u64 m_data_size;
|
||||
};
|
||||
|
||||
class DirectoryBlobReader : public BlobReader
|
||||
{
|
||||
public:
|
||||
static std::unique_ptr<DirectoryBlobReader> Create(const std::string& dol_path);
|
||||
|
||||
// We do not allow copying, because it might mess up the pointers inside DiscContents
|
||||
DirectoryBlobReader(const DirectoryBlobReader&) = delete;
|
||||
DirectoryBlobReader& operator=(const DirectoryBlobReader&) = delete;
|
||||
DirectoryBlobReader(DirectoryBlobReader&&) = default;
|
||||
DirectoryBlobReader& operator=(DirectoryBlobReader&&) = default;
|
||||
|
||||
bool Read(u64 offset, u64 length, u8* buffer) override;
|
||||
bool SupportsReadWiiDecrypted() const override;
|
||||
bool ReadWiiDecrypted(u64 offset, u64 size, u8* buffer, u64 partition_offset) override;
|
||||
|
||||
BlobType GetBlobType() const override;
|
||||
u64 GetRawSize() const override;
|
||||
u64 GetDataSize() const override;
|
||||
|
||||
private:
|
||||
struct PartitionWithType
|
||||
{
|
||||
PartitionWithType(DirectoryBlobPartition&& partition_, PartitionType type_)
|
||||
: partition(std::move(partition_)), type(type_)
|
||||
{
|
||||
}
|
||||
|
||||
DirectoryBlobPartition partition;
|
||||
PartitionType type;
|
||||
};
|
||||
|
||||
explicit DirectoryBlobReader(const std::string& game_partition_root,
|
||||
const std::string& true_root);
|
||||
|
||||
bool ReadInternal(u64 offset, u64 length, u8* buffer, const std::set<DiscContent>& contents);
|
||||
|
||||
void SetNonpartitionDiscHeader(const std::vector<u8>& partition_header,
|
||||
const std::string& game_partition_root);
|
||||
void SetWiiRegionData(const std::string& game_partition_root);
|
||||
void SetPartitions(std::vector<PartitionWithType>&& partitions);
|
||||
void SetPartitionHeader(const DirectoryBlobPartition& partition, u64 partition_address);
|
||||
|
||||
// For GameCube:
|
||||
DirectoryBlobPartition m_gamecube_pseudopartition;
|
||||
|
||||
// For Wii:
|
||||
std::set<DiscContent> m_nonpartition_contents;
|
||||
std::map<u64, DirectoryBlobPartition> m_partitions;
|
||||
|
||||
bool m_is_wii;
|
||||
|
||||
std::vector<u8> m_disc_header_nonpartition;
|
||||
std::vector<u8> m_partition_table;
|
||||
std::vector<u8> m_wii_region_data;
|
||||
std::vector<std::vector<u8>> m_partition_headers;
|
||||
|
||||
u64 m_data_size;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -39,6 +39,7 @@
|
||||
<ClCompile Include="Blob.cpp" />
|
||||
<ClCompile Include="CISOBlob.cpp" />
|
||||
<ClCompile Include="CompressedBlob.cpp" />
|
||||
<ClCompile Include="DirectoryBlob.cpp" />
|
||||
<ClCompile Include="DiscExtractor.cpp" />
|
||||
<ClCompile Include="DiscScrubber.cpp" />
|
||||
<ClCompile Include="DriveBlob.cpp" />
|
||||
@@ -50,7 +51,6 @@
|
||||
<ClCompile Include="NANDImporter.cpp" />
|
||||
<ClCompile Include="TGCBlob.cpp" />
|
||||
<ClCompile Include="Volume.cpp" />
|
||||
<ClCompile Include="VolumeDirectory.cpp" />
|
||||
<ClCompile Include="VolumeGC.cpp" />
|
||||
<ClCompile Include="VolumeWad.cpp" />
|
||||
<ClCompile Include="VolumeWii.cpp" />
|
||||
@@ -61,6 +61,7 @@
|
||||
<ClInclude Include="Blob.h" />
|
||||
<ClInclude Include="CISOBlob.h" />
|
||||
<ClInclude Include="CompressedBlob.h" />
|
||||
<ClInclude Include="DirectoryBlob.h" />
|
||||
<ClInclude Include="DiscExtractor.h" />
|
||||
<ClInclude Include="DiscScrubber.h" />
|
||||
<ClInclude Include="DriveBlob.h" />
|
||||
@@ -72,7 +73,6 @@
|
||||
<ClInclude Include="NANDImporter.h" />
|
||||
<ClInclude Include="TGCBlob.h" />
|
||||
<ClInclude Include="Volume.h" />
|
||||
<ClInclude Include="VolumeDirectory.h" />
|
||||
<ClInclude Include="VolumeGC.h" />
|
||||
<ClInclude Include="VolumeWad.h" />
|
||||
<ClInclude Include="VolumeWii.h" />
|
||||
|
||||
@@ -57,8 +57,8 @@
|
||||
<ClCompile Include="WbfsBlob.cpp">
|
||||
<Filter>Volume\Blob</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VolumeDirectory.cpp">
|
||||
<Filter>Volume</Filter>
|
||||
<ClCompile Include="DirectoryBlob.cpp">
|
||||
<Filter>Volume\Blob</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VolumeGC.cpp">
|
||||
<Filter>Volume</Filter>
|
||||
@@ -122,8 +122,8 @@
|
||||
<ClInclude Include="Volume.h">
|
||||
<Filter>Volume</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VolumeDirectory.h">
|
||||
<Filter>Volume</Filter>
|
||||
<ClInclude Include="DirectoryBlob.h">
|
||||
<Filter>Volume\Blob</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="VolumeGC.h">
|
||||
<Filter>Volume</Filter>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include "DiscIO/Blob.h"
|
||||
#include "DiscIO/Enums.h"
|
||||
#include "DiscIO/VolumeDirectory.h"
|
||||
#include "DiscIO/VolumeGC.h"
|
||||
#include "DiscIO/VolumeWad.h"
|
||||
#include "DiscIO/VolumeWii.h"
|
||||
@@ -112,14 +111,4 @@ std::unique_ptr<Volume> CreateVolumeFromFilename(const std::string& filename)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<Volume> CreateVolumeFromDirectory(const std::string& directory, bool is_wii,
|
||||
const std::string& apploader,
|
||||
const std::string& dol)
|
||||
{
|
||||
if (VolumeDirectory::IsValidDirectory(directory))
|
||||
return std::make_unique<VolumeDirectory>(directory, is_wii, apploader, dol);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -120,8 +120,5 @@ protected:
|
||||
};
|
||||
|
||||
std::unique_ptr<Volume> CreateVolumeFromFilename(const std::string& filename);
|
||||
std::unique_ptr<Volume> CreateVolumeFromDirectory(const std::string& directory, bool is_wii,
|
||||
const std::string& apploader = "",
|
||||
const std::string& dol = "");
|
||||
|
||||
} // namespace
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,161 +0,0 @@
|
||||
// Copyright 2008 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "DiscIO/Volume.h"
|
||||
|
||||
namespace File
|
||||
{
|
||||
struct FSTEntry;
|
||||
}
|
||||
|
||||
//
|
||||
// --- this volume type is used for reading files directly from the hard drive ---
|
||||
//
|
||||
|
||||
namespace DiscIO
|
||||
{
|
||||
enum class BlobType;
|
||||
enum class Country;
|
||||
enum class Language;
|
||||
enum class Region;
|
||||
enum class Platform;
|
||||
|
||||
class VolumeDirectory : public Volume
|
||||
{
|
||||
public:
|
||||
VolumeDirectory(const std::string& directory, bool is_wii, const std::string& apploader = "",
|
||||
const std::string& dol = "");
|
||||
|
||||
~VolumeDirectory();
|
||||
|
||||
static bool IsValidDirectory(const std::string& directory);
|
||||
|
||||
bool Read(u64 offset, u64 length, u8* buffer, const Partition& partition) const override;
|
||||
std::vector<Partition> GetPartitions() const override;
|
||||
Partition GetGamePartition() const override;
|
||||
|
||||
std::string GetGameID(const Partition& partition = PARTITION_NONE) const override;
|
||||
void SetGameID(const std::string& id);
|
||||
|
||||
std::string GetMakerID(const Partition& partition = PARTITION_NONE) const override;
|
||||
|
||||
std::optional<u16> GetRevision(const Partition& partition = PARTITION_NONE) const override
|
||||
{
|
||||
return {};
|
||||
}
|
||||
std::string GetInternalName(const Partition& partition = PARTITION_NONE) const override;
|
||||
std::map<Language, std::string> GetLongNames() const override;
|
||||
std::vector<u32> GetBanner(int* width, int* height) const override;
|
||||
void SetName(const std::string&);
|
||||
|
||||
std::string GetApploaderDate(const Partition& partition = PARTITION_NONE) const override;
|
||||
Platform GetVolumeType() const override;
|
||||
|
||||
Region GetRegion() const override;
|
||||
Country GetCountry(const Partition& partition = PARTITION_NONE) const override;
|
||||
|
||||
BlobType GetBlobType() const override;
|
||||
u64 GetSize() const override;
|
||||
u64 GetRawSize() const override;
|
||||
|
||||
void BuildFST();
|
||||
|
||||
private:
|
||||
static std::string ExtractDirectoryName(const std::string& directory);
|
||||
|
||||
void SetDiskTypeWii();
|
||||
void SetDiskTypeGC();
|
||||
|
||||
bool SetApploader(const std::string& apploader);
|
||||
|
||||
void SetDOL(const std::string& dol);
|
||||
|
||||
// writing to read buffer
|
||||
void WriteToBuffer(u64 source_start_address, u64 source_length, const u8* source, u64* address,
|
||||
u64* length, u8** buffer) const;
|
||||
|
||||
void PadToAddress(u64 start_address, u64* address, u64* length, u8** buffer) const;
|
||||
|
||||
void Write32(u32 data, u32 offset, std::vector<u8>* const buffer);
|
||||
|
||||
// FST creation
|
||||
void WriteEntryData(u32* entry_offset, u8 type, u32 name_offset, u64 data_offset, u64 length,
|
||||
u32 address_shift);
|
||||
void WriteEntryName(u32* name_offset, const std::string& name);
|
||||
void WriteDirectory(const File::FSTEntry& parent_entry, u32* fst_offset, u32* name_offset,
|
||||
u64* data_offset, u32 parent_entry_index);
|
||||
|
||||
std::string m_root_directory;
|
||||
|
||||
std::map<u64, std::string> m_virtual_disk;
|
||||
|
||||
bool m_is_wii;
|
||||
|
||||
// GameCube has no shift, Wii has 2 bit shift
|
||||
u32 m_address_shift;
|
||||
|
||||
// first address on disk containing file data
|
||||
u64 m_data_start_address;
|
||||
|
||||
u64 m_fst_name_offset;
|
||||
std::vector<u8> m_fst_data;
|
||||
|
||||
std::vector<u8> m_disk_header;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct SDiskHeaderInfo
|
||||
{
|
||||
u32 debug_monitor_size;
|
||||
u32 simulated_mem_size;
|
||||
u32 arg_offset;
|
||||
u32 debug_flag;
|
||||
u32 track_location;
|
||||
u32 track_size;
|
||||
u32 country_code;
|
||||
u32 unknown;
|
||||
u32 unknown2;
|
||||
|
||||
// All the data is byteswapped
|
||||
SDiskHeaderInfo()
|
||||
{
|
||||
debug_monitor_size = 0;
|
||||
simulated_mem_size = 0;
|
||||
arg_offset = 0;
|
||||
debug_flag = 0;
|
||||
track_location = 0;
|
||||
track_size = 0;
|
||||
country_code = 0;
|
||||
unknown = 0;
|
||||
unknown2 = 0;
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
std::unique_ptr<SDiskHeaderInfo> m_disk_header_info;
|
||||
|
||||
std::vector<u8> m_apploader;
|
||||
std::vector<u8> m_dol;
|
||||
|
||||
u64 m_fst_address;
|
||||
u64 m_dol_address;
|
||||
|
||||
static constexpr u8 ENTRY_SIZE = 0x0c;
|
||||
static constexpr u8 FILE_ENTRY = 0;
|
||||
static constexpr u8 DIRECTORY_ENTRY = 1;
|
||||
static constexpr u64 DISKHEADER_ADDRESS = 0;
|
||||
static constexpr u64 DISKHEADERINFO_ADDRESS = 0x440;
|
||||
static constexpr u64 APPLOADER_ADDRESS = 0x2440;
|
||||
static const size_t MAX_NAME_LENGTH = 0x3df;
|
||||
static const size_t MAX_ID_LENGTH = 6;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -128,6 +128,9 @@ bool VolumeWii::Read(u64 _ReadOffset, u64 _Length, u8* _pBuffer, const Partition
|
||||
if (partition == PARTITION_NONE)
|
||||
return m_pReader->Read(_ReadOffset, _Length, _pBuffer);
|
||||
|
||||
if (m_pReader->SupportsReadWiiDecrypted())
|
||||
return m_pReader->ReadWiiDecrypted(_ReadOffset, _Length, _pBuffer, partition.offset);
|
||||
|
||||
// Get the decryption key for the partition
|
||||
auto it = m_partitions.find(partition);
|
||||
if (it == m_partitions.end())
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user