Initial modifications to support Dolphin's VolumeDirectory

This commit is contained in:
Phillip Stephens 2017-06-30 03:30:10 -07:00
parent 55ed73b9bb
commit e49568ac83
4 changed files with 89 additions and 18 deletions

View File

@ -57,10 +57,16 @@ struct Header
char m_discVersion;
char m_audioStreaming;
char m_streamBufSz;
char m_unk[14];
char m_unk1[14];
uint32_t m_wiiMagic;
uint32_t m_gcnMagic;
char m_gameTitle[64];
char m_disableHashVerification;
char m_disableDiscEnc;
char m_unk2[0x39e];
uint32_t m_debugMonOff;
uint32_t m_debugLoadAddr;
char m_unk3[0x18];
Header(IDiscIO& dio, bool& err)
{
@ -73,6 +79,8 @@ struct Header
s->read(this, sizeof(*this));
m_wiiMagic = SBig(m_wiiMagic);
m_gcnMagic = SBig(m_gcnMagic);
m_debugMonOff = SBig(m_debugMonOff);
m_debugLoadAddr = SBig(m_debugLoadAddr);
}
Header(const char gameID[6], const char* gameTitle, bool wii, char discNum=0, char discVersion=0,
@ -97,6 +105,8 @@ struct Header
Header hs(*this);
hs.m_wiiMagic = SBig(hs.m_wiiMagic);
hs.m_gcnMagic = SBig(hs.m_gcnMagic);
hs.m_debugMonOff = SBig(hs.m_debugMonOff);
hs.m_debugLoadAddr = SBig(hs.m_debugLoadAddr);
ws.write(&hs, sizeof(hs));
}
};
@ -130,6 +140,32 @@ public:
uint32_t entryPoint;
};
/* Currently only kept for dolphin compatibility*/
struct BI2Header
{
uint32_t dolOff;
uint32_t fstOff;
uint32_t fstSz;
uint32_t fstMaxSz;
uint32_t fstMemoryAddress;
uint32_t userPosition;
uint32_t userSz;
uint8_t padding1[4];
int32_t debugMonitorSize;
int32_t simMemSize;
uint32_t argOffset;
uint32_t debugFlag;
uint32_t trkAddress;
uint32_t trkSz;
uint32_t countryCode;
uint32_t unk1;
uint32_t unk2;
uint32_t unk3;
uint32_t dolLimit;
uint32_t unk4;
uint8_t padding2[0x1fd0];
};
class Node
{
public:
@ -223,6 +259,7 @@ public:
bool extractToDirectory(const SystemString& basePath, const ExtractionContext& ctx) const;
};
protected:
BI2Header m_bi2Header;
uint64_t m_dolOff;
uint64_t m_fstOff;
uint64_t m_fstSz;
@ -299,6 +336,8 @@ public:
}
inline size_t getNodeCount() const { return m_nodes.size(); }
inline const Header& getHeader() const { return m_parent.getHeader(); }
inline const uint8_t* getBI2Buf() const { return reinterpret_cast<const uint8_t*>(&m_bi2Header); }
};
protected:

View File

@ -144,8 +144,14 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
return false;
}
if (Mkdir((path + _S("/sys")).c_str(), 0755) && errno != EEXIST)
{
LogModule.report(logvisor::Error, _S("unable to mkdir '%s/sys'"), path.c_str());
return false;
}
/* Extract Apploader */
SystemString apploaderPath = path + _S("/apploader.bin");
SystemString apploaderPath = path + _S("/sys/apploader.img");
if (ctx.force || Stat(apploaderPath.c_str(), &theStat))
{
if (ctx.verbose && ctx.progressCB)
@ -158,11 +164,11 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
}
/* Extract Dol */
SystemString dolPath = path + _S("/boot.dol");
SystemString dolPath = path + _S("/sys/main.dol");
if (ctx.force || Stat(dolPath.c_str(), &theStat))
{
if (ctx.verbose && ctx.progressCB)
ctx.progressCB("boot.dol", 0.f);
ctx.progressCB("main.dol", 0.f);
std::unique_ptr<uint8_t[]> buf = getDOLBuf();
auto ws = NewFileIO(dolPath)->beginWriteStream();
if (!ws)
@ -170,8 +176,33 @@ bool DiscBase::IPartition::extractToDirectory(const SystemString& path,
ws->write(buf.get(), m_dolSz);
}
/* Extract Boot info */
SystemString bootPath = path + _S("/sys/boot.bin");
if (ctx.force || Stat(bootPath.c_str(), &theStat))
{
if (ctx.verbose && ctx.progressCB)
ctx.progressCB("boot.bin", 0.f);
auto ws = NewFileIO(bootPath)->beginWriteStream();
if (!ws)
return false;
getHeader().write(*ws.get());
}
/* Extract BI2 info */
SystemString bi2Path = path + _S("/sys/bi2.bin");
if (ctx.force || Stat(bi2Path.c_str(), &theStat))
{
if (ctx.verbose && ctx.progressCB)
ctx.progressCB("bi2.bin", 0.f);
const uint8_t* buf = getBI2Buf();
auto ws = NewFileIO(bi2Path)->beginWriteStream();
if (!ws)
return false;
ws->write(buf, sizeof(BI2Header));
}
/* Extract Filesystem */
SystemString fsPath = path + _S("/fsroot");
SystemString fsPath = path + _S("/files");
if (Mkdir(fsPath.c_str(), 0755) && errno != EEXIST)
{
LogModule.report(logvisor::Error, _S("unable to mkdir '%s'"), fsPath.c_str());

View File

@ -18,15 +18,16 @@ public:
err = true;
return;
}
uint32_t vals[5];
s->read(vals, 5 * 4);
m_dolOff = SBig(vals[0]);
m_fstOff = SBig(vals[1]);
m_fstSz = SBig(vals[2]);
m_fstMemoryAddr = SBig(vals[4]);
s->read(&m_bi2Header, sizeof(BI2Header));
m_dolOff = SBig(m_bi2Header.dolOff);
m_fstOff = SBig(m_bi2Header.fstOff);
m_fstSz = SBig(m_bi2Header.fstSz);
m_fstMemoryAddr = SBig(m_bi2Header.fstMemoryAddress);
uint32_t vals[2];
s->seek(0x2440 + 0x14);
s->read(vals, 8);
m_apploaderSz = 32 + SBig(vals[0]) + SBig(vals[1]);
m_apploaderSz = ((32 + SBig(vals[0]) + SBig(vals[1])) + 31) & ~31;
/* Yay files!! */
parseFST(*s);

View File

@ -254,14 +254,14 @@ public:
return;
}
uint32_t vals[3];
ds->read(vals, 12);
m_dolOff = SBig(vals[0]) << 2;
m_fstOff = SBig(vals[1]) << 2;
m_fstSz = SBig(vals[2]) << 2;
s->read(&m_bi2Header, sizeof(BI2Header));
m_dolOff = SBig(m_bi2Header.dolOff) << 2;
m_fstOff = SBig(m_bi2Header.fstOff) << 2;
m_fstSz = SBig(m_bi2Header.fstSz) << 2;
ds->seek(0x2440 + 0x14);
uint32_t vals[2];
ds->read(vals, 8);
m_apploaderSz = 32 + SBig(vals[0]) + SBig(vals[1]);
m_apploaderSz = ((32 + SBig(vals[0]) + SBig(vals[1])) + 31) & ~31;
/* Yay files!! */
parseFST(*ds);