diff --git a/Source/Core/Common/Src/Common.h b/Source/Core/Common/Src/Common.h
index ac8f57e772..c46e6219e3 100644
--- a/Source/Core/Common/Src/Common.h
+++ b/Source/Core/Common/Src/Common.h
@@ -218,6 +218,11 @@ inline u32 swap32(u32 data) {return((swap16(data) << 16) | swap16(data >> 16));}
inline u64 swap64(u64 data) {return(((u64)swap32(data) << 32) | swap32(data >> 32));}
#endif
+inline u16 swap16(u8* _pData) {return(swap16(*(u16*)_pData));}
+inline u32 swap32(u8* _pData) {return(swap32(*(u32*)_pData));}
+inline u64 swap64(u8* _pData) {return(swap64(*(u64*)_pData));}
+
+
} // end of namespace Common
///////////////////////////////////
diff --git a/Source/Core/Common/Src/MathUtil.h b/Source/Core/Common/Src/MathUtil.h
index 6edaffb2ca..6e55b4a789 100644
--- a/Source/Core/Common/Src/MathUtil.h
+++ b/Source/Core/Common/Src/MathUtil.h
@@ -34,4 +34,6 @@ void SaveSSEState();
void LoadSSEState();
void LoadDefaultSSEState();
+#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
+
#endif
diff --git a/Source/Core/Core/Core.vcproj b/Source/Core/Core/Core.vcproj
index f0bb0a466c..6a95657e88 100644
--- a/Source/Core/Core/Core.vcproj
+++ b/Source/Core/Core/Core.vcproj
@@ -2247,6 +2247,14 @@
RelativePath=".\Src\Boot\Boot_ELF.h"
>
+
+
+
+
diff --git a/Source/Core/Core/Src/Boot/Boot.cpp b/Source/Core/Core/Src/Boot/Boot.cpp
index 13ab8fe007..f9ec920058 100644
--- a/Source/Core/Core/Src/Boot/Boot.cpp
+++ b/Source/Core/Core/Src/Boot/Boot.cpp
@@ -290,6 +290,13 @@ bool CBoot::BootUp()
}
break;
+ // Wii WAD
+ // ===================================================================================
+ case SCoreStartupParameter::BOOT_WIIWAD:
+ Boot_WiiWAD(_StartupPara.m_strFilename.c_str());
+ break;
+
+
// BIOS
// ===================================================================================
case SCoreStartupParameter::BOOT_BIOS:
diff --git a/Source/Core/Core/Src/Boot/Boot.h b/Source/Core/Core/Src/Boot/Boot.h
index 6388e802da..8461e5fe91 100644
--- a/Source/Core/Core/Src/Boot/Boot.h
+++ b/Source/Core/Core/Src/Boot/Boot.h
@@ -27,17 +27,9 @@ class CBoot
{
public:
- enum TBootFileType
- {
- BOOT_ERROR,
- BOOT_DOL,
- BOOT_ELF,
- BOOT_ISO,
- BOOT_BIOS
- };
-
static bool BootUp();
static bool IsElfWii(const char *filename);
+ static bool IsWiiWAD(const char *filename);
static std::string GenerateMapFilename();
@@ -50,6 +42,7 @@ private:
static bool LoadMapFromFilename(const std::string& _rFilename, const char* _gameID = NULL);
static bool Boot_ELF(const char *filename);
+ static bool Boot_WiiWAD(const char *filename);
static void EmulatedBIOS(bool _bDebug);
static bool EmulatedBIOS_Wii(bool _bDebug);
diff --git a/Source/Core/Core/Src/Boot/Boot_DOL.cpp b/Source/Core/Core/Src/Boot/Boot_DOL.cpp
index c864c787c3..fc0345a9b9 100644
--- a/Source/Core/Core/Src/Boot/Boot_DOL.cpp
+++ b/Source/Core/Core/Src/Boot/Boot_DOL.cpp
@@ -16,62 +16,63 @@
// http://code.google.com/p/dolphin-emu/
#include "Boot_DOL.h"
+#include "FileUtil.h"
#include "../HW/Memmap.h"
-CDolLoader::CDolLoader(const char* _szFilename) : m_bInit(false)
+
+CDolLoader::CDolLoader(u8* _pBuffer, u32 _Size)
+ : m_bInit(false)
{
- // try to open file
- FILE* pStream = fopen(_szFilename, "rb");
- if (pStream)
+ m_bInit = Initialize(_pBuffer, _Size);
+}
+
+CDolLoader::CDolLoader(const char* _szFilename)
+ : m_bInit(false)
+{
+ u64 size = File::GetSize(_szFilename);
+ u8* tmpBuffer = new u8[(size_t)size];
+
+ FILE* pStream = fopen(_szFilename, "rb");
+ fread(tmpBuffer, size, 1, pStream);
+ fclose(pStream);
+
+ m_bInit = Initialize(tmpBuffer, size);
+ delete [] tmpBuffer;
+}
+
+bool CDolLoader::Initialize(u8* _pBuffer, u32 _Size)
+{
+ memcpy(&m_dolheader, _pBuffer, sizeof(SDolHeader));
+
+ // swap memory
+ u32* p = (u32*)&m_dolheader;
+ for (size_t i=0; i<(sizeof(SDolHeader)>>2); i++)
+ p[i] = Common::swap32(p[i]);
+
+ // load all text (code) sections
+ for(int i = 0; i < DOL_NUM_TEXT; i++)
{
- fread(&m_dolheader, 1, sizeof(SDolHeader), pStream);
-
- // swap memory
- u32* p = (u32*)&m_dolheader;
- for (size_t i=0; i<(sizeof(SDolHeader)>>2); i++)
- p[i] = Common::swap32(p[i]);
-
- // load all text (code) sections
- for(int i = 0; i < DOL_NUM_TEXT; i++)
+ if(m_dolheader.textOffset[i] != 0)
{
- if(m_dolheader.textOffset[i] != 0)
- {
- u8* pTemp = new u8[m_dolheader.textSize[i]];
-
- fseek(pStream, m_dolheader.textOffset[i], SEEK_SET);
- fread(pTemp, 1, m_dolheader.textSize[i], pStream);
-
- for (u32 num = 0; num < m_dolheader.textSize[i]; num++)
- Memory::Write_U8(pTemp[num], m_dolheader.textAddress[i] + num);
-
- delete [] pTemp;
- }
+ u8* pTemp = &_pBuffer[m_dolheader.textOffset[i]];
+ for (u32 num = 0; num < m_dolheader.textSize[i]; num++)
+ Memory::Write_U8(pTemp[num], m_dolheader.textAddress[i] + num);
}
-
- // load all data sections
- for(int i = 0; i < DOL_NUM_DATA; i++)
- {
- if(m_dolheader.dataOffset[i] != 0)
- {
- u8* pTemp = new u8[m_dolheader.dataSize[i]];
-
- fseek(pStream, m_dolheader.dataOffset[i], SEEK_SET);
- fread(pTemp, 1, m_dolheader.dataSize[i], pStream);
-
- for (u32 num = 0; num < m_dolheader.dataSize[i]; num++)
- Memory::Write_U8(pTemp[num], m_dolheader.dataAddress[i] + num);
-
- delete [] pTemp;
- }
- }
-
- //TODO - we know where there is code, and where there is data
- //Make use of this!
-
- fclose(pStream);
- m_bInit = true;
}
+
+ // load all data sections
+ for(int i = 0; i < DOL_NUM_DATA; i++)
+ {
+ if(m_dolheader.dataOffset[i] != 0)
+ {
+ u8* pTemp = &_pBuffer[m_dolheader.dataOffset[i]];
+ for (u32 num = 0; num < m_dolheader.dataSize[i]; num++)
+ Memory::Write_U8(pTemp[num], m_dolheader.dataAddress[i] + num);
+ }
+ }
+
+ return true;
}
u32 CDolLoader::GetEntryPoint()
diff --git a/Source/Core/Core/Src/Boot/Boot_DOL.h b/Source/Core/Core/Src/Boot/Boot_DOL.h
index 730d65506c..cfebb13756 100644
--- a/Source/Core/Core/Src/Boot/Boot_DOL.h
+++ b/Source/Core/Core/Src/Boot/Boot_DOL.h
@@ -24,9 +24,12 @@ class CDolLoader
{
public:
CDolLoader(const char* _szFilename);
+ CDolLoader(u8* _pBuffer, u32 _Size);
+
u32 GetEntryPoint();
static bool IsDolWii(const char* filename);
+
private:
enum
{
@@ -51,6 +54,8 @@ private:
};
SDolHeader m_dolheader;
bool m_bInit;
+
+ bool Initialize(u8* _pBuffer, u32 _Size);
};
#endif
diff --git a/Source/Core/Core/Src/Boot/Boot_ELF.cpp b/Source/Core/Core/Src/Boot/Boot_ELF.cpp
index 087c2dbe16..c560c660a2 100644
--- a/Source/Core/Core/Src/Boot/Boot_ELF.cpp
+++ b/Source/Core/Core/Src/Boot/Boot_ELF.cpp
@@ -19,6 +19,7 @@
#include "Boot.h"
#include "../HLE/HLE.h"
#include "Boot_ELF.h"
+#include "Boot_WiiWAD.h"
#include "ElfReader.h"
#include "MappedFile.h"
diff --git a/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp
new file mode 100644
index 0000000000..396367245d
--- /dev/null
+++ b/Source/Core/Core/Src/Boot/Boot_WiiWAD.cpp
@@ -0,0 +1,279 @@
+// Copyright (C) 2003-2008 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "Boot.h"
+#include "../PowerPC/PowerPC.h"
+#include "../HLE/HLE.h"
+#include "../HW/Memmap.h"
+#include "../ConfigManager.h"
+#include "Blob.h"
+#include "MappedFile.h"
+#include "Boot_DOL.h"
+#include "Boot_WiiWAD.h"
+#include "AES/aes.h"
+#include "MathUtil.h"
+
+class CBlobBigEndianReader
+{
+public:
+ CBlobBigEndianReader(DiscIO::IBlobReader& _rReader) : m_rReader(_rReader) {}
+
+ u32 Read32(u64 _Offset)
+ {
+ u32 Temp;
+ m_rReader.Read(_Offset, 4, (u8*)&Temp);
+ return(Common::swap32(Temp));
+ }
+
+private:
+ DiscIO::IBlobReader& m_rReader;
+};
+
+std::vector m_TileMetaContent;
+u16 m_BootIndex = -1;
+
+void AESDecode(u8* _pKey, u8* _IV, u8* _pSrc, u32 _Size, u8* _pDest)
+{
+ AES_KEY AESKey;
+
+ AES_set_decrypt_key(_pKey, 128, &AESKey);
+ AES_cbc_encrypt(_pSrc, _pDest, _Size, &AESKey, _IV, AES_DECRYPT);
+}
+
+u8* CreateWADEntry(DiscIO::IBlobReader& _rReader, u32 _Size, u64 _Offset)
+{
+ if (_Size > 0)
+ {
+ u8* pTmpBuffer = new u8[_Size];
+ _dbg_assert_msg_(BOOT, pTmpBuffer!=0, "WiiWAD: Cant allocate memory for WAD entry");
+
+ if (!_rReader.Read(_Offset, _Size, pTmpBuffer))
+ {
+ PanicAlert("WiiWAD: Could not read from file");
+ }
+ return pTmpBuffer;
+ }
+ return NULL;
+}
+
+void GetKeyFromTicket(u8* pTicket, u8* pTicketKey)
+{
+ u8 CommonKey[16];
+ FILE* pMasterKeyFile = fopen(WII_MASTERKEY_FILE, "rb");
+ _dbg_assert_msg_(BOOT, pMasterKeyFile!=0x0, "WiiWAD: Cant open MasterKeyFile for WII");
+
+ if (pMasterKeyFile)
+ {
+ fread(CommonKey, 16, 1, pMasterKeyFile);
+ fclose(pMasterKeyFile);
+
+ u8 IV[16];
+ memset(IV, 0, sizeof IV);
+ memcpy(IV, pTicket + 0x01dc, 8);
+ AESDecode(CommonKey, IV, pTicket + 0x01bf, 16, pTicketKey);
+ }
+}
+
+bool ParseTMD(u8* pDataApp, u32 pDataAppSize, u8* pTicket, u8* pTMD)
+{
+ u8 DecryptTitleKey[16];
+ u8 IV[16];
+
+ GetKeyFromTicket(pTicket, DecryptTitleKey);
+
+ u32 numEntries = Common::swap16(pTMD + 0x01de);
+ m_BootIndex = Common::swap16(pTMD + 0x01e0);
+ u8* p = pDataApp;
+
+ m_TileMetaContent.resize(numEntries);
+
+ for (u32 i=0; i
+
+struct STileMetaContent
+{
+ u32 m_ContentID;
+ u16 m_Index;
+ u16 m_Type;
+ u32 m_Size;
+
+ u8* m_pData;
+};
+
+
+// [TODO]: this global internal stuff sux... the whole data should be inside the ES
+// but this is the easiest way atm
+extern std::vector m_TileMetaContent;
\ No newline at end of file
diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp
index c205bfe79e..ed3136cccf 100644
--- a/Source/Core/Core/Src/CoreParameter.cpp
+++ b/Source/Core/Core/Src/CoreParameter.cpp
@@ -125,6 +125,14 @@ bool SCoreStartupParameter::AutoSetup(EBootBios _BootBios)
m_BootType = BOOT_ELF;
bNTSC = true;
}
+ else if ((!strcasecmp(Extension.c_str(), ".wad")) &&
+ CBoot::IsWiiWAD(m_strFilename.c_str()))
+ {
+ bWii = true;
+ Region = EUR_DIR;
+ m_BootType = BOOT_WIIWAD;
+ bNTSC = false;
+ }
else if (!strcasecmp(Extension.c_str(), ".dol"))
{
bWii = CDolLoader::IsDolWii(m_strFilename.c_str());
diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h
index f71d13fed5..33138122fe 100644
--- a/Source/Core/Core/Src/CoreParameter.h
+++ b/Source/Core/Core/Src/CoreParameter.h
@@ -89,6 +89,7 @@ struct SCoreStartupParameter
BOOT_ISO,
BOOT_ELF,
BOOT_DOL,
+ BOOT_WIIWAD,
BOOT_BIOS
};
EBootType m_BootType;
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h
index 3c13b6f05d..459e0b87d2 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_es.h
@@ -54,6 +54,23 @@
#include "WII_IPC_HLE_Device.h"
#include "../VolumeHandler.h"
+#include "../boot/Boot_WiiWAD.h"
+
+
+struct SContentAccess
+{
+ u32 m_Position;
+ STileMetaContent* m_pContent;
+};
+
+typedef std::map CContenAccessMap;
+CContenAccessMap m_ContenAccessMap;
+u32 AccessIdentID = 0x60000000;
+
+
+
+
+
// http://wiibrew.org/index.php?title=/dev/es
class CWII_IPC_HLE_Device_es : public IWII_IPC_HLE_Device
@@ -130,6 +147,90 @@ public:
switch(Buffer.Parameter)
{
+ case IOCTL_ES_OPENCONTENT: // 0x09
+ {
+ u32 CFD = AccessIdentID++;
+ u32 Index = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
+
+ m_ContenAccessMap[CFD].m_Position = 0;
+ m_ContenAccessMap[CFD].m_pContent = &m_TileMetaContent[Index];
+
+ Memory::Write_U32(CFD, _CommandAddress + 0x4);
+
+ LOG(WII_IPC_ES, "ES: IOCTL_ES_OPENCONTENT: Index %i -> got CFD %x", Index, CFD);
+ return true;
+ }
+ break;
+
+ case IOCTL_ES_READCONTENT:
+ {
+ _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1);
+
+ u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
+ u32 Size = Buffer.PayloadBuffer[0].m_Size;
+ u32 Addr = Buffer.PayloadBuffer[0].m_Address;
+
+ _dbg_assert_(WII_IPC_ES, m_ContenAccessMap.find(CFD) != m_ContenAccessMap.end());
+ SContentAccess& rContent = m_ContenAccessMap[CFD];
+
+ u8* pSrc = &rContent.m_pContent->m_pData[rContent.m_Position];
+ u8* pDest = Memory::GetPointer(Addr);
+
+ memcpy(pDest,pSrc, Size);
+ rContent.m_Position += Size;
+
+ LOG(WII_IPC_ES, "ES: IOCTL_ES_READCONTENT: CFD %x, Addr 0x%x, Size %i -> stream pos %i", CFD, Addr, Size, rContent.m_Position);
+
+ Memory::Write_U32(Size, _CommandAddress + 0x4);
+ return true;
+ }
+ break;
+
+ case IOCTL_ES_CLOSECONTENT:
+ {
+ _dbg_assert_(WII_IPC_ES, Buffer.NumberInBuffer == 1);
+ u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
+
+ CContenAccessMap::iterator itr = m_ContenAccessMap.find(CFD);
+ m_ContenAccessMap.erase(itr);
+
+ LOG(WII_IPC_ES, "ES: IOCTL_ES_CLOSECONTENT: CFD %x", CFD);
+
+ Memory::Write_U32(0, _CommandAddress + 0x4);
+ return true;
+ }
+ break;
+
+ case IOCTL_ES_SEEKCONTENT:
+ {
+ u32 CFD = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
+ u32 Addr = Memory::Read_U32(Buffer.InBuffer[1].m_Address);
+ u32 Mode = Memory::Read_U32(Buffer.InBuffer[2].m_Address);
+
+ _dbg_assert_(WII_IPC_ES, m_ContenAccessMap.find(CFD) != m_ContenAccessMap.end());
+ SContentAccess& rContent = m_ContenAccessMap[CFD];
+
+ switch(Mode)
+ {
+ case 0: // SET
+ rContent.m_Position = Addr;
+ break;
+
+ case 1: // CUR
+ break;
+
+ case 2: // END
+ rContent.m_Position = rContent.m_pContent->m_Size;
+ break;
+ }
+
+ LOG(WII_IPC_ES, "ES: IOCTL_ES_SEEKCONTENT: CFD %x, Addr 0x%x, Mode %i -> Pos %i", CFD, Addr, Mode, rContent.m_Position);
+
+ Memory::Write_U32(rContent.m_Position, _CommandAddress + 0x4);
+ return true;
+ }
+ break;
+
case IOCTL_ES_GETTITLEDIR: // 0x1d
{
/* I changed reading the TitleID from disc to reading from the
@@ -166,7 +267,9 @@ public:
case IOCTL_ES_GETVIEWCNT: // 0x12 (Input: 8 bytes, Output: 4 bytes)
{
if(Buffer.NumberInBuffer)
+ {
u32 InBuffer = Memory::Read_U32(Buffer.InBuffer[0].m_Address);
+ }
// Should we write something here?
//Memory::Write_U32(0, Buffer.PayloadBuffer[0].m_Address);
diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp
index 2653771c35..c21de268d4 100644
--- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp
+++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp
@@ -310,6 +310,14 @@ void dcbtst(UGeckoInstruction _inst)
// TODO(ector) check docs
void dcbz(UGeckoInstruction _inst)
{
+ // !!! after the dcbz follows a dcbf... dont clear the memory in this case !!!
+ // 0x81330c2c
+ u32 NextOpcode = Memory::Read_U32(PC+4);
+ if (NextOpcode == 0x7C0400AC)
+ {
+ return;
+ }
+
// HACK but works... we think
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
}
diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp
index 7ed0ed84df..f0b28f797e 100644
--- a/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp
+++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit_LoadStore.cpp
@@ -255,6 +255,8 @@
// Zero cache line.
void Jit64::dcbz(UGeckoInstruction inst)
{
+ Default(inst); return;
+
if(Core::g_CoreStartupParameter.bJITOff || Core::g_CoreStartupParameter.bJITLoadStoreOff)
{Default(inst); return;} // turn off from debugger
INSTRUCTION_START;
diff --git a/Source/Core/Core/Src/SConscript b/Source/Core/Core/Src/SConscript
index d4538c4183..3c53bcd8d7 100644
--- a/Source/Core/Core/Src/SConscript
+++ b/Source/Core/Core/Src/SConscript
@@ -21,6 +21,7 @@ files = ["Console.cpp",
"Boot/Boot_BIOSEmu.cpp",
"Boot/Boot_DOL.cpp",
"Boot/Boot_ELF.cpp",
+ "Boot/Boot_WiiWAD.cpp",
"Boot/ElfReader.cpp",
"Debugger/Debugger_BreakPoints.cpp",
"Debugger/Debugger_SymbolMap.cpp",
diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp
index 401349f43a..15745e00cd 100644
--- a/Source/Core/DolphinWX/Src/FrameTools.cpp
+++ b/Source/Core/DolphinWX/Src/FrameTools.cpp
@@ -409,7 +409,7 @@ void CFrame::DoOpen(bool Boot)
wxEmptyString, wxEmptyString, wxEmptyString,
wxString::Format
(
- _T("All GC/Wii files (elf, dol, gcm, iso)|*.elf;*.dol;*.gcm;*.iso;*.gcz|All files (%s)|%s"),
+ _T("All GC/Wii files (elf, dol, gcm, iso, wad)|*.elf;*.dol;*.gcm;*.iso;*.gcz;*.wad|All files (%s)|%s"),
wxFileSelectorDefaultWildcardStr,
wxFileSelectorDefaultWildcardStr
),