summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorMatthew Parlane <parlane@gmail.com>2012-03-28 21:52:17 +1300
committerMatthew Parlane <parlane@gmail.com>2012-04-04 19:53:05 +1200
commit9bf67d4bb1db516a83f8e5c53bf6efee32131579 (patch)
treeecf3a1c5110f841b6d7ca7160c8a2cb0e6bb867a /Source/Core
parent702905131bc9c745442bdfb9b650b04e6ff0458b (diff)
Implemented /dev/usb/hid as libusb, but this will not work on mac. Code started for using hidapi instead.
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Common/Src/Log.h1
-rw-r--r--Source/Core/Common/Src/LogManager.cpp1
-rw-r--r--Source/Core/Core/Core.vcxproj14
-rw-r--r--Source/Core/Core/Core.vcxproj.filters9
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp3
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp416
-rw-r--r--Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h126
7 files changed, 563 insertions, 7 deletions
diff --git a/Source/Core/Common/Src/Log.h b/Source/Core/Common/Src/Log.h
index 3be97d54d4..4892886693 100644
--- a/Source/Core/Common/Src/Log.h
+++ b/Source/Core/Common/Src/Log.h
@@ -64,6 +64,7 @@ enum LOG_TYPE {
WII_IPC_DVD,
WII_IPC_ES,
WII_IPC_FILEIO,
+ WII_IPC_HID,
WII_IPC_HLE,
WII_IPC_NET,
WII_IPC_SD,
diff --git a/Source/Core/Common/Src/LogManager.cpp b/Source/Core/Common/Src/LogManager.cpp
index a79c413cf8..df55f018c6 100644
--- a/Source/Core/Common/Src/LogManager.cpp
+++ b/Source/Core/Common/Src/LogManager.cpp
@@ -71,6 +71,7 @@ LogManager::LogManager()
m_Log[LogTypes::WIIMOTE] = new LogContainer("Wiimote", "Wiimote");
m_Log[LogTypes::WII_IOB] = new LogContainer("WII_IOB", "WII IO Bridge");
m_Log[LogTypes::WII_IPC] = new LogContainer("WII_IPC", "WII IPC");
+ m_Log[LogTypes::WII_IPC_HID] = new LogContainer("WII_IPC_HID", "WII IPC HID");
m_Log[LogTypes::WII_IPC_HLE] = new LogContainer("WII_IPC_HLE", "WII IPC HLE");
m_Log[LogTypes::WII_IPC_DVD] = new LogContainer("WII_IPC_DVD", "WII IPC DVD");
m_Log[LogTypes::WII_IPC_ES] = new LogContainer("WII_IPC_ES", "WII IPC ES");
diff --git a/Source/Core/Core/Core.vcxproj b/Source/Core/Core/Core.vcxproj
index e03d40e43a..25ede66e60 100644
--- a/Source/Core/Core/Core.vcxproj
+++ b/Source/Core/Core/Core.vcxproj
@@ -115,7 +115,7 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
- <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -127,7 +127,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -139,7 +139,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
- <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -153,7 +153,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|Win32'">
<ClCompile>
- <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -167,7 +167,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -181,7 +181,7 @@
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugFast|x64'">
<ClCompile>
- <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <AdditionalIncludeDirectories>.\Src;..\Common\Src;..\VideoCommon\Src;..\AudioCommon\Src;..\DiscIO\Src;..\InputCommon\Src;..\wiiuse\Src;..\..\..\Externals\Bochs_disasm;..\..\..\Externals\SFML\include;..\..\..\Externals\LZO;..\..\..\Externals\portaudio\include;..\..\..\Externals\zlib;..\..\..\Externals\libusb\include;%(AdditionalIncludeDirectories);..\..\..\Externals\libusb\include</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@@ -326,6 +326,7 @@
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_es.cpp" />
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_FileIO.cpp" />
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_fs.cpp" />
+ <ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_hid.cpp" />
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_net.cpp" />
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_sdio_slot0.cpp" />
<ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_usb.cpp" />
@@ -526,6 +527,7 @@
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_es.h" />
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_FileIO.h" />
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_fs.h" />
+ <ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_hid.h" />
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_net.h" />
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_sdio_slot0.h" />
<ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_stm.h" />
diff --git a/Source/Core/Core/Core.vcxproj.filters b/Source/Core/Core/Core.vcxproj.filters
index 020cf76ad0..475861b64a 100644
--- a/Source/Core/Core/Core.vcxproj.filters
+++ b/Source/Core/Core/Core.vcxproj.filters
@@ -556,6 +556,9 @@
<ClCompile Include="Src\HW\GCMemcard.cpp">
<Filter>HW %28Flipper/Hollywood%29\GCMemcard</Filter>
</ClCompile>
+ <ClCompile Include="Src\IPC_HLE\WII_IPC_HLE_Device_hid.cpp">
+ <Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Src\ConfigManager.h" />
@@ -1033,6 +1036,9 @@
<ClInclude Include="Src\HW\GCMemcard.h">
<Filter>HW %28Flipper/Hollywood%29\GCMemcard</Filter>
</ClInclude>
+ <ClInclude Include="Src\IPC_HLE\WII_IPC_HLE_Device_hid.h">
+ <Filter>IPC HLE %28IOS/Starlet%29\USB</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
@@ -1173,5 +1179,8 @@
<Filter Include="HW %28Flipper/Hollywood%29\GCMemcard">
<UniqueIdentifier>{3e9e6e83-c1bf-45f9-aeff-231f98f60d29}</UniqueIdentifier>
</Filter>
+ <Filter Include="IPC HLE %28IOS/Starlet%29\USB">
+ <UniqueIdentifier>{321a9af5-9b3d-4620-888c-fe9d02e9559e}</UniqueIdentifier>
+ </Filter>
</ItemGroup>
</Project> \ No newline at end of file
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
index cd4f679db9..40c31c9e2b 100644
--- a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp
@@ -50,6 +50,7 @@ They will also generate a true or false return for UpdateInterrupts() in WII_IPC
#include "WII_IPC_HLE_Device_usb.h"
#include "WII_IPC_HLE_Device_usb_kbd.h"
#include "WII_IPC_HLE_Device_sdio_slot0.h"
+#include "WII_IPC_HLE_Device_hid.h"
#include "FileUtil.h" // For Copy
#include "../ConfigManager.h"
@@ -113,7 +114,7 @@ void Init()
g_DeviceMap[i] = new CWII_IPC_HLE_Device_usb_kbd(i, std::string("/dev/usb/kbd")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_sdio_slot0(i, std::string("/dev/sdio/slot0")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/sdio/slot1")); i++;
- g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/hid")); i++;
+ g_DeviceMap[i] = new CWII_IPC_HLE_Device_hid(i, std::string("/dev/usb/hid")); i++;
g_DeviceMap[i] = new CWII_IPC_HLE_Device_stub(i, std::string("/dev/usb/oh1")); i++;
g_DeviceMap[i] = new IWII_IPC_HLE_Device(i, std::string("_Unimplemented_Device_")); i++;
}
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp
new file mode 100644
index 0000000000..0103a534c3
--- /dev/null
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp
@@ -0,0 +1,416 @@
+// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#include "../Core.h"
+#include "../Debugger/Debugger_SymbolMap.h"
+#include "../HW/WII_IPC.h"
+#include "WII_IPC_HLE.h"
+#include "WII_IPC_HLE_Device_hid.h"
+#include "lusb0_usb.h"
+#include "hidapi.h"
+
+CWII_IPC_HLE_Device_hid::CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName)
+ : IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
+{
+
+ usb_init(); /* initialize the library */
+
+}
+
+CWII_IPC_HLE_Device_hid::~CWII_IPC_HLE_Device_hid()
+{
+
+}
+
+bool CWII_IPC_HLE_Device_hid::Open(u32 _CommandAddress, u32 _Mode)
+{
+ Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING);
+ DEBUG_LOG(WII_IPC_HID, "HID::Open");
+ Memory::Write_U32(GetDeviceID(), _CommandAddress + 4);
+ return true;
+}
+
+bool CWII_IPC_HLE_Device_hid::Close(u32 _CommandAddress, bool _bForce)
+{
+ DEBUG_LOG(WII_IPC_HID, "HID::Close");
+ if (!_bForce)
+ Memory::Write_U32(0, _CommandAddress + 4);
+ return true;
+}
+
+bool CWII_IPC_HLE_Device_hid::IOCtl(u32 _CommandAddress)
+{
+ static u32 replyAddress = 0;
+ static bool hasRun = false;
+ u32 Parameter = Memory::Read_U32(_CommandAddress + 0xC);
+ u32 BufferIn = Memory::Read_U32(_CommandAddress + 0x10);
+ u32 BufferInSize = Memory::Read_U32(_CommandAddress + 0x14);
+ u32 BufferOut = Memory::Read_U32(_CommandAddress + 0x18);
+ u32 BufferOutSize = Memory::Read_U32(_CommandAddress + 0x1C);
+
+ u32 ReturnValue = 0;
+ switch (Parameter)
+ {
+ case IOCTL_HID_GET_ATTACHED:
+ {
+ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Get Attached) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ BufferIn, BufferInSize, BufferOut, BufferOutSize);
+ if(!hasRun)
+ {
+ FillOutDevices(BufferOut, BufferOutSize);
+ hasRun = true;
+ }
+ else
+ {
+ replyAddress = _CommandAddress;
+ return false;
+ }
+ break;
+ }
+ case IOCTL_HID_OPEN:
+ {
+ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Open) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ BufferIn, BufferInSize, BufferOut, BufferOutSize);
+
+ //hid version, apparently
+ ReturnValue = 0x40001;
+ break;
+ }
+ case IOCTL_HID_SET_SUSPEND:
+ {
+ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Set Suspend) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ BufferIn, BufferInSize, BufferOut, BufferOutSize);
+ // not actually implemented in IOS
+ ReturnValue = 0;
+
+ if (replyAddress != 0){
+ FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C));
+ WII_IPC_HLE_Interface::EnqReply(replyAddress);
+ replyAddress = 0;
+ hasRun = false;
+ }
+
+ break;
+ }
+ case IOCTL_HID_CANCEL_INTERRUPT:
+ {
+ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Cancel Interrupt) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ BufferIn, BufferInSize, BufferOut, BufferOutSize);
+
+ if (replyAddress != 0){
+ FillOutDevices(Memory::Read_U32(replyAddress + 0x18), Memory::Read_U32(replyAddress + 0x1C));
+ WII_IPC_HLE_Interface::EnqReply(replyAddress);
+ replyAddress = 0;
+ hasRun = false;
+ }
+
+ ReturnValue = 0;
+ break;
+ }
+ case IOCTL_HID_CONTROL:
+ {
+ /*
+ ERROR CODES:
+ -4 Cant find device specified
+ */
+ u32 dev_num = Memory::Read_U32(BufferIn+0x10);
+ u8 requesttype = Memory::Read_U8(BufferIn+0x14);
+ u8 request = Memory::Read_U8(BufferIn+0x15);
+ u16 value = Memory::Read_U16(BufferIn+0x16);
+ u16 index = Memory::Read_U16(BufferIn+0x18);
+ u16 size = Memory::Read_U16(BufferIn+0x1A);
+ u32 data = Memory::Read_U32(BufferIn+0x1C);
+
+ static int upto = 0;
+ int i;
+ usb_find_busses(); /* find all busses */
+ usb_find_devices(); /* find all connected devices */
+
+ struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num);
+
+ if (dev_handle == NULL)
+ {
+ ReturnValue = -4;
+ break;
+ }
+
+ ReturnValue = usb_control_msg(dev_handle, requesttype, request,
+ value, index, (char*)Memory::GetPointer(data), size,
+ 0);
+
+ if(ReturnValue>=0)
+ {
+ ReturnValue += sizeof(usb_ctrl_setup);
+ }
+ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Control)(%02X, %02X) = %d",
+ requesttype, request, ReturnValue);
+
+ usb_close(dev_handle);
+
+ u8 test_out[0x20];
+ Memory::ReadBigEData(test_out, BufferIn, BufferInSize);
+ char file[0x50];
+ snprintf(file, 0x50, "ctrl_ctrlprotocol_%d.bin", upto);
+ FILE* test = fopen (file, "wb");
+ for(i=0;i<0x20;i++)
+ fwrite(&test_out[i], 1, 1, test);
+ if (size > 0)
+ fwrite((char*)Memory::GetPointer(data), 1, size, test);
+ fclose(test);
+ upto++;
+ break;
+ }
+ case IOCTL_HID_INTERRUPT_IN:
+ {
+
+
+ u32 dev_num = Memory::Read_U32(BufferIn+0x10);
+ u32 end_point = Memory::Read_U32(BufferIn+0x14);
+ u32 length = Memory::Read_U32(BufferIn+0x18);
+
+ u32 data = Memory::Read_U32(BufferIn+0x1C);
+
+ struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num);
+
+ if (dev_handle == NULL)
+ {
+ ReturnValue = -4;
+ break;
+ }
+
+ usb_claim_interface(dev_handle,0);
+ ReturnValue = usb_interrupt_read(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 1000);
+
+ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt In)(%d,%d,%p) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ end_point, length, data, ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize);
+
+ usb_close(dev_handle);
+ break;
+ }
+ case IOCTL_HID_INTERRUPT_OUT:
+ {
+
+
+ u32 dev_num = Memory::Read_U32(BufferIn+0x10);
+ u32 end_point = Memory::Read_U32(BufferIn+0x14);
+ u32 length = Memory::Read_U32(BufferIn+0x18);
+
+ u32 data = Memory::Read_U32(BufferIn+0x1C);
+
+ struct usb_dev_handle * dev_handle = GetDeviceByDevNum(dev_num);
+
+ if (dev_handle == NULL)
+ {
+ ReturnValue = -4;
+ break;
+ }
+
+ usb_claim_interface(dev_handle,0);
+ ReturnValue = usb_interrupt_write(dev_handle, end_point, (char*)Memory::GetPointer(data), length, 0);
+
+ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(Interrupt Out) = %d (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ ReturnValue, BufferIn, BufferInSize, BufferOut, BufferOutSize);
+
+ usb_close(dev_handle);
+ break;
+ }
+ default:
+ {
+ DEBUG_LOG(WII_IPC_HID, "HID::IOCtl(0x%x) (BufferIn: (%08x, %i), BufferOut: (%08x, %i)",
+ Parameter, BufferIn, BufferInSize, BufferOut, BufferOutSize);
+ break;
+ }
+ }
+
+ Memory::Write_U32(ReturnValue, _CommandAddress + 4);
+
+ return true;
+}
+
+bool CWII_IPC_HLE_Device_hid::IOCtlV(u32 _CommandAddress)
+{
+
+ Dolphin_Debugger::PrintCallstack(LogTypes::WII_IPC_HID, LogTypes::LWARNING);
+ u32 ReturnValue = 0;
+ SIOCtlVBuffer CommandBuffer(_CommandAddress);
+
+ switch (CommandBuffer.Parameter)
+ {
+
+ default:
+ {
+ DEBUG_LOG(WII_IPC_HID, "%s - IOCtlV:", GetDeviceName().c_str());
+ DEBUG_LOG(WII_IPC_HID, " Parameter: 0x%x", CommandBuffer.Parameter);
+ DEBUG_LOG(WII_IPC_HID, " NumberIn: 0x%08x", CommandBuffer.NumberInBuffer);
+ DEBUG_LOG(WII_IPC_HID, " NumberOut: 0x%08x", CommandBuffer.NumberPayloadBuffer);
+ DEBUG_LOG(WII_IPC_HID, " BufferVector: 0x%08x", CommandBuffer.BufferVector);
+ DEBUG_LOG(WII_IPC_HID, " PayloadAddr: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Address);
+ DEBUG_LOG(WII_IPC_HID, " PayloadSize: 0x%08x", CommandBuffer.PayloadBuffer[0].m_Size);
+ #if defined(_DEBUG) || defined(DEBUGFAST)
+ DumpAsync(CommandBuffer.BufferVector, CommandBuffer.NumberInBuffer, CommandBuffer.NumberPayloadBuffer);
+ #endif
+ }
+ break;
+ }
+
+ Memory::Write_U32(ReturnValue, _CommandAddress + 4);
+ return true;
+}
+
+
+
+void CWII_IPC_HLE_Device_hid::ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src)
+{
+ memcpy(dest,src,sizeof(WiiHIDDeviceDescriptor));
+ dest->bcdUSB = Common::swap16(dest->bcdUSB);
+ dest->idVendor = Common::swap16(dest->idVendor);
+ dest->idProduct = Common::swap16(dest->idProduct);
+ dest->bcdDevice = Common::swap16(dest->bcdDevice);
+}
+
+void CWII_IPC_HLE_Device_hid::ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src)
+{
+ memcpy(dest,src,sizeof(WiiHIDConfigDescriptor));
+ dest->wTotalLength = Common::swap16(dest->wTotalLength);
+}
+
+void CWII_IPC_HLE_Device_hid::ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, struct usb_interface_descriptor *src)
+{
+ memcpy(dest,src,sizeof(WiiHIDInterfaceDescriptor));
+}
+
+void CWII_IPC_HLE_Device_hid::ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src)
+{
+ memcpy(dest,src,sizeof(WiiHIDEndpointDescriptor));
+ dest->wMaxPacketSize = Common::swap16(dest->wMaxPacketSize);
+}
+/*
+// hidapi version
+void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize)
+{
+ // Enumerate and print the HID devices on the system
+ struct hid_device_info *devs, *cur_dev;
+
+ devs = hid_enumerate(0x0, 0x0);
+ cur_dev = devs;
+ while (cur_dev) {
+ printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls",
+ cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
+ printf("\n");
+ printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string);
+ printf(" Product: %ls\n", cur_dev->product_string);
+ printf("\n");
+ cur_dev = cur_dev->next;
+ }
+ hid_free_enumeration(devs);
+}
+*/
+
+// libusb version
+void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize)
+{
+ usb_find_busses(); // find all busses
+ usb_find_devices(); // find all connected devices
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ int OffsetBuffer = BufferOut;
+ int OffsetStart = 0;
+ int c,ic,i,e; // config, interface container, interface, endpoint
+ for (bus = usb_get_busses(); bus; bus = bus->next)
+ {
+ for (dev = bus->devices; dev; dev = dev->next)
+ {
+ struct usb_device_descriptor *device = &dev->descriptor;
+ DEBUG_LOG(WII_IPC_HID, "Found device with Vendor: %d Product: %d Devnum: %d",device->idVendor, device->idProduct, dev->devnum);
+
+ OffsetStart = OffsetBuffer;
+ OffsetBuffer += 4; // skip length for now, fill at end
+
+ Memory::Write_U32(dev->devnum, OffsetBuffer); //write device num
+ OffsetBuffer += 4;
+
+ WiiHIDDeviceDescriptor wii_device;
+ ConvertDeviceToWii(&wii_device, device);
+ Memory::WriteBigEData((const u8*)&wii_device, OffsetBuffer, Align(wii_device.bLength, 4));
+ OffsetBuffer += Align(wii_device.bLength, 4);
+
+ for (c = 0; c < device->bNumConfigurations; c++)
+ {
+ struct usb_config_descriptor *config = &dev->config[c];
+
+ WiiHIDConfigDescriptor wii_config;
+ ConvertConfigToWii(&wii_config, config);
+ Memory::WriteBigEData((const u8*)&wii_config, OffsetBuffer, Align(wii_config.bLength, 4));
+ OffsetBuffer += Align(wii_config.bLength, 4);
+
+ for (ic = 0; ic < config->bNumInterfaces; ic++)
+ {
+ struct usb_interface *interfaceContainer = &config->interface[ic];
+ for (i = 0; i < interfaceContainer->num_altsetting; i++)
+ {
+ struct usb_interface_descriptor *interface = &interfaceContainer->altsetting[i];
+
+ WiiHIDInterfaceDescriptor wii_interface;
+ ConvertInterfaceToWii(&wii_interface, interface);
+ Memory::WriteBigEData((const u8*)&wii_interface, OffsetBuffer, Align(wii_interface.bLength, 4));
+ OffsetBuffer += Align(wii_interface.bLength, 4);
+
+ for (e = 0; e < interface->bNumEndpoints; e++)
+ {
+ struct usb_endpoint_descriptor *endpoint = &interface->endpoint[e];
+
+ WiiHIDEndpointDescriptor wii_endpoint;
+ ConvertEndpointToWii(&wii_endpoint, endpoint);
+ Memory::WriteBigEData((const u8*)&wii_endpoint, OffsetBuffer, Align(wii_endpoint.bLength, 4));
+ OffsetBuffer += Align(wii_endpoint.bLength, 4);
+
+ } //endpoints
+ } // interfaces
+ } // interface containters
+ } // configs
+
+ Memory::Write_U32(OffsetBuffer-OffsetStart, OffsetStart); // fill in length
+
+ } // devices
+ } // buses
+
+ Memory::Write_U32(0xFFFFFFFF, OffsetBuffer); // no more devices
+
+
+}
+
+
+
+int CWII_IPC_HLE_Device_hid::Align(int num, int alignment)
+{
+ return (num + (alignment-1)) & ~(alignment-1);
+}
+
+
+struct usb_dev_handle * CWII_IPC_HLE_Device_hid::GetDeviceByDevNum(u32 devNum)
+{
+ for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next)
+ {
+ for (struct usb_device *dev = bus->devices; dev; dev = dev->next)
+ {
+ if(dev->devnum == devNum){
+ return usb_open(dev);
+ }
+ }
+ }
+ return NULL;
+} \ No newline at end of file
diff --git a/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h
new file mode 100644
index 0000000000..2bb7f47a59
--- /dev/null
+++ b/Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h
@@ -0,0 +1,126 @@
+// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#pragma once
+
+#include "WII_IPC_HLE.h"
+#include "WII_IPC_HLE_Device.h"
+
+class CWII_IPC_HLE_Device_hid : public IWII_IPC_HLE_Device
+{
+public:
+ CWII_IPC_HLE_Device_hid(u32 _DeviceID, const std::string& _rDeviceName);
+
+ virtual ~CWII_IPC_HLE_Device_hid();
+
+ virtual bool Open(u32 _CommandAddress, u32 _Mode);
+ virtual bool Close(u32 _CommandAddress, bool _bForce);
+
+ virtual bool IOCtlV(u32 _CommandAddress);
+ virtual bool IOCtl(u32 _CommandAddress);
+private:
+
+
+ std::map<u32, std::string> deviceList;
+
+ enum
+ {
+ IOCTL_HID_GET_ATTACHED = 0x00,
+ IOCTL_HID_SET_SUSPEND = 0x01,
+ IOCTL_HID_CONTROL = 0x02,
+ IOCTL_HID_INTERRUPT_IN = 0x03,
+ IOCTL_HID_INTERRUPT_OUT = 0x04,
+ IOCTL_HID_GET_US_STRING = 0x05,
+ IOCTL_HID_OPEN = 0x06,
+ IOCTL_HID_SHUTDOWN = 0x07,
+ IOCTL_HID_CANCEL_INTERRUPT = 0x08,
+ };
+
+ /* Device descriptor */
+ typedef struct
+ {
+ u8 bLength;
+ u8 bDescriptorType;
+ u16 bcdUSB;
+ u8 bDeviceClass;
+ u8 bDeviceSubClass;
+ u8 bDeviceProtocol;
+ u8 bMaxPacketSize0;
+ u16 idVendor;
+ u16 idProduct;
+ u16 bcdDevice;
+ u8 iManufacturer;
+ u8 iProduct;
+ u8 iSerialNumber;
+ u8 bNumConfigurations;
+ u8 pad[2];
+ } WiiHIDDeviceDescriptor;
+
+ typedef struct
+ {
+ u8 bLength;
+ u8 bDescriptorType;
+ u16 wTotalLength;
+ u8 bNumInterfaces;
+ u8 bConfigurationValue;
+ u8 iConfiguration;
+ u8 bmAttributes;
+ u8 MaxPower;
+ u8 pad[3];
+ } WiiHIDConfigDescriptor;
+
+ typedef struct
+ {
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bInterfaceNumber;
+ u8 bAlternateSetting;
+ u8 bNumEndpoints;
+ u8 bInterfaceClass;
+ u8 bInterfaceSubClass;
+ u8 bInterfaceProtocol;
+ u8 iInterface;
+ u8 pad[3];
+ } WiiHIDInterfaceDescriptor;
+
+ typedef struct
+ {
+ u8 bLength;
+ u8 bDescriptorType;
+ u8 bEndpointAddress;
+ u8 bmAttributes;
+ u16 wMaxPacketSize;
+ u8 bInterval;
+ u8 bRefresh;
+ u8 bSynchAddress;
+ u8 pad[1];
+ } WiiHIDEndpointDescriptor;
+
+
+ void CWII_IPC_HLE_Device_hid::FillOutDevices(u32 BufferOut, u32 BufferOutSize);
+
+ void ConvertDeviceToWii(WiiHIDDeviceDescriptor *dest, struct usb_device_descriptor *src);
+ void ConvertConfigToWii(WiiHIDConfigDescriptor *dest, struct usb_config_descriptor *src);
+ void ConvertInterfaceToWii(WiiHIDInterfaceDescriptor *dest, struct usb_interface_descriptor *src);
+ void ConvertEndpointToWii(WiiHIDEndpointDescriptor *dest, struct usb_endpoint_descriptor *src);
+
+ int Align(int num, int alignment);
+
+ struct usb_dev_handle * GetDeviceByDevNum(u32 devNum);
+
+
+};