Merge pull request #833 from shuffle2/msvc-improvements
misc improvements for msvc build. -Werror for msvc!
This commit is contained in:
commit
d29e333142
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemDefinitionGroup>
|
<ItemDefinitionGroup>
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1228,7 +1228,9 @@ typedef wxUint32 wxDword;
|
||||||
each time we cast it to a pointer or a handle (which results in hundreds
|
each time we cast it to a pointer or a handle (which results in hundreds
|
||||||
of warnings as Win32 API often passes pointers in them)
|
of warnings as Win32 API often passes pointers in them)
|
||||||
*/
|
*/
|
||||||
#if wxCHECK_VISUALC_VERSION(7)
|
// (dolphin-emu) Just disable __w64 usage. It's not meant to be used anymore,
|
||||||
|
// even on 32bit builds.
|
||||||
|
#if 0
|
||||||
#define wxW64 __w64
|
#define wxW64 __w64
|
||||||
#else
|
#else
|
||||||
#define wxW64
|
#define wxW64
|
||||||
|
|
|
@ -333,7 +333,7 @@ bool wxCommandProcessor::IsDirty() const
|
||||||
{
|
{
|
||||||
// We have never been saved, so we are dirty if and only if we have any
|
// We have never been saved, so we are dirty if and only if we have any
|
||||||
// commands at all.
|
// commands at all.
|
||||||
return m_currentCommand;
|
return !!m_currentCommand;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !m_currentCommand )
|
if ( !m_currentCommand )
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
// for compilers that support precompilation, includes "wx.h".
|
// for compilers that support precompilation, includes "wx.h".
|
||||||
#define GL_GLEXT_PROTOTYPES
|
|
||||||
#include "wx/wxprec.h"
|
#include "wx/wxprec.h"
|
||||||
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
#pragma hdrstop
|
#pragma hdrstop
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
<ImportGroup Label="PropertySheets">
|
<ImportGroup Label="PropertySheets">
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
<Import Project="..\..\Source\VSProps\Base.props" />
|
<Import Project="..\..\Source\VSProps\Base.props" />
|
||||||
|
<Import Project="..\..\Source\VSProps\ClDisableAllWarnings.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup />
|
<PropertyGroup />
|
||||||
|
|
|
@ -172,7 +172,13 @@
|
||||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_es.cpp" />
|
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_es.cpp" />
|
||||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_FileIO.cpp" />
|
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_FileIO.cpp" />
|
||||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_fs.cpp" />
|
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_fs.cpp" />
|
||||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_hid.cpp" />
|
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_hid.cpp">
|
||||||
|
<!--
|
||||||
|
Disable "nonstandard extension used : zero-sized array in struct/union" warning,
|
||||||
|
which is hit in libusb.h (and this is the only file which uses that header).
|
||||||
|
-->
|
||||||
|
<DisableSpecificWarnings>4200;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_net.cpp" />
|
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_net.cpp" />
|
||||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_net_ssl.cpp" />
|
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_net_ssl.cpp" />
|
||||||
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_sdio_slot0.cpp" />
|
<ClCompile Include="IPC_HLE\WII_IPC_HLE_Device_sdio_slot0.cpp" />
|
||||||
|
|
|
@ -195,7 +195,7 @@ FifoDataFile *FifoDataFile::Load(const std::string &filename, bool flagsOnly)
|
||||||
return dataFile;
|
return dataFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FifoDataFile::PadFile(u32 numBytes, File::IOFile& file)
|
void FifoDataFile::PadFile(size_t numBytes, File::IOFile& file)
|
||||||
{
|
{
|
||||||
const u8 zero = 0;
|
const u8 zero = 0;
|
||||||
fwrite(&zero, sizeof(zero), numBytes, file.GetHandle());
|
fwrite(&zero, sizeof(zero), numBytes, file.GetHandle());
|
||||||
|
|
|
@ -66,8 +66,8 @@ public:
|
||||||
u32 *GetXFRegs() { return m_XFRegs; }
|
u32 *GetXFRegs() { return m_XFRegs; }
|
||||||
|
|
||||||
void AddFrame(const FifoFrameInfo &frameInfo);
|
void AddFrame(const FifoFrameInfo &frameInfo);
|
||||||
const FifoFrameInfo &GetFrame(size_t frame) const { return m_Frames[frame]; }
|
const FifoFrameInfo &GetFrame(u32 frame) const { return m_Frames[frame]; }
|
||||||
size_t GetFrameCount() { return m_Frames.size(); }
|
u32 GetFrameCount() { return static_cast<u32>(m_Frames.size()); }
|
||||||
|
|
||||||
bool Save(const std::string& filename);
|
bool Save(const std::string& filename);
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ private:
|
||||||
FLAG_IS_WII = 1
|
FLAG_IS_WII = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
void PadFile(u32 numBytes, File::IOFile &file);
|
void PadFile(size_t numBytes, File::IOFile &file);
|
||||||
|
|
||||||
void SetFlag(u32 flag, bool set);
|
void SetFlag(u32 flag, bool set);
|
||||||
bool GetFlag(u32 flag) const;
|
bool GetFlag(u32 flag) const;
|
||||||
|
|
|
@ -48,7 +48,7 @@ void FifoPlaybackAnalyzer::AnalyzeFrames(FifoDataFile *file, std::vector<Analyze
|
||||||
frameInfo.clear();
|
frameInfo.clear();
|
||||||
frameInfo.resize(file->GetFrameCount());
|
frameInfo.resize(file->GetFrameCount());
|
||||||
|
|
||||||
for (size_t frameIdx = 0; frameIdx < file->GetFrameCount(); ++frameIdx)
|
for (u32 frameIdx = 0; frameIdx < file->GetFrameCount(); ++frameIdx)
|
||||||
{
|
{
|
||||||
const FifoFrameInfo& frame = file->GetFrame(frameIdx);
|
const FifoFrameInfo& frame = file->GetFrame(frameIdx);
|
||||||
AnalyzedFrameInfo& analyzed = frameInfo[frameIdx];
|
AnalyzedFrameInfo& analyzed = frameInfo[frameIdx];
|
||||||
|
|
|
@ -259,7 +259,7 @@ void FifoPlayer::WriteAllMemoryUpdates()
|
||||||
{
|
{
|
||||||
_assert_(m_File);
|
_assert_(m_File);
|
||||||
|
|
||||||
for (size_t frameNum = 0; frameNum < m_File->GetFrameCount(); ++frameNum)
|
for (u32 frameNum = 0; frameNum < m_File->GetFrameCount(); ++frameNum)
|
||||||
{
|
{
|
||||||
const FifoFrameInfo &frame = m_File->GetFrame(frameNum);
|
const FifoFrameInfo &frame = m_File->GetFrame(frameNum);
|
||||||
for (auto& update : frame.memoryUpdates)
|
for (auto& update : frame.memoryUpdates)
|
||||||
|
|
|
@ -378,6 +378,8 @@ void WriteHandler<T>::ResetMethod(WriteHandlingMethod<T>* method)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define all the public specializations that are exported in MMIOHandlers.h.
|
// Define all the public specializations that are exported in MMIOHandlers.h.
|
||||||
MMIO_PUBLIC_SPECIALIZATIONS();
|
#define MaybeExtern
|
||||||
|
MMIO_PUBLIC_SPECIALIZATIONS()
|
||||||
|
#undef MaybeExtern
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,12 +216,14 @@ private:
|
||||||
MaybeExtern template ReadHandlingMethod<u8>* ReadToLarger(Mapping* mmio, u32 larger_addr, u32 shift); \
|
MaybeExtern template ReadHandlingMethod<u8>* ReadToLarger(Mapping* mmio, u32 larger_addr, u32 shift); \
|
||||||
MaybeExtern template ReadHandlingMethod<u16>* ReadToLarger(Mapping* mmio, u32 larger_addr, u32 shift)
|
MaybeExtern template ReadHandlingMethod<u16>* ReadToLarger(Mapping* mmio, u32 larger_addr, u32 shift)
|
||||||
|
|
||||||
#define MMIO_PUBLIC_SPECIALIZATIONS(MaybeExtern) \
|
#define MMIO_PUBLIC_SPECIALIZATIONS() \
|
||||||
MMIO_GENERIC_PUBLIC_SPECIALIZATIONS(MaybeExtern, u8); \
|
MMIO_GENERIC_PUBLIC_SPECIALIZATIONS(MaybeExtern, u8); \
|
||||||
MMIO_GENERIC_PUBLIC_SPECIALIZATIONS(MaybeExtern, u16); \
|
MMIO_GENERIC_PUBLIC_SPECIALIZATIONS(MaybeExtern, u16); \
|
||||||
MMIO_GENERIC_PUBLIC_SPECIALIZATIONS(MaybeExtern, u32); \
|
MMIO_GENERIC_PUBLIC_SPECIALIZATIONS(MaybeExtern, u32); \
|
||||||
MMIO_SPECIAL_PUBLIC_SPECIALIZATIONS(MaybeExtern);
|
MMIO_SPECIAL_PUBLIC_SPECIALIZATIONS(MaybeExtern);
|
||||||
|
|
||||||
MMIO_PUBLIC_SPECIALIZATIONS(extern)
|
#define MaybeExtern extern
|
||||||
|
MMIO_PUBLIC_SPECIALIZATIONS()
|
||||||
|
#undef MaybeExtern
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <libusb.h>
|
||||||
|
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/Debugger/Debugger_SymbolMap.h"
|
#include "Core/Debugger/Debugger_SymbolMap.h"
|
||||||
|
@ -25,7 +26,7 @@ void CWII_IPC_HLE_Device_hid::checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid)
|
||||||
static u16 timeToFill = 0;
|
static u16 timeToFill = 0;
|
||||||
if (timeToFill == 0)
|
if (timeToFill == 0)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(hid->s_device_list_reply);
|
std::lock_guard<std::mutex> lk(hid->m_device_list_reply_mutex);
|
||||||
if (hid->deviceCommandAddress != 0){
|
if (hid->deviceCommandAddress != 0){
|
||||||
hid->FillOutDevices(Memory::Read_U32(hid->deviceCommandAddress + 0x18), Memory::Read_U32(hid->deviceCommandAddress + 0x1C));
|
hid->FillOutDevices(Memory::Read_U32(hid->deviceCommandAddress + 0x18), Memory::Read_U32(hid->deviceCommandAddress + 0x1C));
|
||||||
|
|
||||||
|
@ -97,11 +98,11 @@ CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid()
|
||||||
deinit_libusb = true;
|
deinit_libusb = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& device : open_devices)
|
for (const auto& device : m_open_devices)
|
||||||
{
|
{
|
||||||
libusb_close(device.second);
|
libusb_close(device.second);
|
||||||
}
|
}
|
||||||
open_devices.clear();
|
m_open_devices.clear();
|
||||||
|
|
||||||
if (deinit_libusb)
|
if (deinit_libusb)
|
||||||
libusb_exit(nullptr);
|
libusb_exit(nullptr);
|
||||||
|
@ -238,7 +239,7 @@ bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
|
||||||
}
|
}
|
||||||
case IOCTL_HID_SHUTDOWN:
|
case IOCTL_HID_SHUTDOWN:
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lk(s_device_list_reply);
|
std::lock_guard<std::mutex> lk(m_device_list_reply_mutex);
|
||||||
if (deviceCommandAddress != 0){
|
if (deviceCommandAddress != 0){
|
||||||
Memory::Write_U32(0xFFFFFFFF, Memory::Read_U32(deviceCommandAddress + 0x18));
|
Memory::Write_U32(0xFFFFFFFF, Memory::Read_U32(deviceCommandAddress + 0x18));
|
||||||
|
|
||||||
|
@ -479,12 +480,12 @@ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize)
|
||||||
if (hidDeviceAliases[i] != 0 && check_cur != check)
|
if (hidDeviceAliases[i] != 0 && check_cur != check)
|
||||||
{
|
{
|
||||||
DEBUG_LOG(WII_IPC_HID, "Removing: device %d %hX %hX", i, check, check_cur);
|
DEBUG_LOG(WII_IPC_HID, "Removing: device %d %hX %hX", i, check, check_cur);
|
||||||
std::lock_guard<std::mutex> lk(s_open_devices);
|
std::lock_guard<std::mutex> lk(m_open_devices_mutex);
|
||||||
if (open_devices.find(i) != open_devices.end())
|
if (m_open_devices.find(i) != m_open_devices.end())
|
||||||
{
|
{
|
||||||
libusb_device_handle *handle = open_devices[i];
|
libusb_device_handle *handle = m_open_devices[i];
|
||||||
libusb_close(handle);
|
libusb_close(handle);
|
||||||
open_devices.erase(i);
|
m_open_devices.erase(i);
|
||||||
}
|
}
|
||||||
hidDeviceAliases[i] = 0;
|
hidDeviceAliases[i] = 0;
|
||||||
}
|
}
|
||||||
|
@ -514,11 +515,11 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lk(s_open_devices);
|
std::lock_guard<std::mutex> lk(m_open_devices_mutex);
|
||||||
|
|
||||||
if (open_devices.find(devNum) != open_devices.end())
|
if (m_open_devices.find(devNum) != m_open_devices.end())
|
||||||
{
|
{
|
||||||
handle = open_devices[devNum];
|
handle = m_open_devices[devNum];
|
||||||
if (libusb_kernel_driver_active(handle, 0) != LIBUSB_ERROR_NO_DEVICE)
|
if (libusb_kernel_driver_active(handle, 0) != LIBUSB_ERROR_NO_DEVICE)
|
||||||
{
|
{
|
||||||
return handle;
|
return handle;
|
||||||
|
@ -526,7 +527,7 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
libusb_close(handle);
|
libusb_close(handle);
|
||||||
open_devices.erase(devNum);
|
m_open_devices.erase(devNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,7 +598,7 @@ libusb_device_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
open_devices[devNum] = handle;
|
m_open_devices[devNum] = handle;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -4,20 +4,31 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <libusb.h>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#include "Common/Thread.h"
|
#include "Common/Thread.h"
|
||||||
#include "Core/IPC_HLE/WII_IPC_HLE.h"
|
#include "Core/IPC_HLE/WII_IPC_HLE.h"
|
||||||
#include "Core/IPC_HLE/WII_IPC_HLE_Device.h"
|
#include "Core/IPC_HLE/WII_IPC_HLE_Device.h"
|
||||||
|
|
||||||
|
// Forward declare things which we need from libusb header.
|
||||||
|
// This prevents users of this file from indirectly pulling in libusb.
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#define LIBUSB_CALL WINAPI
|
||||||
|
#else
|
||||||
|
#define LIBUSB_CALL
|
||||||
|
#endif
|
||||||
|
struct libusb_device_handle;
|
||||||
|
struct libusb_device_descriptor;
|
||||||
|
struct libusb_config_descriptor;
|
||||||
|
struct libusb_interface_descriptor;
|
||||||
|
struct libusb_endpoint_descriptor;
|
||||||
|
struct libusb_transfer;
|
||||||
|
|
||||||
#define HID_ID_MASK 0x0000FFFFFFFFFFFF
|
#define HID_ID_MASK 0x0000FFFFFFFFFFFF
|
||||||
#define MAX_HID_INTERFACES 1
|
#define MAX_HID_INTERFACES 1
|
||||||
|
|
||||||
#define HIDERR_NO_DEVICE_FOUND -4
|
#define HIDERR_NO_DEVICE_FOUND -4
|
||||||
|
|
||||||
/* Connection timed out */
|
|
||||||
|
|
||||||
class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device
|
class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -45,7 +56,6 @@ private:
|
||||||
IOCTL_HID_CANCEL_INTERRUPT = 0x08,
|
IOCTL_HID_CANCEL_INTERRUPT = 0x08,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Device descriptor */
|
|
||||||
struct WiiHIDDeviceDescriptor
|
struct WiiHIDDeviceDescriptor
|
||||||
{
|
{
|
||||||
u8 bLength;
|
u8 bLength;
|
||||||
|
@ -108,32 +118,22 @@ private:
|
||||||
u32 deviceCommandAddress;
|
u32 deviceCommandAddress;
|
||||||
void FillOutDevices(u32 BufferOut, u32 BufferOutSize);
|
void FillOutDevices(u32 BufferOut, u32 BufferOutSize);
|
||||||
int GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check);
|
int GetAvaiableDevNum(u16 idVendor, u16 idProduct, u8 bus, u8 port, u16 check);
|
||||||
bool ClaimDevice(libusb_device_handle * dev);
|
bool ClaimDevice(libusb_device_handle* dev);
|
||||||
|
|
||||||
void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, const struct libusb_device_descriptor *src);
|
void ConvertDeviceToWii(WiiHIDDeviceDescriptor* dest, const libusb_device_descriptor* src);
|
||||||
void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, const struct libusb_config_descriptor *src);
|
void ConvertConfigToWii(WiiHIDConfigDescriptor* dest, const libusb_config_descriptor* src);
|
||||||
void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, const struct libusb_interface_descriptor *src);
|
void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor* dest, const libusb_interface_descriptor* src);
|
||||||
void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, const struct libusb_endpoint_descriptor *src);
|
void ConvertEndpointToWii(WiiHIDEndpointDescriptor* dest, const libusb_endpoint_descriptor* src);
|
||||||
|
|
||||||
int Align(int num, int alignment);
|
int Align(int num, int alignment);
|
||||||
static void checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid);
|
static void checkUsbUpdates(CWII_IPC_HLE_Device_hid* hid);
|
||||||
static void LIBUSB_CALL handleUsbUpdates(struct libusb_transfer *transfer);
|
static void LIBUSB_CALL handleUsbUpdates(libusb_transfer* transfer);
|
||||||
|
|
||||||
struct libusb_device_handle * GetDeviceByDevNum(u32 devNum);
|
libusb_device_handle* GetDeviceByDevNum(u32 devNum);
|
||||||
std::map<u32,libusb_device_handle*> open_devices;
|
std::map<u32, libusb_device_handle*> m_open_devices;
|
||||||
std::mutex s_open_devices;
|
std::mutex m_open_devices_mutex;
|
||||||
std::mutex s_device_list_reply;
|
std::mutex m_device_list_reply_mutex;
|
||||||
std::map<std::string,int> device_identifiers;
|
|
||||||
|
|
||||||
std::thread usb_thread;
|
std::thread usb_thread;
|
||||||
bool usb_thread_running;
|
bool usb_thread_running;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
u32 enq_address;
|
|
||||||
u32 type;
|
|
||||||
void * context;
|
|
||||||
} _hidevent;
|
|
||||||
|
|
||||||
std::list<_hidevent> event_list;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -312,7 +312,7 @@ void Jit64::mtcrf(UGeckoInstruction inst)
|
||||||
u64 newcrval = PPCCRToInternal(newcr);
|
u64 newcrval = PPCCRToInternal(newcr);
|
||||||
if ((s64)newcrval == (s32)newcrval)
|
if ((s64)newcrval == (s32)newcrval)
|
||||||
{
|
{
|
||||||
MOV(64, M(&PowerPC::ppcState.cr_val[i]), Imm32(newcrval));
|
MOV(64, M(&PowerPC::ppcState.cr_val[i]), Imm32((s32)newcrval));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1665,9 +1665,9 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, u32 exitAddress) {
|
||||||
X64Reg reg = regFindFreeReg(RI);
|
X64Reg reg = regFindFreeReg(RI);
|
||||||
u64 val = ibuild->GetImmValue64(I);
|
u64 val = ibuild->GetImmValue64(I);
|
||||||
if ((u32)val == val)
|
if ((u32)val == val)
|
||||||
Jit->MOV(32, R(reg), Imm32(val));
|
Jit->MOV(32, R(reg), Imm32((u32)val));
|
||||||
else if ((s32)val == (s64)val)
|
else if ((s32)val == (s64)val)
|
||||||
Jit->MOV(64, R(reg), Imm32(val));
|
Jit->MOV(64, R(reg), Imm32((s32)val));
|
||||||
else
|
else
|
||||||
Jit->MOV(64, R(reg), Imm64(val));
|
Jit->MOV(64, R(reg), Imm64(val));
|
||||||
RI.regs[reg] = I;
|
RI.regs[reg] = I;
|
||||||
|
|
|
@ -266,7 +266,7 @@ const u8 *Jitx86Base::BackPatch(u8 *codePtr, u32 emAddress, void *ctx_void)
|
||||||
XEmitter emitter(start);
|
XEmitter emitter(start);
|
||||||
const u8 *trampoline = trampolines.GetWriteTrampoline(info, registersInUse, pc);
|
const u8 *trampoline = trampolines.GetWriteTrampoline(info, registersInUse, pc);
|
||||||
emitter.CALL((void *)trampoline);
|
emitter.CALL((void *)trampoline);
|
||||||
int padding = codePtr + info.instructionSize - emitter.GetCodePtr();
|
ptrdiff_t padding = (codePtr - emitter.GetCodePtr()) + info.instructionSize;
|
||||||
if (padding > 0)
|
if (padding > 0)
|
||||||
{
|
{
|
||||||
emitter.NOP(padding);
|
emitter.NOP(padding);
|
||||||
|
|
|
@ -413,7 +413,7 @@ void EmuCodeBlock::SafeWriteRegToReg(X64Reg reg_value, X64Reg reg_addr, int acce
|
||||||
{
|
{
|
||||||
const u8* backpatchStart = GetCodePtr();
|
const u8* backpatchStart = GetCodePtr();
|
||||||
u8* mov = UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, offset, !(flags & SAFE_LOADSTORE_NO_SWAP));
|
u8* mov = UnsafeWriteRegToReg(reg_value, reg_addr, accessSize, offset, !(flags & SAFE_LOADSTORE_NO_SWAP));
|
||||||
int padding = BACKPATCH_SIZE - (GetCodePtr() - backpatchStart);
|
ptrdiff_t padding = BACKPATCH_SIZE - (GetCodePtr() - backpatchStart);
|
||||||
if (padding > 0)
|
if (padding > 0)
|
||||||
{
|
{
|
||||||
NOP(padding);
|
NOP(padding);
|
||||||
|
|
|
@ -114,7 +114,7 @@ PadSettingCheckBox::PadSettingCheckBox(wxWindow* const parent, ControllerEmu::Co
|
||||||
|
|
||||||
void PadSettingCheckBox::UpdateGUI()
|
void PadSettingCheckBox::UpdateGUI()
|
||||||
{
|
{
|
||||||
((wxCheckBox*)wxcontrol)->SetValue(setting->GetValue());
|
((wxCheckBox*)wxcontrol)->SetValue(!!setting->GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PadSettingCheckBox::UpdateValue()
|
void PadSettingCheckBox::UpdateValue()
|
||||||
|
|
|
@ -21,112 +21,117 @@
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
#include "Common/MathUtil.h"
|
#include "Common/MathUtil.h"
|
||||||
#include "Common/NandPaths.h"
|
#include "Common/NandPaths.h"
|
||||||
|
#include "Common/StdMakeUnique.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
#include "Common/Crypto/ec.h"
|
#include "Common/Crypto/ec.h"
|
||||||
#include "DolphinWX/MemoryCards/WiiSaveCrypted.h"
|
#include "DolphinWX/MemoryCards/WiiSaveCrypted.h"
|
||||||
|
|
||||||
static Common::replace_v replacements;
|
static Common::replace_v replacements;
|
||||||
|
|
||||||
const u8 SDKey[16] = {
|
const u8 CWiiSaveCrypted::s_sd_key[16] = {
|
||||||
0xAB, 0x01, 0xB9, 0xD8, 0xE1, 0x62, 0x2B, 0x08,
|
0xAB, 0x01, 0xB9, 0xD8, 0xE1, 0x62, 0x2B, 0x08,
|
||||||
0xAF, 0xBA, 0xD8, 0x4D, 0xBF, 0xC2, 0xA5, 0x5D
|
0xAF, 0xBA, 0xD8, 0x4D, 0xBF, 0xC2, 0xA5, 0x5D
|
||||||
};
|
};
|
||||||
const u8 MD5_BLANKER[0x10] = {
|
const u8 CWiiSaveCrypted::s_md5_blanker[16] = {
|
||||||
0x0E, 0x65, 0x37, 0x81, 0x99, 0xBE, 0x45, 0x17,
|
0x0E, 0x65, 0x37, 0x81, 0x99, 0xBE, 0x45, 0x17,
|
||||||
0xAB, 0x06, 0xEC, 0x22, 0x45, 0x1A, 0x57, 0x93
|
0xAB, 0x06, 0xEC, 0x22, 0x45, 0x1A, 0x57, 0x93
|
||||||
};
|
};
|
||||||
const u32 NG_id = 0x0403AC68;
|
const u32 CWiiSaveCrypted::s_ng_id = 0x0403AC68;
|
||||||
|
|
||||||
bool CWiiSaveCrypted::ImportWiiSave(const char* FileName)
|
bool CWiiSaveCrypted::ImportWiiSave(const char* filename)
|
||||||
{
|
{
|
||||||
CWiiSaveCrypted saveFile(FileName);
|
CWiiSaveCrypted save_file(filename);
|
||||||
return saveFile.b_valid;
|
return save_file.m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWiiSaveCrypted::ExportWiiSave(u64 TitleID)
|
bool CWiiSaveCrypted::ExportWiiSave(u64 title_id)
|
||||||
{
|
{
|
||||||
CWiiSaveCrypted exportSave("", TitleID);
|
CWiiSaveCrypted export_save("", title_id);
|
||||||
if (exportSave.b_valid)
|
if (export_save.m_valid)
|
||||||
{
|
{
|
||||||
SuccessAlertT("Successfully exported file to %s", exportSave.encryptedSavePath.c_str());
|
SuccessAlertT("Successfully exported file to %s",
|
||||||
|
export_save.m_encrypted_save_path.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PanicAlertT("Export failed");
|
PanicAlertT("Export failed");
|
||||||
}
|
}
|
||||||
return exportSave.b_valid;
|
return export_save.m_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWiiSaveCrypted::ExportAllSaves()
|
void CWiiSaveCrypted::ExportAllSaves()
|
||||||
{
|
{
|
||||||
std::string titleFolder = File::GetUserPath(D_WIIUSER_IDX) + "title";
|
std::string title_folder = File::GetUserPath(D_WIIUSER_IDX) + "title";
|
||||||
std::vector<u64> titles;
|
std::vector<u64> titles;
|
||||||
u32 pathMask = 0x00010000;
|
const u32 path_mask = 0x00010000;
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
File::FSTEntry FST_Temp;
|
File::FSTEntry fst_tmp;
|
||||||
std::string folder = StringFromFormat("%s/%08x/", titleFolder.c_str(), pathMask | i);
|
std::string folder = StringFromFormat("%s/%08x/", title_folder.c_str(), path_mask | i);
|
||||||
File::ScanDirectoryTree(folder, FST_Temp);
|
File::ScanDirectoryTree(folder, fst_tmp);
|
||||||
|
|
||||||
for (const File::FSTEntry& entry : FST_Temp.children)
|
for (const File::FSTEntry& entry : fst_tmp.children)
|
||||||
{
|
{
|
||||||
if (entry.isDirectory)
|
if (entry.isDirectory)
|
||||||
{
|
{
|
||||||
u32 gameid;
|
u32 game_id;
|
||||||
if (AsciiToHex(entry.virtualName, gameid))
|
if (AsciiToHex(entry.virtualName, game_id))
|
||||||
{
|
{
|
||||||
std::string bannerPath = StringFromFormat("%s%08x/data/banner.bin", folder.c_str(), gameid);
|
std::string banner_path =
|
||||||
if (File::Exists(bannerPath))
|
StringFromFormat("%s%08x/data/banner.bin", folder.c_str(), game_id);
|
||||||
|
if (File::Exists(banner_path))
|
||||||
{
|
{
|
||||||
u64 titleID = (((u64)pathMask | i) << 32) | gameid;
|
u64 title_id = (((u64)path_mask | i) << 32) | game_id;
|
||||||
titles.push_back(titleID);
|
titles.push_back(title_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SuccessAlertT("Found %u save files", (unsigned int) titles.size());
|
SuccessAlertT("Found %u save files", (unsigned int)titles.size());
|
||||||
u32 success = 0;
|
u32 success = 0;
|
||||||
for (const u64& title : titles)
|
for (const u64& title : titles)
|
||||||
{
|
{
|
||||||
CWiiSaveCrypted* exportSave = new CWiiSaveCrypted("", title);
|
CWiiSaveCrypted* export_save = new CWiiSaveCrypted("", title);
|
||||||
if (exportSave->b_valid)
|
if (export_save->m_valid)
|
||||||
success++;
|
success++;
|
||||||
delete exportSave;
|
delete export_save;
|
||||||
}
|
}
|
||||||
SuccessAlertT("Sucessfully exported %u saves to %s", success, (File::GetUserPath(D_USER_IDX) + "private/wii/title/").c_str());
|
SuccessAlertT("Sucessfully exported %u saves to %s", success,
|
||||||
|
(File::GetUserPath(D_USER_IDX) + "private/wii/title/").c_str());
|
||||||
}
|
}
|
||||||
CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 TitleID)
|
|
||||||
: m_TitleID(TitleID)
|
CWiiSaveCrypted::CWiiSaveCrypted(const char* filename, u64 title_id)
|
||||||
|
: m_title_id(title_id)
|
||||||
{
|
{
|
||||||
Common::ReadReplacements(replacements);
|
Common::ReadReplacements(replacements);
|
||||||
encryptedSavePath = std::string(FileName);
|
m_encrypted_save_path = std::string(filename);
|
||||||
memcpy(SD_IV, "\x21\x67\x12\xE6\xAA\x1F\x68\x9F\x95\xC5\xA2\x23\x24\xDC\x6A\x98", 0x10);
|
memcpy(m_sd_iv, "\x21\x67\x12\xE6\xAA\x1F\x68\x9F\x95\xC5\xA2\x23\x24\xDC\x6A\x98", 0x10);
|
||||||
|
|
||||||
if (!TitleID) // Import
|
if (!title_id) // Import
|
||||||
{
|
{
|
||||||
aes_setkey_dec(&m_AES_ctx, SDKey, 128);
|
aes_setkey_dec(&m_aes_ctx, s_sd_key, 128);
|
||||||
b_valid = true;
|
m_valid = true;
|
||||||
ReadHDR();
|
ReadHDR();
|
||||||
ReadBKHDR();
|
ReadBKHDR();
|
||||||
ImportWiiSaveFiles();
|
ImportWiiSaveFiles();
|
||||||
// TODO: check_sig()
|
// TODO: check_sig()
|
||||||
if (b_valid)
|
if (m_valid)
|
||||||
{
|
{
|
||||||
SuccessAlertT("Successfully imported save files");
|
SuccessAlertT("Successfully imported save files");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PanicAlertT("Import failed");
|
PanicAlertT("Import failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aes_setkey_enc(&m_AES_ctx, SDKey, 128);
|
aes_setkey_enc(&m_aes_ctx, s_sd_key, 128);
|
||||||
|
|
||||||
if (getPaths(true))
|
if (getPaths(true))
|
||||||
{
|
{
|
||||||
b_valid = true;
|
m_valid = true;
|
||||||
WriteHDR();
|
WriteHDR();
|
||||||
WriteBKHDR();
|
WriteBKHDR();
|
||||||
ExportWiiSaveFiles();
|
ExportWiiSaveFiles();
|
||||||
|
@ -137,92 +142,97 @@ CWiiSaveCrypted::CWiiSaveCrypted(const char* FileName, u64 TitleID)
|
||||||
|
|
||||||
void CWiiSaveCrypted::ReadHDR()
|
void CWiiSaveCrypted::ReadHDR()
|
||||||
{
|
{
|
||||||
File::IOFile fpData_bin(encryptedSavePath, "rb");
|
File::IOFile data_file(m_encrypted_save_path, "rb");
|
||||||
if (!fpData_bin)
|
if (!data_file)
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Cannot open %s", encryptedSavePath.c_str());
|
ERROR_LOG(CONSOLE, "Cannot open %s", m_encrypted_save_path.c_str());
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!fpData_bin.ReadBytes(&_encryptedHeader, HEADER_SZ))
|
if (!data_file.ReadBytes(&m_encrypted_header, HEADER_SZ))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Failed to read header");
|
ERROR_LOG(CONSOLE, "Failed to read header");
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fpData_bin.Close();
|
data_file.Close();
|
||||||
|
|
||||||
aes_crypt_cbc(&m_AES_ctx, AES_DECRYPT, HEADER_SZ, SD_IV, (const u8*)&_encryptedHeader, (u8*)&_header);
|
aes_crypt_cbc(&m_aes_ctx, AES_DECRYPT, HEADER_SZ, m_sd_iv, (const u8*)&m_encrypted_header,
|
||||||
u32 bannerSize = Common::swap32(_header.hdr.BannerSize);
|
(u8*)&m_header);
|
||||||
if ((bannerSize < FULL_BNR_MIN) || (bannerSize > FULL_BNR_MAX) ||
|
u32 banner_size = Common::swap32(m_header.hdr.BannerSize);
|
||||||
(((bannerSize - BNR_SZ) % ICON_SZ) != 0))
|
if ((banner_size < FULL_BNR_MIN) || (banner_size > FULL_BNR_MAX) ||
|
||||||
|
(((banner_size - BNR_SZ) % ICON_SZ) != 0))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Not a Wii save or read failure for file header size %x", bannerSize);
|
ERROR_LOG(CONSOLE, "Not a Wii save or read failure for file header size %x", banner_size);
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_TitleID = Common::swap64(_header.hdr.SaveGameTitle);
|
m_title_id = Common::swap64(m_header.hdr.SaveGameTitle);
|
||||||
|
|
||||||
|
|
||||||
u8 md5_file[16];
|
u8 md5_file[16];
|
||||||
u8 md5_calc[16];
|
u8 md5_calc[16];
|
||||||
memcpy(md5_file, _header.hdr.Md5, 0x10);
|
memcpy(md5_file, m_header.hdr.Md5, 0x10);
|
||||||
memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10);
|
memcpy(m_header.hdr.Md5, s_md5_blanker, 0x10);
|
||||||
md5((u8*)&_header, HEADER_SZ, md5_calc);
|
md5((u8*)&m_header, HEADER_SZ, md5_calc);
|
||||||
if (memcmp(md5_file, md5_calc, 0x10))
|
if (memcmp(md5_file, md5_calc, 0x10))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "MD5 mismatch\n %016" PRIx64 "%016" PRIx64 " != %016" PRIx64 "%016" PRIx64, Common::swap64(md5_file),Common::swap64(md5_file+8), Common::swap64(md5_calc), Common::swap64(md5_calc+8));
|
ERROR_LOG(CONSOLE, "MD5 mismatch\n %016" PRIx64 "%016" PRIx64 " != %016" PRIx64 "%016" PRIx64,
|
||||||
b_valid= false;
|
Common::swap64(md5_file),Common::swap64(md5_file + 8), Common::swap64(md5_calc),
|
||||||
|
Common::swap64(md5_calc + 8));
|
||||||
|
m_valid= false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!getPaths())
|
if (!getPaths())
|
||||||
{
|
{
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::string BannerFilePath = WiiTitlePath + "banner.bin";
|
std::string banner_file_path = m_wii_title_path + "banner.bin";
|
||||||
if (!File::Exists(BannerFilePath) || AskYesNoT("%s already exists, overwrite?", BannerFilePath.c_str()))
|
if (!File::Exists(banner_file_path) ||
|
||||||
|
AskYesNoT("%s already exists, overwrite?", banner_file_path.c_str()))
|
||||||
{
|
{
|
||||||
INFO_LOG(CONSOLE, "Creating file %s", BannerFilePath.c_str());
|
INFO_LOG(CONSOLE, "Creating file %s", banner_file_path.c_str());
|
||||||
File::IOFile fpBanner_bin(BannerFilePath, "wb");
|
File::IOFile banner_file(banner_file_path, "wb");
|
||||||
fpBanner_bin.WriteBytes(_header.BNR, bannerSize);
|
banner_file.WriteBytes(m_header.BNR, banner_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWiiSaveCrypted::WriteHDR()
|
void CWiiSaveCrypted::WriteHDR()
|
||||||
{
|
{
|
||||||
if (!b_valid) return;
|
if (!m_valid) return;
|
||||||
memset(&_header, 0, HEADER_SZ);
|
memset(&m_header, 0, HEADER_SZ);
|
||||||
|
|
||||||
std::string BannerFilePath = WiiTitlePath + "banner.bin";
|
std::string banner_file_path = m_wii_title_path + "banner.bin";
|
||||||
u32 bannerSize = File::GetSize(BannerFilePath);
|
u32 banner_size = static_cast<u32>(File::GetSize(banner_file_path));
|
||||||
_header.hdr.BannerSize = Common::swap32(bannerSize);
|
m_header.hdr.BannerSize = Common::swap32(banner_size);
|
||||||
|
|
||||||
_header.hdr.SaveGameTitle = Common::swap64(m_TitleID);
|
m_header.hdr.SaveGameTitle = Common::swap64(m_title_id);
|
||||||
memcpy(_header.hdr.Md5, MD5_BLANKER, 0x10);
|
memcpy(m_header.hdr.Md5, s_md5_blanker, 0x10);
|
||||||
_header.hdr.Permissions = 0x3C;
|
m_header.hdr.Permissions = 0x3C;
|
||||||
|
|
||||||
File::IOFile fpBanner_bin(BannerFilePath, "rb");
|
File::IOFile banner_file(banner_file_path, "rb");
|
||||||
if (!fpBanner_bin.ReadBytes(_header.BNR, bannerSize))
|
if (!banner_file.ReadBytes(m_header.BNR, banner_size))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Failed to read banner.bin");
|
ERROR_LOG(CONSOLE, "Failed to read banner.bin");
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// remove nocopy flag
|
// remove nocopy flag
|
||||||
_header.BNR[7] &= ~1;
|
m_header.BNR[7] &= ~1;
|
||||||
|
|
||||||
u8 md5_calc[16];
|
u8 md5_calc[16];
|
||||||
md5((u8*)&_header, HEADER_SZ, md5_calc);
|
md5((u8*)&m_header, HEADER_SZ, md5_calc);
|
||||||
memcpy(_header.hdr.Md5, md5_calc, 0x10);
|
memcpy(m_header.hdr.Md5, md5_calc, 0x10);
|
||||||
|
|
||||||
aes_crypt_cbc(&m_AES_ctx, AES_ENCRYPT, HEADER_SZ, SD_IV, (const u8*)&_header, (u8*)&_encryptedHeader);
|
aes_crypt_cbc(&m_aes_ctx, AES_ENCRYPT, HEADER_SZ, m_sd_iv, (const u8*)&m_header,
|
||||||
|
(u8*)&m_encrypted_header);
|
||||||
|
|
||||||
File::IOFile fpData_bin(encryptedSavePath, "wb");
|
File::IOFile data_file(m_encrypted_save_path, "wb");
|
||||||
if (!fpData_bin.WriteBytes(&_encryptedHeader, HEADER_SZ))
|
if (!data_file.WriteBytes(&m_encrypted_header, HEADER_SZ))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Failed to write header for %s", encryptedSavePath.c_str());
|
ERROR_LOG(CONSOLE, "Failed to write header for %s", m_encrypted_save_path.c_str());
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,135 +240,141 @@ void CWiiSaveCrypted::WriteHDR()
|
||||||
|
|
||||||
void CWiiSaveCrypted::ReadBKHDR()
|
void CWiiSaveCrypted::ReadBKHDR()
|
||||||
{
|
{
|
||||||
if (!b_valid) return;
|
if (!m_valid) return;
|
||||||
|
|
||||||
File::IOFile fpData_bin(encryptedSavePath, "rb");
|
File::IOFile fpData_bin(m_encrypted_save_path, "rb");
|
||||||
if (!fpData_bin)
|
if (!fpData_bin)
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Cannot open %s", encryptedSavePath.c_str());
|
ERROR_LOG(CONSOLE, "Cannot open %s", m_encrypted_save_path.c_str());
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fpData_bin.Seek(HEADER_SZ, SEEK_SET);
|
fpData_bin.Seek(HEADER_SZ, SEEK_SET);
|
||||||
if (!fpData_bin.ReadBytes(&bkhdr, BK_SZ))
|
if (!fpData_bin.ReadBytes(&m_bk_hdr, BK_SZ))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Failed to read bk header");
|
ERROR_LOG(CONSOLE, "Failed to read bk header");
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fpData_bin.Close();
|
fpData_bin.Close();
|
||||||
|
|
||||||
if (bkhdr.size != Common::swap32(BK_LISTED_SZ) ||
|
if (m_bk_hdr.size != Common::swap32(BK_LISTED_SZ) ||
|
||||||
bkhdr.magic != Common::swap32(BK_HDR_MAGIC))
|
m_bk_hdr.magic != Common::swap32(BK_HDR_MAGIC))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Invalid Size(%x) or Magic word (%x)", bkhdr.size, bkhdr.magic);
|
ERROR_LOG(CONSOLE, "Invalid Size(%x) or Magic word (%x)", m_bk_hdr.size, m_bk_hdr.magic);
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_numberOfFiles = Common::swap32(bkhdr.numberOfFiles);
|
m_files_list_size = Common::swap32(m_bk_hdr.numberOfFiles);
|
||||||
_sizeOfFiles = Common::swap32(bkhdr.sizeOfFiles);
|
m_size_of_files = Common::swap32(m_bk_hdr.sizeOfFiles);
|
||||||
_totalSize = Common::swap32(bkhdr.totalSize);
|
m_total_size = Common::swap32(m_bk_hdr.totalSize);
|
||||||
|
|
||||||
if (_sizeOfFiles + FULL_CERT_SZ != _totalSize)
|
if (m_size_of_files + FULL_CERT_SZ != m_total_size)
|
||||||
WARN_LOG(CONSOLE, "Size(%x) + cert(%x) does not equal totalsize(%x)", _sizeOfFiles, FULL_CERT_SZ, _totalSize);
|
{
|
||||||
if (m_TitleID != Common::swap64(bkhdr.SaveGameTitle))
|
WARN_LOG(CONSOLE, "Size(%x) + cert(%x) does not equal totalsize(%x)", m_size_of_files,
|
||||||
WARN_LOG(CONSOLE, "Encrypted title (%" PRIx64 ") does not match unencrypted title (%" PRIx64 ")", m_TitleID, Common::swap64(bkhdr.SaveGameTitle));
|
FULL_CERT_SZ, m_total_size);
|
||||||
|
}
|
||||||
|
if (m_title_id != Common::swap64(m_bk_hdr.SaveGameTitle))
|
||||||
|
{
|
||||||
|
WARN_LOG(CONSOLE, "Encrypted title (%" PRIx64 ") does not match unencrypted title (%" PRIx64 ")",
|
||||||
|
m_title_id, Common::swap64(m_bk_hdr.SaveGameTitle));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWiiSaveCrypted::WriteBKHDR()
|
void CWiiSaveCrypted::WriteBKHDR()
|
||||||
{
|
{
|
||||||
if (!b_valid) return;
|
if (!m_valid) return;
|
||||||
_numberOfFiles = 0;
|
m_files_list_size = 0;
|
||||||
_sizeOfFiles = 0;
|
m_size_of_files = 0;
|
||||||
|
|
||||||
ScanForFiles(WiiTitlePath, FilesList, &_numberOfFiles, &_sizeOfFiles);
|
ScanForFiles(m_wii_title_path, m_files_list, &m_files_list_size, &m_size_of_files);
|
||||||
memset(&bkhdr, 0, BK_SZ);
|
memset(&m_bk_hdr, 0, BK_SZ);
|
||||||
bkhdr.size = Common::swap32(BK_LISTED_SZ);
|
m_bk_hdr.size = Common::swap32(BK_LISTED_SZ);
|
||||||
bkhdr.magic = Common::swap32(BK_HDR_MAGIC);
|
m_bk_hdr.magic = Common::swap32(BK_HDR_MAGIC);
|
||||||
bkhdr.NGid = NG_id;
|
m_bk_hdr.NGid = s_ng_id;
|
||||||
bkhdr.numberOfFiles = Common::swap32(_numberOfFiles);
|
m_bk_hdr.numberOfFiles = Common::swap32(m_files_list_size);
|
||||||
bkhdr.sizeOfFiles = Common::swap32(_sizeOfFiles);
|
m_bk_hdr.sizeOfFiles = Common::swap32(m_size_of_files);
|
||||||
bkhdr.totalSize = Common::swap32(_sizeOfFiles + FULL_CERT_SZ);
|
m_bk_hdr.totalSize = Common::swap32(m_size_of_files + FULL_CERT_SZ);
|
||||||
bkhdr.SaveGameTitle = Common::swap64(m_TitleID);
|
m_bk_hdr.SaveGameTitle = Common::swap64(m_title_id);
|
||||||
|
|
||||||
File::IOFile fpData_bin(encryptedSavePath, "ab");
|
File::IOFile data_file(m_encrypted_save_path, "ab");
|
||||||
if (!fpData_bin.WriteBytes(&bkhdr, BK_SZ))
|
if (!data_file.WriteBytes(&m_bk_hdr, BK_SZ))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Failed to write bkhdr");
|
ERROR_LOG(CONSOLE, "Failed to write bkhdr");
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWiiSaveCrypted::ImportWiiSaveFiles()
|
void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||||
{
|
{
|
||||||
if (!b_valid) return;
|
if (!m_valid) return;
|
||||||
|
|
||||||
File::IOFile fpData_bin(encryptedSavePath, "rb");
|
File::IOFile data_file(m_encrypted_save_path, "rb");
|
||||||
if (!fpData_bin)
|
if (!data_file)
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Cannot open %s", encryptedSavePath.c_str());
|
ERROR_LOG(CONSOLE, "Cannot open %s", m_encrypted_save_path.c_str());
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fpData_bin.Seek(HEADER_SZ + BK_SZ, SEEK_SET);
|
data_file.Seek(HEADER_SZ + BK_SZ, SEEK_SET);
|
||||||
|
|
||||||
|
FileHDR file_hdr_tmp;
|
||||||
|
|
||||||
FileHDR _tmpFileHDR;
|
for (u32 i = 0; i < m_files_list_size; ++i)
|
||||||
|
|
||||||
for (u32 i = 0; i < _numberOfFiles; ++i)
|
|
||||||
{
|
{
|
||||||
memset(&_tmpFileHDR, 0, FILE_HDR_SZ);
|
memset(&file_hdr_tmp, 0, FILE_HDR_SZ);
|
||||||
memset(IV, 0, 0x10);
|
memset(m_iv, 0, 0x10);
|
||||||
u32 _fileSize = 0;
|
u32 file_size = 0;
|
||||||
|
|
||||||
if (!fpData_bin.ReadBytes(&_tmpFileHDR, FILE_HDR_SZ))
|
if (!data_file.ReadBytes(&file_hdr_tmp, FILE_HDR_SZ))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Failed to read header for file %d", i);
|
ERROR_LOG(CONSOLE, "Failed to read header for file %d", i);
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Common::swap32(_tmpFileHDR.magic) != FILE_HDR_MAGIC)
|
if (Common::swap32(file_hdr_tmp.magic) != FILE_HDR_MAGIC)
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Bad File Header");
|
ERROR_LOG(CONSOLE, "Bad File Header");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string fileName ((char*)_tmpFileHDR.name);
|
std::string filename((char*)file_hdr_tmp.name);
|
||||||
for (Common::replace_v::const_iterator iter = replacements.begin(); iter != replacements.end(); ++iter)
|
for (const Common::replace_t& replacement : replacements)
|
||||||
{
|
{
|
||||||
for (size_t j = 0; (j = fileName.find(iter->first, j)) != fileName.npos; ++j)
|
for (size_t j = 0; (j = filename.find(replacement.first, j)) != filename.npos; ++j)
|
||||||
fileName.replace(j, 1, iter->second);
|
filename.replace(j, 1, replacement.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string fullFilePath = WiiTitlePath + fileName;
|
std::string file_path_full = m_wii_title_path + filename;
|
||||||
File::CreateFullPath(fullFilePath);
|
File::CreateFullPath(file_path_full);
|
||||||
if (_tmpFileHDR.type == 1)
|
if (file_hdr_tmp.type == 1)
|
||||||
{
|
{
|
||||||
_fileSize = Common::swap32(_tmpFileHDR.size);
|
file_size = Common::swap32(file_hdr_tmp.size);
|
||||||
u32 RoundedFileSize = ROUND_UP(_fileSize, BLOCK_SZ);
|
u32 file_size_rounded = ROUND_UP(file_size, BLOCK_SZ);
|
||||||
std::vector<u8> _data,_encryptedData;
|
std::vector<u8> file_data, file_data_enc;
|
||||||
_data.reserve(RoundedFileSize);
|
file_data.reserve(file_size_rounded);
|
||||||
_encryptedData.reserve(RoundedFileSize);
|
file_data_enc.reserve(file_size_rounded);
|
||||||
if (!fpData_bin.ReadBytes(&_encryptedData[0], RoundedFileSize))
|
if (!data_file.ReadBytes(&file_data_enc[0], file_size_rounded))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Failed to read data from file %d", i);
|
ERROR_LOG(CONSOLE, "Failed to read data from file %d", i);
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(m_iv, file_hdr_tmp.IV, 0x10);
|
||||||
|
aes_crypt_cbc(&m_aes_ctx, AES_DECRYPT, file_size_rounded, m_iv,
|
||||||
|
(const u8*)&file_data_enc[0], &file_data[0]);
|
||||||
|
|
||||||
memcpy(IV, _tmpFileHDR.IV, 0x10);
|
if (!File::Exists(file_path_full) ||
|
||||||
aes_crypt_cbc(&m_AES_ctx, AES_DECRYPT, RoundedFileSize, IV, (const u8*)&_encryptedData[0], &_data[0]);
|
AskYesNoT("%s already exists, overwrite?", file_path_full.c_str()))
|
||||||
|
|
||||||
if (!File::Exists(fullFilePath) || AskYesNoT("%s already exists, overwrite?", fullFilePath.c_str()))
|
|
||||||
{
|
{
|
||||||
INFO_LOG(CONSOLE, "Creating file %s", fullFilePath.c_str());
|
INFO_LOG(CONSOLE, "Creating file %s", file_path_full.c_str());
|
||||||
|
|
||||||
File::IOFile fpRawSaveFile(fullFilePath, "wb");
|
File::IOFile raw_save_file(file_path_full, "wb");
|
||||||
fpRawSaveFile.WriteBytes(&_data[0], _fileSize);
|
raw_save_file.WriteBytes(&file_data[0], file_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -367,93 +383,95 @@ void CWiiSaveCrypted::ImportWiiSaveFiles()
|
||||||
|
|
||||||
void CWiiSaveCrypted::ExportWiiSaveFiles()
|
void CWiiSaveCrypted::ExportWiiSaveFiles()
|
||||||
{
|
{
|
||||||
if (!b_valid) return;
|
if (!m_valid) return;
|
||||||
|
|
||||||
for (u32 i = 0; i < _numberOfFiles; i++)
|
for (u32 i = 0; i < m_files_list_size; i++)
|
||||||
{
|
{
|
||||||
FileHDR tmpFileHDR;
|
FileHDR file_hdr_tmp;
|
||||||
std::string __name;
|
std::string name;
|
||||||
memset(&tmpFileHDR, 0, FILE_HDR_SZ);
|
memset(&file_hdr_tmp, 0, FILE_HDR_SZ);
|
||||||
|
|
||||||
u32 _fileSize = 0;
|
u32 file_size = 0;
|
||||||
if (File::IsDirectory(FilesList[i]))
|
if (File::IsDirectory(m_files_list[i]))
|
||||||
{
|
{
|
||||||
tmpFileHDR.type = 2;
|
file_hdr_tmp.type = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_fileSize = File::GetSize(FilesList[i]);
|
file_size = static_cast<u32>(File::GetSize(m_files_list[i]));
|
||||||
tmpFileHDR.type = 1;
|
file_hdr_tmp.type = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 _roundedfileSize = ROUND_UP(_fileSize, BLOCK_SZ);
|
u32 file_size_rounded = ROUND_UP(file_size, BLOCK_SZ);
|
||||||
tmpFileHDR.magic = Common::swap32(FILE_HDR_MAGIC);
|
file_hdr_tmp.magic = Common::swap32(FILE_HDR_MAGIC);
|
||||||
tmpFileHDR.size = Common::swap32(_fileSize);
|
file_hdr_tmp.size = Common::swap32(file_size);
|
||||||
tmpFileHDR.Permissions = 0x3c;
|
file_hdr_tmp.Permissions = 0x3c;
|
||||||
|
|
||||||
__name = FilesList[i].substr(WiiTitlePath.length()+1);
|
|
||||||
|
|
||||||
|
name = m_files_list[i].substr(m_wii_title_path.length() + 1);
|
||||||
|
|
||||||
for (const Common::replace_t& repl : replacements)
|
for (const Common::replace_t& repl : replacements)
|
||||||
{
|
{
|
||||||
for (size_t j = 0; (j = __name.find(repl.second, j)) != __name.npos; ++j)
|
for (size_t j = 0; (j = name.find(repl.second, j)) != name.npos; ++j)
|
||||||
{
|
{
|
||||||
__name.replace(j, repl.second.length(), 1, repl.first);
|
name.replace(j, repl.second.length(), 1, repl.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__name.length() > 0x44)
|
if (name.length() > 0x44)
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "\"%s\" is too long for the filename, max length is 0x44 + \\0", __name.c_str());
|
ERROR_LOG(CONSOLE, "\"%s\" is too long for the filename, max length is 0x44 + \\0", name.c_str());
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
strncpy((char *)tmpFileHDR.name, __name.c_str(), sizeof(tmpFileHDR.name));
|
strncpy((char *)file_hdr_tmp.name, name.c_str(), sizeof(file_hdr_tmp.name));
|
||||||
|
|
||||||
{
|
{
|
||||||
File::IOFile fpData_bin(encryptedSavePath, "ab");
|
File::IOFile fpData_bin(m_encrypted_save_path, "ab");
|
||||||
fpData_bin.WriteBytes(&tmpFileHDR, FILE_HDR_SZ);
|
fpData_bin.WriteBytes(&file_hdr_tmp, FILE_HDR_SZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmpFileHDR.type == 1)
|
if (file_hdr_tmp.type == 1)
|
||||||
{
|
{
|
||||||
if (_fileSize == 0)
|
if (file_size == 0)
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "%s is a 0 byte file", FilesList[i].c_str());
|
ERROR_LOG(CONSOLE, "%s is a 0 byte file", m_files_list[i].c_str());
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
File::IOFile fpRawSaveFile(FilesList[i], "rb");
|
File::IOFile raw_save_file(m_files_list[i], "rb");
|
||||||
if (!fpRawSaveFile)
|
if (!raw_save_file)
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "%s failed to open", FilesList[i].c_str());
|
ERROR_LOG(CONSOLE, "%s failed to open", m_files_list[i].c_str());
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<u8> _data,_encryptedData;
|
std::vector<u8> file_data, file_data_enc;
|
||||||
_data.reserve(_roundedfileSize);
|
file_data.reserve(file_size_rounded);
|
||||||
_encryptedData.reserve(_roundedfileSize);
|
file_data_enc.reserve(file_size_rounded);
|
||||||
memset(&_data[0], 0, _roundedfileSize);
|
memset(&file_data[0], 0, file_size_rounded);
|
||||||
if (!fpRawSaveFile.ReadBytes(&_data[0], _fileSize))
|
if (!raw_save_file.ReadBytes(&file_data[0], file_size))
|
||||||
{
|
{
|
||||||
ERROR_LOG(CONSOLE, "Failed to read data from file: %s", FilesList[i].c_str());
|
ERROR_LOG(CONSOLE, "Failed to read data from file: %s",
|
||||||
b_valid = false;
|
m_files_list[i].c_str());
|
||||||
|
m_valid = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
aes_crypt_cbc(&m_AES_ctx, AES_ENCRYPT, _roundedfileSize, tmpFileHDR.IV, (const u8*)&_data[0], &_encryptedData[0]);
|
aes_crypt_cbc(&m_aes_ctx, AES_ENCRYPT, file_size_rounded,
|
||||||
|
file_hdr_tmp.IV, (const u8*)&file_data[0], &file_data_enc[0]);
|
||||||
File::IOFile fpData_bin(encryptedSavePath, "ab");
|
|
||||||
if (!fpData_bin.WriteBytes(&_encryptedData[0], _roundedfileSize))
|
|
||||||
ERROR_LOG(CONSOLE, "Failed to write data to file: %s", encryptedSavePath.c_str());
|
|
||||||
|
|
||||||
|
|
||||||
|
File::IOFile fpData_bin(m_encrypted_save_path, "ab");
|
||||||
|
if (!fpData_bin.WriteBytes(&file_data_enc[0], file_size_rounded))
|
||||||
|
{
|
||||||
|
ERROR_LOG(CONSOLE, "Failed to write data to file: %s",
|
||||||
|
m_encrypted_save_path.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWiiSaveCrypted::do_sig()
|
void CWiiSaveCrypted::do_sig()
|
||||||
{
|
{
|
||||||
if (!b_valid) return;
|
if (!m_valid) return;
|
||||||
u8 sig[0x40];
|
u8 sig[0x40];
|
||||||
u8 ng_cert[0x180];
|
u8 ng_cert[0x180];
|
||||||
u8 ap_cert[0x180];
|
u8 ap_cert[0x180];
|
||||||
|
@ -462,17 +480,16 @@ void CWiiSaveCrypted::do_sig()
|
||||||
u8 ap_sig[60];
|
u8 ap_sig[60];
|
||||||
char signer[64];
|
char signer[64];
|
||||||
char name[64];
|
char name[64];
|
||||||
u8 *data;
|
|
||||||
u32 data_size;
|
u32 data_size;
|
||||||
|
|
||||||
u32 NG_key_id = 0x6AAB8C59;
|
const u32 ng_key_id = 0x6AAB8C59;
|
||||||
|
|
||||||
u8 NG_priv[30] = {
|
const u8 ng_priv[30] = {
|
||||||
0, 0xAB, 0xEE, 0xC1, 0xDD, 0xB4, 0xA6, 0x16, 0x6B, 0x70, 0xFD, 0x7E, 0x56, 0x67, 0x70,
|
0, 0xAB, 0xEE, 0xC1, 0xDD, 0xB4, 0xA6, 0x16, 0x6B, 0x70, 0xFD, 0x7E, 0x56, 0x67, 0x70,
|
||||||
0x57, 0x55, 0x27, 0x38, 0xA3, 0x26, 0xC5, 0x46, 0x16, 0xF7, 0x62, 0xC9, 0xED, 0x73, 0xF2
|
0x57, 0x55, 0x27, 0x38, 0xA3, 0x26, 0xC5, 0x46, 0x16, 0xF7, 0x62, 0xC9, 0xED, 0x73, 0xF2
|
||||||
};
|
};
|
||||||
|
|
||||||
u8 NG_sig[0x3C] = {
|
const u8 ng_sig[0x3C] = {
|
||||||
0, 0xD8, 0x81, 0x63, 0xB2, 0x00, 0x6B, 0x0B, 0x54, 0x82, 0x88, 0x63, 0x81, 0x1C, 0x00,
|
0, 0xD8, 0x81, 0x63, 0xB2, 0x00, 0x6B, 0x0B, 0x54, 0x82, 0x88, 0x63, 0x81, 0x1C, 0x00,
|
||||||
0x71, 0x12, 0xED, 0xB7, 0xFD, 0x21, 0xAB, 0x0E, 0x50, 0x0E, 0x1F, 0xBF, 0x78, 0xAD, 0x37,
|
0x71, 0x12, 0xED, 0xB7, 0xFD, 0x21, 0xAB, 0x0E, 0x50, 0x0E, 0x1F, 0xBF, 0x78, 0xAD, 0x37,
|
||||||
0x00, 0x71, 0x8D, 0x82, 0x41, 0xEE, 0x45, 0x11, 0xC7, 0x3B, 0xAC, 0x08, 0xB6, 0x83, 0xDC,
|
0x00, 0x71, 0x8D, 0x82, 0x41, 0xEE, 0x45, 0x11, 0xC7, 0x3B, 0xAC, 0x08, 0xB6, 0x83, 0xDC,
|
||||||
|
@ -480,8 +497,8 @@ void CWiiSaveCrypted::do_sig()
|
||||||
};
|
};
|
||||||
|
|
||||||
sprintf(signer, "Root-CA00000001-MS00000002");
|
sprintf(signer, "Root-CA00000001-MS00000002");
|
||||||
sprintf(name, "NG%08x", NG_id);
|
sprintf(name, "NG%08x", s_ng_id);
|
||||||
make_ec_cert(ng_cert, NG_sig, signer, name, NG_priv, NG_key_id);
|
make_ec_cert(ng_cert, ng_sig, signer, name, ng_priv, ng_key_id);
|
||||||
|
|
||||||
|
|
||||||
memset(ap_priv, 0, sizeof ap_priv);
|
memset(ap_priv, 0, sizeof ap_priv);
|
||||||
|
@ -489,53 +506,52 @@ void CWiiSaveCrypted::do_sig()
|
||||||
|
|
||||||
memset(ap_sig, 81, sizeof ap_sig); // temp
|
memset(ap_sig, 81, sizeof ap_sig); // temp
|
||||||
|
|
||||||
sprintf(signer, "Root-CA00000001-MS00000002-NG%08x", NG_id);
|
sprintf(signer, "Root-CA00000001-MS00000002-NG%08x", s_ng_id);
|
||||||
sprintf(name, "AP%08x%08x", 1, 2);
|
sprintf(name, "AP%08x%08x", 1, 2);
|
||||||
make_ec_cert(ap_cert, ap_sig, signer, name, ap_priv, 0);
|
make_ec_cert(ap_cert, ap_sig, signer, name, ap_priv, 0);
|
||||||
|
|
||||||
sha1(ap_cert + 0x80, 0x100, hash);
|
sha1(ap_cert + 0x80, 0x100, hash);
|
||||||
generate_ecdsa(ap_sig, ap_sig + 30, NG_priv, hash);
|
generate_ecdsa(ap_sig, ap_sig + 30, ng_priv, hash);
|
||||||
make_ec_cert(ap_cert, ap_sig, signer, name, ap_priv, 0);
|
make_ec_cert(ap_cert, ap_sig, signer, name, ap_priv, 0);
|
||||||
|
|
||||||
data_size = Common::swap32(bkhdr.sizeOfFiles) + 0x80;
|
data_size = Common::swap32(m_bk_hdr.sizeOfFiles) + 0x80;
|
||||||
|
|
||||||
File::IOFile fpData_bin(encryptedSavePath, "rb");
|
File::IOFile data_file(m_encrypted_save_path, "rb");
|
||||||
if (!fpData_bin)
|
if (!data_file)
|
||||||
{
|
{
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
data = new u8[data_size];
|
auto data = std::make_unique<u8[]>(data_size);
|
||||||
|
|
||||||
fpData_bin.Seek(0xf0c0, SEEK_SET);
|
data_file.Seek(0xf0c0, SEEK_SET);
|
||||||
if (!fpData_bin.ReadBytes(data, data_size))
|
if (!data_file.ReadBytes(data.get(), data_size))
|
||||||
{
|
{
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sha1(data, data_size, hash);
|
sha1(data.get(), data_size, hash);
|
||||||
sha1(hash, 20, hash);
|
sha1(hash, 20, hash);
|
||||||
delete []data;
|
|
||||||
|
|
||||||
fpData_bin.Open(encryptedSavePath, "ab");
|
data_file.Open(m_encrypted_save_path, "ab");
|
||||||
if (!fpData_bin)
|
if (!data_file)
|
||||||
{
|
{
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
generate_ecdsa(sig, sig + 30, ap_priv, hash);
|
generate_ecdsa(sig, sig + 30, ap_priv, hash);
|
||||||
*(u32*)(sig + 60) = Common::swap32(0x2f536969);
|
*(u32*)(sig + 60) = Common::swap32(0x2f536969);
|
||||||
|
|
||||||
fpData_bin.WriteArray(sig, sizeof(sig));
|
data_file.WriteArray(sig, sizeof(sig));
|
||||||
fpData_bin.WriteArray(ng_cert, sizeof(ng_cert));
|
data_file.WriteArray(ng_cert, sizeof(ng_cert));
|
||||||
fpData_bin.WriteArray(ap_cert, sizeof(ap_cert));
|
data_file.WriteArray(ap_cert, sizeof(ap_cert));
|
||||||
|
|
||||||
b_valid = fpData_bin.IsGood();
|
m_valid = data_file.IsGood();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWiiSaveCrypted::make_ec_cert(u8 *cert, const u8 *sig, const char *signer, const char *name,
|
||||||
void CWiiSaveCrypted::make_ec_cert(u8 *cert, u8 *sig, char *signer, char *name, u8 *priv, u32 key_id)
|
const u8 *priv, const u32 key_id)
|
||||||
{
|
{
|
||||||
memset(cert, 0, 0x180);
|
memset(cert, 0, 0x180);
|
||||||
*(u32*)cert = Common::swap32(0x10002);
|
*(u32*)cert = Common::swap32(0x10002);
|
||||||
|
@ -548,90 +564,101 @@ void CWiiSaveCrypted::make_ec_cert(u8 *cert, u8 *sig, char *signer, char *name,
|
||||||
ec_priv_to_pub(priv, cert + 0x108);
|
ec_priv_to_pub(priv, cert + 0x108);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWiiSaveCrypted::getPaths(bool forExport)
|
bool CWiiSaveCrypted::getPaths(bool for_export)
|
||||||
{
|
{
|
||||||
if (m_TitleID)
|
if (m_title_id)
|
||||||
{
|
{
|
||||||
WiiTitlePath = Common::GetTitleDataPath(m_TitleID);
|
m_wii_title_path = Common::GetTitleDataPath(m_title_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forExport)
|
if (for_export)
|
||||||
{
|
{
|
||||||
char GameID[5];
|
char game_id[5];
|
||||||
sprintf(GameID, "%c%c%c%c",
|
sprintf(game_id, "%c%c%c%c",
|
||||||
(u8)(m_TitleID >> 24) & 0xFF, (u8)(m_TitleID >> 16) & 0xFF,
|
(u8)(m_title_id >> 24) & 0xFF, (u8)(m_title_id >> 16) & 0xFF,
|
||||||
(u8)(m_TitleID >> 8) & 0xFF, (u8)m_TitleID & 0xFF);
|
(u8)(m_title_id >> 8) & 0xFF, (u8)m_title_id & 0xFF);
|
||||||
|
|
||||||
if (!File::IsDirectory(WiiTitlePath))
|
if (!File::IsDirectory(m_wii_title_path))
|
||||||
{
|
{
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
ERROR_LOG(CONSOLE, "No save folder found for title %s", GameID);
|
ERROR_LOG(CONSOLE, "No save folder found for title %s", game_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!File::Exists(WiiTitlePath + "banner.bin"))
|
if (!File::Exists(m_wii_title_path + "banner.bin"))
|
||||||
{
|
{
|
||||||
b_valid = false;
|
m_valid = false;
|
||||||
ERROR_LOG(CONSOLE, "No banner file found for title %s", GameID);
|
ERROR_LOG(CONSOLE, "No banner file found for title %s", game_id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (encryptedSavePath.length() == 0)
|
if (m_encrypted_save_path.length() == 0)
|
||||||
{
|
{
|
||||||
encryptedSavePath = File::GetUserPath(D_USER_IDX); // If no path was passed, use User folder
|
// If no path was passed, use User folder
|
||||||
|
m_encrypted_save_path = File::GetUserPath(D_USER_IDX);
|
||||||
}
|
}
|
||||||
encryptedSavePath += StringFromFormat("private/wii/title/%s/data.bin", GameID);
|
m_encrypted_save_path += StringFromFormat("private/wii/title/%s/data.bin", game_id);
|
||||||
File::CreateFullPath(encryptedSavePath);
|
File::CreateFullPath(m_encrypted_save_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
File::CreateFullPath(WiiTitlePath);
|
File::CreateFullPath(m_wii_title_path);
|
||||||
if (!AskYesNoT("Warning! it is advised to backup all files in the folder:\n%s\nDo you wish to continue?", WiiTitlePath.c_str()))
|
if (!AskYesNoT(
|
||||||
|
"Warning! it is advised to backup all files in the folder:\n%s\nDo you wish to continue?",
|
||||||
|
m_wii_title_path.c_str()))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWiiSaveCrypted::ScanForFiles(std::string savDir, std::vector<std::string>& FileList, u32 *_numFiles, u32 *_sizeFiles)
|
void CWiiSaveCrypted::ScanForFiles(std::string save_directory, std::vector<std::string>& file_list,
|
||||||
|
u32 *num_files, u32 *size_files)
|
||||||
{
|
{
|
||||||
std::vector<std::string> Directories;
|
std::vector<std::string> directories;
|
||||||
*_numFiles = *_sizeFiles = 0;
|
directories.push_back(save_directory);
|
||||||
|
u32 num = 0;
|
||||||
|
u32 size = 0;
|
||||||
|
|
||||||
Directories.push_back(savDir);
|
for (u32 i = 0; i < directories.size(); ++i)
|
||||||
for (u32 i = 0; i < Directories.size(); ++i)
|
|
||||||
{
|
{
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
FileList.push_back(Directories[i]);//add dir to fst
|
// add dir to fst
|
||||||
|
file_list.push_back(directories[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
File::FSTEntry FST_Temp;
|
File::FSTEntry fst_tmp;
|
||||||
File::ScanDirectoryTree(Directories[i], FST_Temp);
|
File::ScanDirectoryTree(directories[i], fst_tmp);
|
||||||
for (const File::FSTEntry& elem : FST_Temp.children)
|
for (const File::FSTEntry& elem : fst_tmp.children)
|
||||||
{
|
{
|
||||||
if (strncmp(elem.virtualName.c_str(), "banner.bin", 10) != 0)
|
if (strncmp(elem.virtualName.c_str(), "banner.bin", 10) != 0)
|
||||||
{
|
{
|
||||||
(*_numFiles)++;
|
num++;
|
||||||
*_sizeFiles += FILE_HDR_SZ;
|
size += FILE_HDR_SZ;
|
||||||
if (elem.isDirectory)
|
if (elem.isDirectory)
|
||||||
{
|
{
|
||||||
if ((elem.virtualName == "nocopy") || elem.virtualName == "nomove")
|
if ((elem.virtualName == "nocopy") || elem.virtualName == "nomove")
|
||||||
{
|
{
|
||||||
NOTICE_LOG(CONSOLE, "This save will likely require homebrew tools to copy to a real Wii.");
|
NOTICE_LOG(CONSOLE,
|
||||||
|
"This save will likely require homebrew tools to copy to a real Wii.");
|
||||||
}
|
}
|
||||||
|
|
||||||
Directories.push_back(elem.physicalName);
|
directories.push_back(elem.physicalName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FileList.push_back(elem.physicalName);
|
file_list.push_back(elem.physicalName);
|
||||||
*_sizeFiles += ROUND_UP(elem.size, BLOCK_SZ);
|
size += ROUND_UP(elem.size, BLOCK_SZ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*num_files = num;
|
||||||
|
*size_files = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
CWiiSaveCrypted::~CWiiSaveCrypted()
|
CWiiSaveCrypted::~CWiiSaveCrypted()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,49 +10,51 @@
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
// --- this is used for encrypted Wii save files
|
|
||||||
|
|
||||||
|
|
||||||
class CWiiSaveCrypted
|
class CWiiSaveCrypted
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool static ImportWiiSave(const char* FileName);
|
bool static ImportWiiSave(const char* filename);
|
||||||
bool static ExportWiiSave(u64 TitleID);
|
bool static ExportWiiSave(u64 title_id);
|
||||||
void static ExportAllSaves();
|
void static ExportAllSaves();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CWiiSaveCrypted(const char* FileName, u64 TitleID = 0);
|
CWiiSaveCrypted(const char* filename, u64 title_id = 0);
|
||||||
~CWiiSaveCrypted();
|
~CWiiSaveCrypted();
|
||||||
void ReadHDR();
|
void ReadHDR();
|
||||||
void ReadBKHDR();
|
void ReadBKHDR();
|
||||||
void WriteHDR();
|
void WriteHDR();
|
||||||
void WriteBKHDR();
|
void WriteBKHDR();
|
||||||
void Extract(){;}
|
void Extract(){}
|
||||||
void ImportWiiSaveFiles();
|
void ImportWiiSaveFiles();
|
||||||
void ExportWiiSaveFiles(); // To data.bin
|
void ExportWiiSaveFiles();
|
||||||
void do_sig();
|
void do_sig();
|
||||||
void make_ec_cert(u8 *cert, u8 *sig, char *signer, char *name, u8 *priv, u32 key_id);
|
void make_ec_cert(u8 *cert, const u8 *sig, const char *signer, const char *name,
|
||||||
bool getPaths(bool forExport = false);
|
const u8 *priv, const u32 key_id);
|
||||||
void ScanForFiles(std::string savDir, std::vector<std::string>&FilesList, u32 *_numFiles, u32 *_sizeFiles);
|
bool getPaths(bool for_export = false);
|
||||||
|
void ScanForFiles(std::string save_directory, std::vector<std::string>& file_list,
|
||||||
|
u32 *num_files, u32 *size_files);
|
||||||
|
|
||||||
aes_context m_AES_ctx;
|
static const u8 s_sd_key[16];
|
||||||
u8 SD_IV[0x10];
|
static const u8 s_md5_blanker[16];
|
||||||
std::vector<std::string> FilesList;
|
static const u32 s_ng_id;
|
||||||
|
|
||||||
std::string encryptedSavePath;
|
aes_context m_aes_ctx;
|
||||||
|
u8 m_sd_iv[0x10];
|
||||||
|
std::vector<std::string> m_files_list;
|
||||||
|
|
||||||
std::string WiiTitlePath;
|
std::string m_encrypted_save_path;
|
||||||
|
|
||||||
u8 IV[0x10];
|
std::string m_wii_title_path;
|
||||||
|
|
||||||
u32 //_bannerSize,
|
u8 m_iv[0x10];
|
||||||
_numberOfFiles,
|
|
||||||
_sizeOfFiles,
|
|
||||||
_totalSize;
|
|
||||||
|
|
||||||
u64 m_TitleID;
|
u32 m_files_list_size;
|
||||||
|
u32 m_size_of_files;
|
||||||
|
u32 m_total_size;
|
||||||
|
|
||||||
bool b_valid;
|
u64 m_title_id;
|
||||||
|
|
||||||
|
bool m_valid;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
@ -92,7 +94,7 @@ private:
|
||||||
{
|
{
|
||||||
Data_Bin_HDR hdr;
|
Data_Bin_HDR hdr;
|
||||||
u8 BNR[FULL_BNR_MAX];
|
u8 BNR[FULL_BNR_MAX];
|
||||||
}_header, _encryptedHeader;
|
};
|
||||||
|
|
||||||
struct BK_Header // Not encrypted
|
struct BK_Header // Not encrypted
|
||||||
{
|
{
|
||||||
|
@ -110,7 +112,7 @@ private:
|
||||||
u64 SaveGameTitle;
|
u64 SaveGameTitle;
|
||||||
u8 MACaddress[6];
|
u8 MACaddress[6];
|
||||||
u8 padding[0x12];
|
u8 padding[0x12];
|
||||||
}bkhdr;
|
};
|
||||||
|
|
||||||
struct FileHDR // encrypted
|
struct FileHDR // encrypted
|
||||||
{
|
{
|
||||||
|
@ -124,4 +126,8 @@ private:
|
||||||
u8 unk[0x20];
|
u8 unk[0x20];
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
HEADER m_header;
|
||||||
|
HEADER m_encrypted_header;
|
||||||
|
BK_Header m_bk_hdr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -125,7 +125,7 @@ public:
|
||||||
|
|
||||||
void SetValue(ControlState new_value) override
|
void SetValue(ControlState new_value) override
|
||||||
{
|
{
|
||||||
SConfig::GetInstance().m_BackgroundInput = new_value;
|
SConfig::GetInstance().m_BackgroundInput = !!new_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControlState GetValue() override
|
ControlState GetValue() override
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <wbemidl.h>
|
|
||||||
|
|
||||||
#include "InputCommon/ControllerInterface/DInput/DInput.h"
|
#include "InputCommon/ControllerInterface/DInput/DInput.h"
|
||||||
#include "InputCommon/ControllerInterface/DInput/DInputJoystick.h"
|
#include "InputCommon/ControllerInterface/DInput/DInputJoystick.h"
|
||||||
|
@ -17,109 +16,14 @@ namespace DInput
|
||||||
|
|
||||||
#define DATA_BUFFER_SIZE 32
|
#define DATA_BUFFER_SIZE 32
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
static const GUID s_known_xinput_guids[] = {
|
||||||
// Modified some MSDN code to get all the XInput device GUID.Data1 values in a vector,
|
// ValveStreamingGamepad
|
||||||
// faster than checking all the devices for each DirectInput device, like MSDN says to do
|
{ MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||||
//-----------------------------------------------------------------------------
|
// IID_X360WiredGamepad
|
||||||
void GetXInputGUIDS( std::vector<DWORD>& guids )
|
{ MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||||
{
|
// IID_X360WirelessGamepad
|
||||||
|
{ MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } },
|
||||||
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=nullptr; } }
|
};
|
||||||
|
|
||||||
IWbemLocator* pIWbemLocator = nullptr;
|
|
||||||
IEnumWbemClassObject* pEnumDevices = nullptr;
|
|
||||||
IWbemClassObject* pDevices[20] = {0};
|
|
||||||
IWbemServices* pIWbemServices = nullptr;
|
|
||||||
BSTR bstrNamespace = nullptr;
|
|
||||||
BSTR bstrDeviceID = nullptr;
|
|
||||||
BSTR bstrClassName = nullptr;
|
|
||||||
DWORD uReturned = 0;
|
|
||||||
VARIANT var;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
// CoInit if needed
|
|
||||||
hr = CoInitialize(nullptr);
|
|
||||||
bool bCleanupCOM = SUCCEEDED(hr);
|
|
||||||
|
|
||||||
// Create WMI
|
|
||||||
hr = CoCreateInstance(__uuidof(WbemLocator),
|
|
||||||
nullptr,
|
|
||||||
CLSCTX_INPROC_SERVER,
|
|
||||||
__uuidof(IWbemLocator),
|
|
||||||
(LPVOID*) &pIWbemLocator);
|
|
||||||
if (FAILED(hr) || pIWbemLocator == nullptr)
|
|
||||||
goto LCleanup;
|
|
||||||
|
|
||||||
bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == nullptr) goto LCleanup;
|
|
||||||
bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == nullptr) goto LCleanup;
|
|
||||||
bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == nullptr) goto LCleanup;
|
|
||||||
|
|
||||||
// Connect to WMI
|
|
||||||
hr = pIWbemLocator->ConnectServer(bstrNamespace, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &pIWbemServices);
|
|
||||||
if (FAILED(hr) || pIWbemServices == nullptr)
|
|
||||||
goto LCleanup;
|
|
||||||
|
|
||||||
// Switch security level to IMPERSONATE.
|
|
||||||
CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr,
|
|
||||||
RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE);
|
|
||||||
|
|
||||||
hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, nullptr, &pEnumDevices);
|
|
||||||
if (FAILED(hr) || pEnumDevices == nullptr)
|
|
||||||
goto LCleanup;
|
|
||||||
|
|
||||||
// Loop over all devices
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// Get 20 at a time
|
|
||||||
hr = pEnumDevices->Next(10000, 20, pDevices, &uReturned);
|
|
||||||
if (FAILED(hr) || uReturned == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (UINT iDevice = 0; iDevice < uReturned; ++iDevice)
|
|
||||||
{
|
|
||||||
// For each device, get its device ID
|
|
||||||
hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, nullptr, nullptr);
|
|
||||||
if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != nullptr)
|
|
||||||
{
|
|
||||||
// Check if the device ID contains "IG_". If it does, then it's an XInput device
|
|
||||||
// This information can not be found from DirectInput
|
|
||||||
if (wcsstr(var.bstrVal, L"IG_"))
|
|
||||||
{
|
|
||||||
// If it does, then get the VID/PID from var.bstrVal
|
|
||||||
DWORD dwPid = 0, dwVid = 0;
|
|
||||||
WCHAR* strVid = wcsstr(var.bstrVal, L"VID_");
|
|
||||||
if (strVid && swscanf(strVid, L"VID_%4X", &dwVid) != 1)
|
|
||||||
dwVid = 0;
|
|
||||||
WCHAR* strPid = wcsstr(var.bstrVal, L"PID_");
|
|
||||||
if (strPid && swscanf(strPid, L"PID_%4X", &dwPid) != 1)
|
|
||||||
dwPid = 0;
|
|
||||||
|
|
||||||
// Compare the VID/PID to the DInput device
|
|
||||||
DWORD dwVidPid = MAKELONG(dwVid, dwPid);
|
|
||||||
guids.push_back(dwVidPid);
|
|
||||||
//bIsXinputDevice = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SAFE_RELEASE(pDevices[iDevice]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LCleanup:
|
|
||||||
if (bstrNamespace)
|
|
||||||
SysFreeString(bstrNamespace);
|
|
||||||
if (bstrDeviceID)
|
|
||||||
SysFreeString(bstrDeviceID);
|
|
||||||
if (bstrClassName)
|
|
||||||
SysFreeString(bstrClassName);
|
|
||||||
for (UINT iDevice = 0; iDevice < 20; iDevice++)
|
|
||||||
SAFE_RELEASE(pDevices[iDevice]);
|
|
||||||
SAFE_RELEASE(pEnumDevices);
|
|
||||||
SAFE_RELEASE(pIWbemLocator);
|
|
||||||
SAFE_RELEASE(pIWbemServices);
|
|
||||||
|
|
||||||
if (bCleanupCOM)
|
|
||||||
CoUninitialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitJoystick(IDirectInput8* const idi8, std::vector<Core::Device*>& devices, HWND hwnd)
|
void InitJoystick(IDirectInput8* const idi8, std::vector<Core::Device*>& devices, HWND hwnd)
|
||||||
{
|
{
|
||||||
|
@ -130,14 +34,14 @@ void InitJoystick(IDirectInput8* const idi8, std::vector<Core::Device*>& devices
|
||||||
// multiple joysticks with the same name shall get unique ids starting at 0
|
// multiple joysticks with the same name shall get unique ids starting at 0
|
||||||
std::map< std::basic_string<TCHAR>, int> name_counts;
|
std::map< std::basic_string<TCHAR>, int> name_counts;
|
||||||
|
|
||||||
std::vector<DWORD> xinput_guids;
|
|
||||||
GetXInputGUIDS( xinput_guids );
|
|
||||||
|
|
||||||
for (DIDEVICEINSTANCE& joystick : joysticks)
|
for (DIDEVICEINSTANCE& joystick : joysticks)
|
||||||
{
|
{
|
||||||
// skip XInput Devices
|
// skip XInput Devices
|
||||||
if (std::find(xinput_guids.begin(), xinput_guids.end(), joystick.guidProduct.Data1) != xinput_guids.end())
|
if (std::find(std::begin(s_known_xinput_guids), std::end(s_known_xinput_guids),
|
||||||
|
joystick.guidProduct) != std::end(s_known_xinput_guids))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
LPDIRECTINPUTDEVICE8 js_device;
|
LPDIRECTINPUTDEVICE8 js_device;
|
||||||
if (SUCCEEDED(idi8->CreateDevice(joystick.guidInstance, &js_device, nullptr)))
|
if (SUCCEEDED(idi8->CreateDevice(joystick.guidInstance, &js_device, nullptr)))
|
||||||
|
@ -248,7 +152,7 @@ Joystick::Joystick( /*const LPCDIDEVICEINSTANCE lpddi, */const LPDIRECTINPUTDEVI
|
||||||
std::list<DIDEVICEOBJECTINSTANCE> objects;
|
std::list<DIDEVICEOBJECTINSTANCE> objects;
|
||||||
if (SUCCEEDED(m_device->EnumObjects(DIEnumDeviceObjectsCallback, (LPVOID)&objects, DIDFT_AXIS)))
|
if (SUCCEEDED(m_device->EnumObjects(DIEnumDeviceObjectsCallback, (LPVOID)&objects, DIDFT_AXIS)))
|
||||||
{
|
{
|
||||||
InitForceFeedback(m_device, objects.size());
|
InitForceFeedback(m_device, (int)objects.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearInputState();
|
ClearInputState();
|
||||||
|
|
|
@ -282,7 +282,7 @@ std::string OpenGLPostProcessing::LoadShaderOptions(const std::string& code)
|
||||||
}
|
}
|
||||||
else if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
|
else if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_INTEGER)
|
||||||
{
|
{
|
||||||
u32 count = it.second.m_integer_values.size();
|
u32 count = static_cast<u32>(it.second.m_integer_values.size());
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
glsl_options += StringFromFormat("uniform int option_%s;\n", it.first.c_str());
|
glsl_options += StringFromFormat("uniform int option_%s;\n", it.first.c_str());
|
||||||
else
|
else
|
||||||
|
@ -290,7 +290,7 @@ std::string OpenGLPostProcessing::LoadShaderOptions(const std::string& code)
|
||||||
}
|
}
|
||||||
else if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_FLOAT)
|
else if (it.second.m_type == PostProcessingShaderConfiguration::ConfigurationOption::OptionType::OPTION_FLOAT)
|
||||||
{
|
{
|
||||||
u32 count = it.second.m_float_values.size();
|
u32 count = static_cast<u32>(it.second.m_float_values.size());
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
glsl_options += StringFromFormat("uniform float option_%s;\n", it.first.c_str());
|
glsl_options += StringFromFormat("uniform float option_%s;\n", it.first.c_str());
|
||||||
else
|
else
|
||||||
|
|
|
@ -144,7 +144,8 @@ static void ApplySSAASettings()
|
||||||
if (g_ogl_config.bSupportSampleShading)
|
if (g_ogl_config.bSupportSampleShading)
|
||||||
{
|
{
|
||||||
glEnable(GL_SAMPLE_SHADING_ARB);
|
glEnable(GL_SAMPLE_SHADING_ARB);
|
||||||
glMinSampleShadingARB(s_MSAASamples);
|
GLfloat min_sample_shading_value = static_cast<GLfloat>(s_MSAASamples);
|
||||||
|
glMinSampleShadingARB(min_sample_shading_value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -718,7 +719,7 @@ void Renderer::DrawDebugInfo()
|
||||||
glLineWidth(3.0f);
|
glLineWidth(3.0f);
|
||||||
|
|
||||||
// 2*Coords + 3*Color
|
// 2*Coords + 3*Color
|
||||||
u32 length = stats.efb_regions.size() * sizeof(GLfloat) * (2+3)*2*6;
|
GLsizeiptr length = stats.efb_regions.size() * sizeof(GLfloat) * (2 + 3) * 2 * 6;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO);
|
glBindBuffer(GL_ARRAY_BUFFER, s_ShowEFBCopyRegions_VBO);
|
||||||
glBufferData(GL_ARRAY_BUFFER, length, nullptr, GL_STREAM_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, length, nullptr, GL_STREAM_DRAW);
|
||||||
GLfloat *Vertices = (GLfloat*)glMapBufferRange(GL_ARRAY_BUFFER, 0, length, GL_MAP_WRITE_BIT);
|
GLfloat *Vertices = (GLfloat*)glMapBufferRange(GL_ARRAY_BUFFER, 0, length, GL_MAP_WRITE_BIT);
|
||||||
|
@ -822,8 +823,9 @@ void Renderer::DrawDebugInfo()
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
s_ShowEFBCopyRegions.Bind();
|
s_ShowEFBCopyRegions.Bind();
|
||||||
glBindVertexArray( s_ShowEFBCopyRegions_VAO );
|
glBindVertexArray(s_ShowEFBCopyRegions_VAO);
|
||||||
glDrawArrays(GL_LINES, 0, stats.efb_regions.size() * 2*6);
|
GLsizei count = static_cast<GLsizei>(stats.efb_regions.size() * 2*6);
|
||||||
|
glDrawArrays(GL_LINES, 0, count);
|
||||||
|
|
||||||
// Restore Line Size
|
// Restore Line Size
|
||||||
SetLineWidth();
|
SetLineWidth();
|
||||||
|
@ -1180,7 +1182,11 @@ void Renderer::SetViewport()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
glViewport(ceil(X), ceil(Y), ceil(Width), ceil(Height));
|
auto iceilf = [](float f)
|
||||||
|
{
|
||||||
|
return static_cast<GLint>(ceilf(f));
|
||||||
|
};
|
||||||
|
glViewport(iceilf(X), iceilf(Y), iceilf(Width), iceilf(Height));
|
||||||
}
|
}
|
||||||
glDepthRangef(GLNear, GLFar);
|
glDepthRangef(GLNear, GLFar);
|
||||||
}
|
}
|
||||||
|
@ -1405,10 +1411,10 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
||||||
|
|
||||||
if (g_ActiveConfig.bUseRealXFB)
|
if (g_ActiveConfig.bUseRealXFB)
|
||||||
{
|
{
|
||||||
drawRc.top = flipped_trc.top;
|
drawRc.top = static_cast<float>(flipped_trc.top);
|
||||||
drawRc.bottom = flipped_trc.bottom;
|
drawRc.bottom = static_cast<float>(flipped_trc.bottom);
|
||||||
drawRc.left = flipped_trc.left;
|
drawRc.left = static_cast<float>(flipped_trc.left);
|
||||||
drawRc.right = flipped_trc.right;
|
drawRc.right = static_cast<float>(flipped_trc.right);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1417,10 +1423,17 @@ void Renderer::SwapImpl(u32 xfbAddr, u32 fbWidth, u32 fbHeight,const EFBRectangl
|
||||||
int xfbWidth = xfbSource->srcWidth;
|
int xfbWidth = xfbSource->srcWidth;
|
||||||
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
|
int hOffset = ((s32)xfbSource->srcAddr - (s32)xfbAddr) / ((s32)fbWidth * 2);
|
||||||
|
|
||||||
drawRc.top = flipped_trc.top - hOffset * flipped_trc.GetHeight() / fbHeight;
|
MathUtil::Rectangle<u32> rect_u32;
|
||||||
drawRc.bottom = flipped_trc.top - (hOffset + xfbHeight) * flipped_trc.GetHeight() / fbHeight;
|
|
||||||
drawRc.left = flipped_trc.left + (flipped_trc.GetWidth() - xfbWidth * flipped_trc.GetWidth() / fbWidth)/2;
|
rect_u32.top = flipped_trc.top - hOffset * flipped_trc.GetHeight() / fbHeight;
|
||||||
drawRc.right = flipped_trc.left + (flipped_trc.GetWidth() + xfbWidth * flipped_trc.GetWidth() / fbWidth)/2;
|
rect_u32.bottom = flipped_trc.top - (hOffset + xfbHeight) * flipped_trc.GetHeight() / fbHeight;
|
||||||
|
rect_u32.left = flipped_trc.left + (flipped_trc.GetWidth() - xfbWidth * flipped_trc.GetWidth() / fbWidth)/2;
|
||||||
|
rect_u32.right = flipped_trc.left + (flipped_trc.GetWidth() + xfbWidth * flipped_trc.GetWidth() / fbWidth)/2;
|
||||||
|
|
||||||
|
drawRc.top = static_cast<float>(rect_u32.top);
|
||||||
|
drawRc.bottom = static_cast<float>(rect_u32.bottom);
|
||||||
|
drawRc.left = static_cast<float>(rect_u32.left);
|
||||||
|
drawRc.right = static_cast<float>(rect_u32.right);
|
||||||
|
|
||||||
// The following code disables auto stretch. Kept for reference.
|
// The following code disables auto stretch. Kept for reference.
|
||||||
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
// scale draw area for a 1 to 1 pixel mapping with the draw target
|
||||||
|
|
|
@ -274,12 +274,14 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
|
|
||||||
glViewport(0, 0, virtual_width, virtual_height);
|
glViewport(0, 0, virtual_width, virtual_height);
|
||||||
|
|
||||||
|
GLuint uniform_location;
|
||||||
if (srcFormat == PEControl::Z24)
|
if (srcFormat == PEControl::Z24)
|
||||||
{
|
{
|
||||||
s_DepthMatrixProgram.Bind();
|
s_DepthMatrixProgram.Bind();
|
||||||
if (s_DepthCbufid != cbufid)
|
if (s_DepthCbufid != cbufid)
|
||||||
glUniform4fv(s_DepthMatrixUniform, 5, colmat);
|
glUniform4fv(s_DepthMatrixUniform, 5, colmat);
|
||||||
s_DepthCbufid = cbufid;
|
s_DepthCbufid = cbufid;
|
||||||
|
uniform_location = s_DepthCopyPositionUniform;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -287,11 +289,12 @@ void TextureCache::TCacheEntry::FromRenderTarget(u32 dstAddr, unsigned int dstFo
|
||||||
if (s_ColorCbufid != cbufid)
|
if (s_ColorCbufid != cbufid)
|
||||||
glUniform4fv(s_ColorMatrixUniform, 7, colmat);
|
glUniform4fv(s_ColorMatrixUniform, 7, colmat);
|
||||||
s_ColorCbufid = cbufid;
|
s_ColorCbufid = cbufid;
|
||||||
|
uniform_location = s_ColorCopyPositionUniform;
|
||||||
}
|
}
|
||||||
|
|
||||||
TargetRectangle R = g_renderer->ConvertEFBRectangle(srcRect);
|
TargetRectangle R = g_renderer->ConvertEFBRectangle(srcRect);
|
||||||
glUniform4f(srcFormat == PEControl::Z24 ? s_DepthCopyPositionUniform : s_ColorCopyPositionUniform,
|
glUniform4f(uniform_location, static_cast<float>(R.left), static_cast<float>(R.top),
|
||||||
R.left, R.top, R.right, R.bottom);
|
static_cast<float>(R.right), static_cast<float>(R.bottom));
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
|
@ -345,7 +345,8 @@ void EncodeToRamYUYV(GLuint srcTexture, const TargetRectangle& sourceRc, u8* des
|
||||||
|
|
||||||
s_rgbToYuyvProgram.Bind();
|
s_rgbToYuyvProgram.Bind();
|
||||||
|
|
||||||
glUniform4f(s_rgbToYuyvUniform_loc, sourceRc.left, sourceRc.top, sourceRc.right, sourceRc.bottom);
|
glUniform4f(s_rgbToYuyvUniform_loc, static_cast<float>(sourceRc.left), static_cast<float>(sourceRc.top),
|
||||||
|
static_cast<float>(sourceRc.right), static_cast<float>(sourceRc.bottom));
|
||||||
|
|
||||||
// We enable linear filtering, because the gamecube does filtering in the vertical direction when
|
// We enable linear filtering, because the gamecube does filtering in the vertical direction when
|
||||||
// yscale is enabled.
|
// yscale is enabled.
|
||||||
|
|
|
@ -151,10 +151,10 @@ void SWBPWritten(int address, int newvalue)
|
||||||
{
|
{
|
||||||
int regNum = (address >> 1 ) & 0x3;
|
int regNum = (address >> 1 ) & 0x3;
|
||||||
TevReg& reg = bpmem.tevregs[regNum];
|
TevReg& reg = bpmem.tevregs[regNum];
|
||||||
bool konst = reg.type_ra;
|
bool is_konst = reg.type_ra != 0;
|
||||||
|
|
||||||
Rasterizer::SetTevReg(regNum, Tev::ALP_C, konst, reg.alpha);
|
Rasterizer::SetTevReg(regNum, Tev::ALP_C, is_konst, static_cast<s16>(reg.alpha));
|
||||||
Rasterizer::SetTevReg(regNum, Tev::RED_C, konst, reg.red);
|
Rasterizer::SetTevReg(regNum, Tev::RED_C, is_konst, static_cast<s16>(reg.red));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -166,10 +166,10 @@ void SWBPWritten(int address, int newvalue)
|
||||||
{
|
{
|
||||||
int regNum = (address >> 1 ) & 0x3;
|
int regNum = (address >> 1 ) & 0x3;
|
||||||
TevReg& reg = bpmem.tevregs[regNum];
|
TevReg& reg = bpmem.tevregs[regNum];
|
||||||
bool konst = reg.type_bg;
|
bool is_konst = reg.type_bg != 0;
|
||||||
|
|
||||||
Rasterizer::SetTevReg(regNum, Tev::GRN_C, konst, reg.green);
|
Rasterizer::SetTevReg(regNum, Tev::GRN_C, is_konst, static_cast<s16>(reg.green));
|
||||||
Rasterizer::SetTevReg(regNum, Tev::BLU_C, konst, reg.blue);
|
Rasterizer::SetTevReg(regNum, Tev::BLU_C, is_konst, static_cast<s16>(reg.blue));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,7 +143,7 @@ void RunGpu()
|
||||||
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
{
|
{
|
||||||
// Directly map reads and writes to the cpreg structure.
|
// Directly map reads and writes to the cpreg structure.
|
||||||
for (size_t i = 0; i < sizeof (cpreg) / sizeof (u16); ++i)
|
for (u32 i = 0; i < sizeof (cpreg) / sizeof (u16); ++i)
|
||||||
{
|
{
|
||||||
u16* ptr = ((u16*)&cpreg) + i;
|
u16* ptr = ((u16*)&cpreg) + i;
|
||||||
mmio->Register(base | (i * 2),
|
mmio->Register(base | (i * 2),
|
||||||
|
@ -154,7 +154,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
|
|
||||||
// Bleh. Apparently SWCommandProcessor does not know about regs 0x40 to
|
// Bleh. Apparently SWCommandProcessor does not know about regs 0x40 to
|
||||||
// 0x64...
|
// 0x64...
|
||||||
for (size_t i = 0x40; i < 0x64; ++i)
|
for (u32 i = 0x40; i < 0x64; ++i)
|
||||||
{
|
{
|
||||||
mmio->Register(base | i,
|
mmio->Register(base | i,
|
||||||
MMIO::Constant<u16>(0),
|
MMIO::Constant<u16>(0),
|
||||||
|
|
|
@ -219,7 +219,7 @@ static void BPWritten(const BPCmd& bp)
|
||||||
|
|
||||||
CopyEFB(destAddr, srcRect,
|
CopyEFB(destAddr, srcRect,
|
||||||
PE_copy.tp_realFormat(), bpmem.zcontrol.pixel_format,
|
PE_copy.tp_realFormat(), bpmem.zcontrol.pixel_format,
|
||||||
PE_copy.intensity_fmt, PE_copy.half_scale);
|
!!PE_copy.intensity_fmt, !!PE_copy.half_scale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -235,19 +235,19 @@ static void BPWritten(const BPCmd& bp)
|
||||||
else
|
else
|
||||||
yScale = (float)bpmem.dispcopyyscale / 256.0f;
|
yScale = (float)bpmem.dispcopyyscale / 256.0f;
|
||||||
|
|
||||||
float xfbLines = ((bpmem.copyTexSrcWH.y + 1.0f) * yScale);
|
float num_xfb_lines = ((bpmem.copyTexSrcWH.y + 1.0f) * yScale);
|
||||||
if ((u32)xfbLines > MAX_XFB_HEIGHT)
|
|
||||||
|
u32 height = static_cast<u32>(num_xfb_lines);
|
||||||
|
if (height > MAX_XFB_HEIGHT)
|
||||||
{
|
{
|
||||||
INFO_LOG(VIDEO, "Tried to scale EFB to too many XFB lines (%f)", xfbLines);
|
INFO_LOG(VIDEO, "Tried to scale EFB to too many XFB lines: %d (%f)",
|
||||||
xfbLines = MAX_XFB_HEIGHT;
|
height, num_xfb_lines);
|
||||||
|
height = MAX_XFB_HEIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 width = bpmem.copyMipMapStrideChannels << 4;
|
u32 width = bpmem.copyMipMapStrideChannels << 4;
|
||||||
u32 height = xfbLines;
|
|
||||||
|
|
||||||
Renderer::RenderToXFB(destAddr, srcRect,
|
Renderer::RenderToXFB(destAddr, srcRect, width, height, s_gammaLUT[PE_copy.gamma]);
|
||||||
width, height,
|
|
||||||
s_gammaLUT[PE_copy.gamma]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear the rectangular region after copying it.
|
// Clear the rectangular region after copying it.
|
||||||
|
@ -565,9 +565,9 @@ static void BPWritten(const BPCmd& bp)
|
||||||
// don't compare with changes!
|
// don't compare with changes!
|
||||||
int num = (bp.address >> 1) & 0x3;
|
int num = (bp.address >> 1) & 0x3;
|
||||||
if ((bp.address & 1) == 0)
|
if ((bp.address & 1) == 0)
|
||||||
PixelShaderManager::SetColorChanged(bpmem.tevregs[num].type_ra, num);
|
PixelShaderManager::SetColorChanged(static_cast<int>(bpmem.tevregs[num].type_ra), num);
|
||||||
else
|
else
|
||||||
PixelShaderManager::SetColorChanged(bpmem.tevregs[num].type_bg, num);
|
PixelShaderManager::SetColorChanged(static_cast<int>(bpmem.tevregs[num].type_bg), num);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -107,13 +107,13 @@ PC_TexFormat GetHiresTex(const std::string& filename, unsigned int* pWidth, unsi
|
||||||
//int offset = 0;
|
//int offset = 0;
|
||||||
PC_TexFormat returnTex = PC_TEX_FMT_NONE;
|
PC_TexFormat returnTex = PC_TEX_FMT_NONE;
|
||||||
|
|
||||||
switch (texformat)
|
|
||||||
{
|
|
||||||
// TODO(neobrain): This function currently has no way to enforce RGBA32
|
// TODO(neobrain): This function currently has no way to enforce RGBA32
|
||||||
// output, which however is required on some configurations to function
|
// output, which however is required on some configurations to function
|
||||||
// properly. As a lazy workaround, we hence disable the optimized code
|
// properly. As a lazy workaround, we hence disable the optimized code
|
||||||
// path for now.
|
// path for now.
|
||||||
#if 0
|
#if 0
|
||||||
|
switch (texformat)
|
||||||
|
{
|
||||||
case GX_TF_I4:
|
case GX_TF_I4:
|
||||||
case GX_TF_I8:
|
case GX_TF_I8:
|
||||||
case GX_TF_IA4:
|
case GX_TF_IA4:
|
||||||
|
@ -131,7 +131,6 @@ PC_TexFormat GetHiresTex(const std::string& filename, unsigned int* pWidth, unsi
|
||||||
}
|
}
|
||||||
returnTex = PC_TEX_FMT_IA8;
|
returnTex = PC_TEX_FMT_IA8;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
*required_size = width * height * 4;
|
*required_size = width * height * 4;
|
||||||
if (data_size < *required_size)
|
if (data_size < *required_size)
|
||||||
|
@ -141,6 +140,14 @@ PC_TexFormat GetHiresTex(const std::string& filename, unsigned int* pWidth, unsi
|
||||||
returnTex = PC_TEX_FMT_RGBA32;
|
returnTex = PC_TEX_FMT_RGBA32;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
*required_size = width * height * 4;
|
||||||
|
if (data_size < *required_size)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
memcpy(data, temp, width * height * 4);
|
||||||
|
returnTex = PC_TEX_FMT_RGBA32;
|
||||||
|
#endif
|
||||||
|
|
||||||
INFO_LOG(VIDEO, "Loading custom texture from %s", textureMap[filename].c_str());
|
INFO_LOG(VIDEO, "Loading custom texture from %s", textureMap[filename].c_str());
|
||||||
cleanup:
|
cleanup:
|
||||||
|
|
|
@ -100,8 +100,8 @@ void PixelShaderManager::SetConstants()
|
||||||
|
|
||||||
if (s_bViewPortChanged)
|
if (s_bViewPortChanged)
|
||||||
{
|
{
|
||||||
constants.zbias[1][0] = xfmem.viewport.farZ;
|
constants.zbias[1][0] = static_cast<u32>(xfmem.viewport.farZ);
|
||||||
constants.zbias[1][1] = xfmem.viewport.zRange;
|
constants.zbias[1][1] = static_cast<u32>(xfmem.viewport.zRange);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
s_bViewPortChanged = false;
|
s_bViewPortChanged = false;
|
||||||
}
|
}
|
||||||
|
@ -110,10 +110,10 @@ void PixelShaderManager::SetConstants()
|
||||||
void PixelShaderManager::SetColorChanged(int type, int num)
|
void PixelShaderManager::SetColorChanged(int type, int num)
|
||||||
{
|
{
|
||||||
int4* c = type ? constants.kcolors : constants.colors;
|
int4* c = type ? constants.kcolors : constants.colors;
|
||||||
c[num][0] = bpmem.tevregs[num].red;
|
c[num][0] = static_cast<s32>(bpmem.tevregs[num].red);
|
||||||
c[num][3] = bpmem.tevregs[num].alpha;
|
c[num][3] = static_cast<s32>(bpmem.tevregs[num].alpha);
|
||||||
c[num][2] = bpmem.tevregs[num].blue;
|
c[num][2] = static_cast<s32>(bpmem.tevregs[num].blue);
|
||||||
c[num][1] = bpmem.tevregs[num].green;
|
c[num][1] = static_cast<s32>(bpmem.tevregs[num].green);
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
PRIM_LOG("pixel %scolor%d: %d %d %d %d\n", type?"k":"", num, c[num][0], c[num][1], c[num][2], c[num][3]);
|
PRIM_LOG("pixel %scolor%d: %d %d %d %d\n", type?"k":"", num, c[num][0], c[num][1], c[num][2], c[num][3]);
|
||||||
|
|
|
@ -285,9 +285,10 @@ void VertexShaderManager::SetConstants()
|
||||||
double(light.ddir[1]) * double(light.ddir[1]) +
|
double(light.ddir[1]) * double(light.ddir[1]) +
|
||||||
double(light.ddir[2]) * double(light.ddir[2]);
|
double(light.ddir[2]) * double(light.ddir[2]);
|
||||||
norm = 1.0 / sqrt(norm);
|
norm = 1.0 / sqrt(norm);
|
||||||
dstlight.dir[0] = light.ddir[0] * norm;
|
float norm_float = static_cast<float>(norm);
|
||||||
dstlight.dir[1] = light.ddir[1] * norm;
|
dstlight.dir[0] = light.ddir[0] * norm_float;
|
||||||
dstlight.dir[2] = light.ddir[2] * norm;
|
dstlight.dir[1] = light.ddir[1] * norm_float;
|
||||||
|
dstlight.dir[2] = light.ddir[2] * norm_float;
|
||||||
}
|
}
|
||||||
dirty = true;
|
dirty = true;
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,10 @@
|
||||||
<PreprocessorDefinitions Condition="Exists('$(DXSDK_DIR)')">HAVE_DXSDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions Condition="Exists('$(DXSDK_DIR)')">HAVE_DXSDK;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<PreprocessorDefinitions>USE_UPNP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>USE_UPNP;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PreprocessorDefinitions>PSAPI_VERSION=1;_M_X86=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<PreprocessorDefinitions Condition="'$(Platform)'=='x64'">_ARCH_64=1;_M_X86_64=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<TreatWarningAsError>true</TreatWarningAsError>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<StructMemberAlignment>16Bytes</StructMemberAlignment>
|
<StructMemberAlignment>16Bytes</StructMemberAlignment>
|
||||||
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
<RuntimeTypeInfo>false</RuntimeTypeInfo>
|
||||||
|
@ -59,8 +62,8 @@
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<!--Enforce some behaviors as standards-conformant when they don't default as such-->
|
<!--Enforce some behaviors as standards-conformant when they don't default as such-->
|
||||||
<AdditionalOptions>/Zc:inline /Zc:rvalueCast /volatile:iso %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:inline /Zc:rvalueCast /volatile:iso %(AdditionalOptions)</AdditionalOptions>
|
||||||
<AdditionalOptions>/Zo /D PSAPI_VERSION=1 /D _M_X86=1 %(AdditionalOptions)</AdditionalOptions>
|
<!--Enable detailed debug info-->
|
||||||
<AdditionalOptions Condition="'$(Platform)'=='x64'">/D _ARCH_64=1 /D _M_X86_64=1 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zo %(AdditionalOptions)</AdditionalOptions>
|
||||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||||
<!--
|
<!--
|
||||||
This is for GetVersionEx being marked as depreciated - which is idiotic and there's
|
This is for GetVersionEx being marked as depreciated - which is idiotic and there's
|
||||||
|
@ -89,6 +92,8 @@
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<FunctionLevelLinking>false</FunctionLevelLinking>
|
<FunctionLevelLinking>false</FunctionLevelLinking>
|
||||||
<PreprocessorDefinitions>_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<!--This option is not supported in debug mode (for VS2013)-->
|
||||||
|
<AdditionalOptions>/Zc:strictStrings %(AdditionalOptions)</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<!--Link Base-->
|
<!--Link Base-->
|
||||||
<Link>
|
<Link>
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ImportGroup Label="PropertySheets" />
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<ItemDefinitionGroup>
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>TurnOffAllWarnings</WarningLevel>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup />
|
||||||
|
</Project>
|
Loading…
Reference in New Issue