Install shared content from wads to the proper location
allows (among other things) installing the wiimenu from a wad extracted from the update partition of a game currently you can choose Tools > Install Wii Menu or right click wad from the gamelist and install restart required to have the Tools > Load Wii Menu work I thought I had already commit this, I guess I forgot and it's just been sitting on my hdd :p git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5448 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
c1dde5bb1d
commit
303f7e3af8
|
@ -120,8 +120,18 @@ bool CBoot::Install_WiiWAD(const char* _pFilename)
|
|||
fwrite(Content.m_Header, DiscIO::INANDContentLoader::CONTENT_HEADER_SIZE, 1, pTMDFile);
|
||||
|
||||
char APPFileName[1024];
|
||||
if (Content.m_Type & 0x8000) //shared
|
||||
{
|
||||
sprintf(APPFileName, "%s",
|
||||
DiscIO::CSharedContent::AccessInstance().AddSharedContent(Content.m_SHA1Hash).c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(APPFileName, "%s%08x.app", ContentPath, Content.m_ContentID);
|
||||
}
|
||||
|
||||
if (!File::Exists(APPFileName))
|
||||
{
|
||||
FILE* pAPPFile = fopen(APPFileName, "wb");
|
||||
if (pAPPFile == NULL)
|
||||
{
|
||||
|
@ -132,6 +142,11 @@ bool CBoot::Install_WiiWAD(const char* _pFilename)
|
|||
fwrite(Content.m_pData, Content.m_Size, 1, pAPPFile);
|
||||
fclose(pAPPFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(DISCIO, "Content %s already exists.", APPFileName);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(pTMDFile);
|
||||
|
||||
|
@ -161,6 +176,11 @@ bool CBoot::Install_WiiWAD(const char* _pFilename)
|
|||
|
||||
fclose(pTicketFile);
|
||||
|
||||
if (!DiscIO::cUIDsys::AccessInstance().AddTitle(TitleID))
|
||||
{
|
||||
INFO_LOG(DISCIO, "Title %08x%08x, already exists in uid.sys", TitleID_HI, TitleID_LO);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,14 +92,16 @@ bool CWII_IPC_HLE_Device_es::Open(u32 _CommandAddress, u32 _Mode)
|
|||
m_TitleID = ((u64)0x00010000 << 32) | 0xF00DBEEF;
|
||||
}
|
||||
|
||||
// TODO: when dev/fs IOCTLV_GETUSAGE is correct (wii doesnt report fs as corrupt) uncomment this line
|
||||
// title ids are all listed in sys/uid.sys - lpfaint99
|
||||
//DiscIO::cUIDsys::AccessInstance().GetTitleIDs(m_TitleIDs);
|
||||
|
||||
// scan for the title ids listed in TMDs within /title/
|
||||
m_TitleIDs.push_back(0x0000000100000002ULL);
|
||||
//m_TitleIDs.push_back(0x0001000248414741ULL);
|
||||
//m_TitleIDs.push_back(0x0001000248414341ULL);
|
||||
//m_TitleIDs.push_back(0x0001000248414241ULL);
|
||||
//m_TitleIDs.push_back(0x0001000248414141ULL);
|
||||
|
||||
// scan for the title ids listed in TMDs within /title/
|
||||
//FindValidTitleIDs();
|
||||
|
||||
INFO_LOG(WII_IPC_ES, "Set default title to %08x/%08x", (u32)(m_TitleID>>32), (u32)m_TitleID);
|
||||
|
|
|
@ -29,51 +29,31 @@
|
|||
namespace DiscIO
|
||||
{
|
||||
|
||||
|
||||
class CSharedContent
|
||||
{
|
||||
public:
|
||||
|
||||
static CSharedContent& AccessInstance() { return m_Instance; }
|
||||
|
||||
std::string GetFilenameFromSHA1(u8* _pHash);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
CSharedContent();
|
||||
|
||||
virtual ~CSharedContent();
|
||||
|
||||
struct SElement
|
||||
{
|
||||
u8 FileName[8];
|
||||
u8 SHA1Hash[20];
|
||||
};
|
||||
|
||||
std::vector<SElement> m_Elements;
|
||||
static CSharedContent m_Instance;
|
||||
};
|
||||
|
||||
CSharedContent CSharedContent::m_Instance;
|
||||
cUIDsys cUIDsys::m_Instance;
|
||||
|
||||
CSharedContent::CSharedContent()
|
||||
{
|
||||
char szFilename[1024];
|
||||
sprintf(szFilename, "%sshared1/content.map", File::GetUserPath(D_WIIUSER_IDX));
|
||||
if (File::Exists(szFilename))
|
||||
sprintf(contentMap, "%sshared1/content.map", File::GetUserPath(D_WIIUSER_IDX));
|
||||
lastID = 0;
|
||||
if (File::Exists(contentMap))
|
||||
{
|
||||
FILE* pFile = fopen(szFilename, "rb");
|
||||
FILE* pFile = fopen(contentMap, "rb");
|
||||
while(!feof(pFile))
|
||||
{
|
||||
SElement Element;
|
||||
if (fread(&Element, sizeof(SElement), 1, pFile) == 1)
|
||||
{
|
||||
m_Elements.push_back(Element);
|
||||
lastID++;
|
||||
}
|
||||
}
|
||||
fclose(pFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
File::CreateFullPath(contentMap);
|
||||
}
|
||||
}
|
||||
|
||||
CSharedContent::~CSharedContent()
|
||||
|
@ -95,6 +75,29 @@ std::string CSharedContent::GetFilenameFromSHA1(u8* _pHash)
|
|||
return "unk";
|
||||
}
|
||||
|
||||
std::string CSharedContent::AddSharedContent(u8* _pHash)
|
||||
{
|
||||
std::string szFilename = GetFilenameFromSHA1(_pHash);
|
||||
if (strcasecmp(szFilename.c_str(), "unk") == 0)
|
||||
{
|
||||
char tempFilename[1024], c_ID[9];
|
||||
SElement Element;
|
||||
sprintf(c_ID, "%08x", lastID);
|
||||
memcpy(Element.FileName, c_ID, 8);
|
||||
memcpy(Element.SHA1Hash, _pHash, 20);
|
||||
m_Elements.push_back(Element);
|
||||
FILE* pFile = fopen(contentMap, "ab");
|
||||
if (pFile)
|
||||
{
|
||||
fwrite(&Element, sizeof(SElement), 1, pFile);
|
||||
fclose(pFile);
|
||||
}
|
||||
sprintf(tempFilename, "%sshared1/%s.app", File::GetUserPath(D_WIIUSER_IDX), c_ID);
|
||||
szFilename = tempFilename;
|
||||
lastID++;
|
||||
}
|
||||
return szFilename;
|
||||
}
|
||||
|
||||
|
||||
// this classes must be created by the CNANDContentManager
|
||||
|
@ -371,5 +374,100 @@ const INANDContentLoader& CNANDContentManager::GetNANDLoader(const std::string&
|
|||
return *m_Map[_rName];
|
||||
}
|
||||
|
||||
cUIDsys::cUIDsys()
|
||||
{
|
||||
sprintf(uidSys, "%ssys/uid.sys", File::GetUserPath(D_WIIUSER_IDX));
|
||||
lastUID = 0x00001000;
|
||||
if (File::Exists(uidSys))
|
||||
{
|
||||
FILE* pFile = fopen(uidSys, "rb");
|
||||
while(!feof(pFile))
|
||||
{
|
||||
SElement Element;
|
||||
if (fread(&Element, sizeof(SElement), 1, pFile) == 1)
|
||||
{
|
||||
if (CheckValidTitle(Common::swap64(Element.titleID)))
|
||||
{
|
||||
m_Elements.push_back(Element);
|
||||
lastUID++;
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(pFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
File::CreateFullPath(uidSys);
|
||||
}
|
||||
}
|
||||
|
||||
cUIDsys::~cUIDsys()
|
||||
{}
|
||||
|
||||
u32 cUIDsys::GetUIDFromTitle(u64 _Title)
|
||||
{
|
||||
for (size_t i=0; i<m_Elements.size(); i++)
|
||||
{
|
||||
if (Common::swap64(_Title) == (u64)m_Elements[i].titleID)
|
||||
{
|
||||
return Common::swap32(m_Elements[i].UID);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cUIDsys::AddTitle(u64 _TitleID)
|
||||
{
|
||||
if (GetUIDFromTitle(_TitleID))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
SElement Element;
|
||||
*(u64*)&(Element.titleID) = Common::swap64(_TitleID);
|
||||
*(u32*)&(Element.UID) = Common::swap32(lastUID);
|
||||
m_Elements.push_back(Element);
|
||||
lastUID++;
|
||||
FILE* pFile = fopen(uidSys, "ab");
|
||||
if (pFile)
|
||||
{
|
||||
if (fwrite(&Element, sizeof(SElement), 1, pFile) != 1)
|
||||
ERROR_LOG(DISCIO, "fwrite failed");
|
||||
fclose(pFile);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void cUIDsys::GetTitleIDs(std::vector<u64>& _TitleIDs)
|
||||
{
|
||||
for (size_t i = 0; i < m_Elements.size(); i++)
|
||||
{
|
||||
_TitleIDs.push_back(Common::swap64(m_Elements[i].titleID));
|
||||
}
|
||||
}
|
||||
|
||||
bool cUIDsys::CheckValidTitle(u64 _TitleID)
|
||||
{
|
||||
char TitlePath[1024];
|
||||
sprintf(TitlePath, "%stitle/%08x/%08x/content/title.tmd", File::GetUserPath(D_WIIUSER_IDX),
|
||||
(u32)(_TitleID >> 32), (u32)(_TitleID & 0xFFFFFFFF));
|
||||
|
||||
if (File::Exists(TitlePath))
|
||||
{
|
||||
FILE* pTMDFile = fopen(TitlePath, "rb");
|
||||
if(pTMDFile)
|
||||
{
|
||||
u64 TitleID = 0xDEADBEEFDEADBEEFULL;
|
||||
fseek(pTMDFile, 0x18C, SEEK_SET);
|
||||
fread(&TitleID, 8, 1, pTMDFile);
|
||||
fclose(pTMDFile);
|
||||
if (_TitleID == Common::swap64(TitleID))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace end
|
||||
|
||||
|
|
|
@ -94,7 +94,66 @@ private:
|
|||
|
||||
};
|
||||
|
||||
class CSharedContent
|
||||
{
|
||||
public:
|
||||
|
||||
static CSharedContent& AccessInstance() { return m_Instance; }
|
||||
|
||||
std::string GetFilenameFromSHA1(u8* _pHash);
|
||||
std::string AddSharedContent(u8* _pHash);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
CSharedContent();
|
||||
|
||||
virtual ~CSharedContent();
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct SElement
|
||||
{
|
||||
u8 FileName[8];
|
||||
u8 SHA1Hash[20];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
u32 lastID;
|
||||
char contentMap[1024];
|
||||
std::vector<SElement> m_Elements;
|
||||
static CSharedContent m_Instance;
|
||||
};
|
||||
|
||||
class cUIDsys
|
||||
{
|
||||
public:
|
||||
|
||||
static cUIDsys& AccessInstance() { return m_Instance; }
|
||||
|
||||
u32 GetUIDFromTitle(u64 _Title);
|
||||
bool AddTitle(u64 _Title);
|
||||
bool CheckValidTitle(u64 _TitleID);
|
||||
void GetTitleIDs(std::vector<u64>& _TitleIDs);
|
||||
private:
|
||||
|
||||
|
||||
cUIDsys();
|
||||
|
||||
virtual ~cUIDsys();
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct SElement
|
||||
{
|
||||
u8 titleID[8];
|
||||
u8 UID[4];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
u32 lastUID;
|
||||
char uidSys[1024];
|
||||
std::vector<SElement> m_Elements;
|
||||
static cUIDsys m_Instance;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -281,6 +281,7 @@ EVT_MENU(IDM_MEMCARD, CFrame::OnMemcard)
|
|||
EVT_MENU(IDM_IMPORTSAVE, CFrame::OnImportSave)
|
||||
EVT_MENU(IDM_CHEATS, CFrame::OnShow_CheatsWindow)
|
||||
EVT_MENU(IDM_CHANGEDISC, CFrame::OnChangeDisc)
|
||||
EVT_MENU(IDM_INSTALL_WII_MENU, CFrame::OnLoadWiiMenu)
|
||||
EVT_MENU(IDM_LOAD_WII_MENU, CFrame::OnLoadWiiMenu)
|
||||
|
||||
EVT_MENU(IDM_TOGGLE_FULLSCREEN, CFrame::OnToggleFullscreen)
|
||||
|
|
|
@ -192,6 +192,10 @@ void CFrame::CreateMenu()
|
|||
{
|
||||
toolsMenu->Append(IDM_LOAD_WII_MENU, _T("Load Wii Menu"));
|
||||
}
|
||||
else
|
||||
{
|
||||
toolsMenu->Append(IDM_INSTALL_WII_MENU, _T("Install Wii Menu"));
|
||||
}
|
||||
toolsMenu->AppendSeparator();
|
||||
toolsMenu->AppendCheckItem(IDM_CONNECT_WIIMOTE1, GetMenuLabel(HK_WIIMOTE1_CONNECT));
|
||||
toolsMenu->AppendCheckItem(IDM_CONNECT_WIIMOTE2, GetMenuLabel(HK_WIIMOTE2_CONNECT));
|
||||
|
@ -1035,10 +1039,34 @@ void CFrame::OnShow_CheatsWindow(wxCommandEvent& WXUNUSED (event))
|
|||
CheatsWindow = new wxCheatsWindow(this, wxDefaultPosition, wxSize(600, 390));
|
||||
}
|
||||
|
||||
void CFrame::OnLoadWiiMenu(wxCommandEvent& WXUNUSED (event))
|
||||
void CFrame::OnLoadWiiMenu(wxCommandEvent& event)
|
||||
{
|
||||
if (event.GetId() == IDM_LOAD_WII_MENU)
|
||||
{
|
||||
BootGame(std::string (File::GetUserPath(D_WIIMENU_IDX)));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
wxString path = wxFileSelector(
|
||||
_T("Select the System Menu wad extracted from the update partition of a disc"),
|
||||
wxEmptyString, wxEmptyString, wxEmptyString,
|
||||
wxString::Format
|
||||
(
|
||||
_T("System Menu wad|RVL-WiiSystemmenu-v*.wad"),
|
||||
wxFileSelectorDefaultWildcardStr,
|
||||
wxFileSelectorDefaultWildcardStr
|
||||
),
|
||||
wxFD_OPEN | wxFD_PREVIEW | wxFD_FILE_MUST_EXIST,
|
||||
this);
|
||||
|
||||
if (CBoot::Install_WiiWAD(path.mb_str()))
|
||||
{;// TODO: Fix so that menu item changes approprately so a restart is not required
|
||||
// GetMenuBar()->FindItem(IDM_INSTALL_WII_MENU)->SetId(IDM_LOAD_WII_MENU);
|
||||
// GetMenuBar()->FindItem(IDM_LOAD_WII_MENU)->SetItemLabel(_T("Load Wii Menu"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CFrame::OnConnectWiimote(wxCommandEvent& event)
|
||||
{
|
||||
|
|
|
@ -95,6 +95,7 @@ enum
|
|||
IDM_CHANGEDISC,
|
||||
IDM_PROPERTIES,
|
||||
IDM_LOAD_WII_MENU,
|
||||
IDM_INSTALL_WII_MENU,
|
||||
IDM_LUA,
|
||||
IDM_CONNECT_WIIMOTE1,
|
||||
IDM_CONNECT_WIIMOTE2,
|
||||
|
|
Loading…
Reference in New Issue