Added the ability to install WADs (such as DLC WADs). Currently it just installs a WAD when booting it fails (when it's not bootable), I'm not sure whether there should be a menu option specially for installing WADS...
note: If you previously manually installed WADS by creating a *file* called "CONTENT", trying to reinstall that WAD automatically will fail unless you delete the file. Added some empty log files that some games require for DLC to be recognized. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3474 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
1 parent
c468d1e36a
commit
232217c1cd
12 files changed
+421
-191
No files matched your search
@@ -32,6 +32,8 @@ public:
|
||||
static bool IsWiiWAD(const char *filename);
|
||||
|
||||
static std::string GenerateMapFilename();
|
||||
|
||||
static bool Install_WiiWAD(const char *filename);
|
||||
|
||||
private:
|
||||
enum { BIOS_SIZE = 2*1024*1024 };
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "../PatchEngine.h"
|
||||
#include "../IPC_HLE/WII_IPC_HLE.h"
|
||||
|
||||
#include "WiiWAD.h"
|
||||
#include "NANDContentLoader.h"
|
||||
#include "FileUtil.h"
|
||||
#include "Boot_DOL.h"
|
||||
@@ -32,7 +33,7 @@
|
||||
|
||||
bool CBoot::IsWiiWAD(const char *filename)
|
||||
{
|
||||
return DiscIO::CNANDContentManager::IsWiiWAD(filename);
|
||||
return DiscIO::WiiWAD::IsWiiWAD(filename);
|
||||
}
|
||||
|
||||
bool CBoot::Boot_WiiWAD(const char* _pFilename)
|
||||
@@ -57,7 +58,7 @@ bool CBoot::Boot_WiiWAD(const char* _pFilename)
|
||||
// DOL
|
||||
const DiscIO::SNANDContent* pContent = ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex());
|
||||
if (pContent == NULL)
|
||||
return false;
|
||||
return false;
|
||||
|
||||
WII_IPC_HLE_Interface::SetDefaultContentFile(_pFilename);
|
||||
|
||||
@@ -83,3 +84,80 @@ bool CBoot::Boot_WiiWAD(const char* _pFilename)
|
||||
}
|
||||
|
||||
|
||||
bool CBoot::Install_WiiWAD(const char* _pFilename)
|
||||
{
|
||||
if (!IsWiiWAD(_pFilename))
|
||||
return false;
|
||||
const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(_pFilename);
|
||||
if (ContentLoader.IsValid() == false)
|
||||
return false;
|
||||
|
||||
u64 TitleID = ContentLoader.GetTitleID();
|
||||
u32 TitleID_HI = (u32)(TitleID >> 32);
|
||||
u32 TitleID_LO = (u32)(TitleID);
|
||||
|
||||
//copy WAD's tmd header and contents to content directory
|
||||
|
||||
char ContentPath[260+1];
|
||||
sprintf(ContentPath, FULL_WII_USER_DIR "title/%08x/%08x/content/", TitleID_HI, TitleID_LO);
|
||||
File::CreateFullPath(ContentPath);
|
||||
|
||||
std::string TMDFileName(ContentPath);
|
||||
TMDFileName += "title.tmd";
|
||||
|
||||
FILE* pTMDFile = fopen(TMDFileName.c_str(), "wb");
|
||||
if (pTMDFile == NULL) {
|
||||
PanicAlert("WAD installation failed: error creating %s", TMDFileName.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
fwrite(ContentLoader.GetTmdHeader(), DiscIO::INANDContentLoader::TMD_HEADER_SIZE, 1, pTMDFile);
|
||||
|
||||
for (u32 i = 0; i < ContentLoader.GetContentSize(); i++)
|
||||
{
|
||||
DiscIO::SNANDContent Content = ContentLoader.GetContent()[i];
|
||||
|
||||
fwrite(Content.m_Header, DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE, 1, pTMDFile);
|
||||
|
||||
char APPFileName[1024];
|
||||
sprintf(APPFileName, "%s%08x.app", ContentPath, Content.m_ContentID);
|
||||
|
||||
FILE* pAPPFile = fopen(APPFileName, "wb");
|
||||
if (pAPPFile == NULL) {
|
||||
PanicAlert("WAD installation failed: error creating %s", APPFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
fwrite(Content.m_pData, Content.m_Size, 1, pAPPFile);
|
||||
fclose(pAPPFile);
|
||||
}
|
||||
|
||||
fclose(pTMDFile);
|
||||
|
||||
//Extract and copy WAD's ticket to ticket directory
|
||||
|
||||
char TicketPath[260+1];
|
||||
sprintf(TicketPath, FULL_WII_USER_DIR "ticket/%08x/", TitleID_HI);
|
||||
File::CreateFullPath(TicketPath);
|
||||
|
||||
char TicketFileName[260+1];
|
||||
sprintf(TicketFileName, FULL_WII_USER_DIR "ticket/%08x/%08x.tik", TitleID_HI, TitleID_LO);
|
||||
|
||||
FILE* pTicketFile = fopen(TicketFileName, "wb");
|
||||
if (pTicketFile == NULL) {
|
||||
PanicAlert("WAD installation failed: error creating %s", TicketFileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
DiscIO::WiiWAD Wad(_pFilename);
|
||||
if (!Wad.IsValid())
|
||||
return false;
|
||||
|
||||
fwrite(Wad.GetTicket(), Wad.GetTicketSize(), 1, pTicketFile);
|
||||
|
||||
fclose(pTicketFile);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +151,16 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
|
||||
{
|
||||
const DiscIO::IVolume* pVolume = DiscIO::CreateVolumeFromFilename(m_strFilename.c_str());
|
||||
const DiscIO::INANDContentLoader& ContentLoader = DiscIO::CNANDContentManager::Access().GetNANDLoader(m_strFilename);
|
||||
|
||||
if (ContentLoader.GetContentByIndex(ContentLoader.GetBootIndex()) == NULL)
|
||||
{
|
||||
//WAD is valid yet cannot be booted. Install instead.
|
||||
bool installed = CBoot::Install_WiiWAD(m_strFilename.c_str());
|
||||
if (installed)
|
||||
SuccessAlert("The WAD has been installed successfully");
|
||||
return false; //do not boot
|
||||
}
|
||||
|
||||
u64 TitleID = ContentLoader.GetTitleID();
|
||||
char* pTitleID = (char*)&TitleID;
|
||||
|
||||
|
||||
@@ -200,8 +200,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
|
||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
|
||||
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename);
|
||||
std::string TitlePath = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitlePath);
|
||||
|
||||
ERROR_LOG(WII_IPC_ES, "IOCTL_ES_GETTITLECONTENTS: title: %08x/%08x MaxCount: %i (just content in private directory)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
|
||||
|
||||
@@ -240,7 +240,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
_dbg_assert_msg_(WII_IPC_ES, m_ContentAccessMap[CFD].m_pContent != NULL, "No Content for TitleID: %08x/%08x at Index %x", (u32)(TitleID>>32), (u32)TitleID, Index);
|
||||
// Fix for DLC by itsnotmailmail
|
||||
if (m_ContentAccessMap[CFD].m_pContent == NULL)
|
||||
CFD = 0xffffffff;
|
||||
CFD = 0xffffffff; //TODO: what is the correct error value here?
|
||||
Memory::Write_U32(CFD, _CommandAddress + 0x4);
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "ES: IOCTL_ES_OPENTITLECONTENT: TitleID: %08x/%08x Index %i -> got CFD %x", (u32)(TitleID>>32), (u32)TitleID, Index, CFD);
|
||||
@@ -517,8 +517,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETTMDVIEWCNT no out buffer");
|
||||
|
||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename);
|
||||
std::string TitlePath = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitlePath);
|
||||
|
||||
_dbg_assert_(WII_IPC_ES, Loader.IsValid());
|
||||
u32 TMDViewCnt = 0;
|
||||
@@ -545,8 +545,8 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
|
||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
|
||||
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename);
|
||||
std::string TitlePath = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitlePath);
|
||||
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETTMDVIEWCNT: title: %08x/%08x buffersize: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
|
||||
@@ -557,7 +557,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
{
|
||||
u32 Address = Buffer.PayloadBuffer[0].m_Address;
|
||||
|
||||
Memory::WriteBigEData(Loader.GetTicket(), Address, DiscIO::INANDContentLoader::TICKET_VIEW_SIZE);
|
||||
Memory::WriteBigEData(Loader.GetTicketView(), Address, DiscIO::INANDContentLoader::TICKET_VIEW_SIZE);
|
||||
Address += DiscIO::INANDContentLoader::TICKET_VIEW_SIZE;
|
||||
|
||||
Memory::Write_U16(Loader.GetTitleVersion(), Address); Address += 2;
|
||||
@@ -581,6 +581,68 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_ES_GETSTOREDTMD:
|
||||
{
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMD no in buffer");
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMD no out buffer");
|
||||
|
||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
|
||||
std::string TitlePath = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitlePath);
|
||||
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x buffersize: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
|
||||
|
||||
u32 Count = 0;
|
||||
if (Loader.IsValid())
|
||||
{
|
||||
u32 Address = Buffer.PayloadBuffer[0].m_Address;
|
||||
|
||||
Memory::WriteBigEData(Loader.GetTmdHeader(), Address, DiscIO::INANDContentLoader::TMD_HEADER_SIZE);
|
||||
Address += DiscIO::INANDContentLoader::TMD_HEADER_SIZE;
|
||||
|
||||
const std::vector<DiscIO::SNANDContent>& rContent = Loader.GetContent();
|
||||
for (size_t i=0; i<Loader.GetContentSize(); i++)
|
||||
{
|
||||
Memory::WriteBigEData(rContent[i].m_Header, Address, DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE);
|
||||
Address += DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE;
|
||||
}
|
||||
|
||||
_dbg_assert_(WII_IPC_ES, (Address-Buffer.PayloadBuffer[0].m_Address) == Buffer.PayloadBuffer[0].m_Size);
|
||||
}
|
||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_ES_GETSTOREDTMDSIZE:
|
||||
{
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMDSIZE no in buffer");
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_ES_GETSTOREDTMDSIZE no out buffer");
|
||||
|
||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||
std::string TitlePath = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitlePath);
|
||||
|
||||
_dbg_assert_(WII_IPC_ES, Loader.IsValid());
|
||||
u32 TMDCnt = 0;
|
||||
if (Loader.IsValid())
|
||||
{
|
||||
TMDCnt += DiscIO::INANDContentLoader::TMD_HEADER_SIZE;
|
||||
TMDCnt += (u32)Loader.GetContentSize() * DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE;
|
||||
}
|
||||
Memory::Write_U32(TMDCnt, Buffer.PayloadBuffer[0].m_Address);
|
||||
|
||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDCnt);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_ES_ENCRYPT:
|
||||
{
|
||||
u32 keyIndex = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
|
||||
@@ -644,71 +706,6 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_ES_GETSTOREDTMD:
|
||||
{
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 2, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMD no in buffer");
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMD no out buffer");
|
||||
|
||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||
u32 MaxCount = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
|
||||
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename);
|
||||
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x buffersize: %i", (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
|
||||
|
||||
u32 Count = 0;
|
||||
if (Loader.IsValid())
|
||||
{
|
||||
u32 Address = Buffer.PayloadBuffer[0].m_Address;
|
||||
|
||||
Memory::WriteBigEData(Loader.GetTmdHeader(), Address, DiscIO::INANDContentLoader::TMD_HEADER_SIZE);
|
||||
Address += DiscIO::INANDContentLoader::TMD_HEADER_SIZE;
|
||||
|
||||
const std::vector<DiscIO::SNANDContent>& rContent = Loader.GetContent();
|
||||
for (size_t i=0; i<Loader.GetContentSize(); i++)
|
||||
{
|
||||
Memory::Write_U32(rContent[i].m_ContentID, Address); Address += 4;
|
||||
Memory::Write_U16(rContent[i].m_Index, Address); Address += 2;
|
||||
Memory::Write_U16(rContent[i].m_Type, Address); Address += 2;
|
||||
Memory::Write_U64(rContent[i].m_Size, Address); Address += 8;
|
||||
Memory::WriteBigEData(rContent[i].m_SHA1Hash, Address, 20); Address += 20;
|
||||
}
|
||||
|
||||
_dbg_assert_(WII_IPC_ES, (Address-Buffer.PayloadBuffer[0].m_Address) == Buffer.PayloadBuffer[0].m_Size);
|
||||
}
|
||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMD: title: %08x/%08x (buffer size: %i)", (u32)(TitleID >> 32), (u32)TitleID, MaxCount);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_ES_GETSTOREDTMDSIZE:
|
||||
{
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberInBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_GETSTOREDTMDSIZE no in buffer");
|
||||
_dbg_assert_msg_(WII_IPC_ES, Buffer.NumberPayloadBuffer == 1, "CWII_IPC_HLE_Device_es: IOCTL_ES_ES_GETSTOREDTMDSIZE no out buffer");
|
||||
|
||||
u64 TitleID = Memory::Read_U64(Buffer.InBuffer[0].m_Address);
|
||||
std::string TitleFilename = CreateTitleContentPath(TitleID);
|
||||
const DiscIO::INANDContentLoader& Loader = DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename);
|
||||
|
||||
_dbg_assert_(WII_IPC_ES, Loader.IsValid());
|
||||
u32 TMDCnt = 0;
|
||||
if (Loader.IsValid())
|
||||
{
|
||||
TMDCnt += DiscIO::INANDContentLoader::TMD_HEADER_SIZE;
|
||||
TMDCnt += (u32)Loader.GetContentSize() * (4 + 2 + 2 + 8 + 20); //id, index, type, size, hash
|
||||
}
|
||||
Memory::Write_U32(TMDCnt, Buffer.PayloadBuffer[0].m_Address);
|
||||
|
||||
Memory::Write_U32(0, _CommandAddress + 0x4);
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "IOCTL_ES_GETSTOREDTMDSIZE: title: %08x/%08x (view size %i)", (u32)(TitleID >> 32), (u32)TitleID, TMDCnt);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case IOCTL_ES_GETCONSUMPTION: // (Input: 8 bytes, Output: 0 bytes, 4 bytes)
|
||||
_dbg_assert_msg_(WII_IPC_ES, 0, "IOCTL_ES_GETCONSUMPTION: this looks really wrong...");
|
||||
break;
|
||||
@@ -717,7 +714,7 @@ bool CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||
_dbg_assert_msg_(WII_IPC_ES, 0, "IOCTL_ES_DIGETTICKETVIEW: this looks really wrong...");
|
||||
break;
|
||||
|
||||
case IOCTL_ES_GETDEVICECERT: //
|
||||
case IOCTL_ES_GETDEVICECERT: // (Input: none, Output: 384 bytes)
|
||||
_dbg_assert_msg_(WII_IPC_ES, 0, "IOCTL_ES_GETDEVICECERT: this looks really wrong...");
|
||||
break;
|
||||
|
||||
@@ -744,8 +741,8 @@ const DiscIO::INANDContentLoader& CWII_IPC_HLE_Device_es::AccessContentDevice(u6
|
||||
if (itr != m_NANDContent.end())
|
||||
return *itr->second;
|
||||
|
||||
std::string TitleFilename = CreateTitleContentPath(_TitleID);
|
||||
m_NANDContent[_TitleID] = &DiscIO::CNANDContentManager::Access().GetNANDLoader(TitleFilename);
|
||||
std::string TitlePath = CreateTitleContentPath(_TitleID);
|
||||
m_NANDContent[_TitleID] = &DiscIO::CNANDContentManager::Access().GetNANDLoader(TitlePath);
|
||||
|
||||
_dbg_assert_(WII_IPC_ES, m_NANDContent[_TitleID]->IsValid());
|
||||
return *m_NANDContent[_TitleID];
|
||||
|
||||
Reference in new issue
Block a user