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:
itsnotmailmail committed 2009-06-17 02:50:54 +00:00
1 parent c468d1e36a
commit 232217c1cd
12 files changed
+421 -191

No files matched your search

+2
View File
@@ -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 };
+80 -2
View File
@@ -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;
}
+10
View File
@@ -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];