diff options
| author | Matthew Parlane <parlane@gmail.com> | 2012-03-28 21:52:17 +1300 |
|---|---|---|
| committer | Matthew Parlane <parlane@gmail.com> | 2012-04-04 19:53:05 +1200 |
| commit | 9bf67d4bb1db516a83f8e5c53bf6efee32131579 (patch) | |
| tree | ecf3a1c5110f841b6d7ca7160c8a2cb0e6bb867a /Source/Core | |
| parent | 702905131bc9c745442bdfb9b650b04e6ff0458b (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.h | 1 | ||||
| -rw-r--r-- | Source/Core/Common/Src/LogManager.cpp | 1 | ||||
| -rw-r--r-- | Source/Core/Core/Core.vcxproj | 14 | ||||
| -rw-r--r-- | Source/Core/Core/Core.vcxproj.filters | 9 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE.cpp | 3 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.cpp | 416 | ||||
| -rw-r--r-- | Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_hid.h | 126 |
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); + + +}; |
