mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-22 00:59:18 +01:00
Use hidapi for Wiimotes on Windows (#1033)
This commit is contained in:
parent
09409a5108
commit
1849083073
@ -89,10 +89,9 @@ if (WIN32)
|
|||||||
option(ENABLE_XINPUT "Enables the usage of XInput" ON)
|
option(ENABLE_XINPUT "Enables the usage of XInput" ON)
|
||||||
option(ENABLE_DIRECTINPUT "Enables the usage of DirectInput" ON)
|
option(ENABLE_DIRECTINPUT "Enables the usage of DirectInput" ON)
|
||||||
add_compile_definitions(HAS_DIRECTINPUT)
|
add_compile_definitions(HAS_DIRECTINPUT)
|
||||||
set(ENABLE_WIIMOTE ON)
|
|
||||||
elseif (UNIX)
|
|
||||||
option(ENABLE_HIDAPI "Build with HIDAPI" ON)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
option(ENABLE_HIDAPI "Build with HIDAPI" ON)
|
||||||
option(ENABLE_SDL "Enables the SDLController backend" ON)
|
option(ENABLE_SDL "Enables the SDLController backend" ON)
|
||||||
|
|
||||||
# audio backends
|
# audio backends
|
||||||
|
@ -70,18 +70,9 @@ if (ENABLE_WIIMOTE)
|
|||||||
api/Wiimote/NativeWiimoteController.h
|
api/Wiimote/NativeWiimoteController.h
|
||||||
api/Wiimote/NativeWiimoteController.cpp
|
api/Wiimote/NativeWiimoteController.cpp
|
||||||
api/Wiimote/WiimoteDevice.h
|
api/Wiimote/WiimoteDevice.h
|
||||||
)
|
|
||||||
if (ENABLE_HIDAPI)
|
|
||||||
target_sources(CemuInput PRIVATE
|
|
||||||
api/Wiimote/hidapi/HidapiWiimote.cpp
|
api/Wiimote/hidapi/HidapiWiimote.cpp
|
||||||
api/Wiimote/hidapi/HidapiWiimote.h
|
api/Wiimote/hidapi/HidapiWiimote.h
|
||||||
)
|
)
|
||||||
elseif (WIN32)
|
|
||||||
target_sources(CemuInput PRIVATE
|
|
||||||
api/Wiimote/windows/WinWiimoteDevice.cpp
|
|
||||||
api/Wiimote/windows/WinWiimoteDevice.h
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
#include "input/api/Wiimote/NativeWiimoteController.h"
|
#include "input/api/Wiimote/NativeWiimoteController.h"
|
||||||
#include "input/api/Wiimote/WiimoteMessages.h"
|
#include "input/api/Wiimote/WiimoteMessages.h"
|
||||||
|
|
||||||
#ifdef HAS_HIDAPI
|
|
||||||
#include "input/api/Wiimote/hidapi/HidapiWiimote.h"
|
#include "input/api/Wiimote/hidapi/HidapiWiimote.h"
|
||||||
#elif BOOST_OS_WINDOWS
|
|
||||||
#include "input/api/Wiimote/windows/WinWiimoteDevice.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <numbers>
|
#include <numbers>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
#include "input/api/Wiimote/windows/WinWiimoteDevice.h"
|
|
||||||
|
|
||||||
#include <hidsdi.h>
|
|
||||||
#include <SetupAPI.h>
|
|
||||||
|
|
||||||
#pragma comment(lib, "Setupapi.lib")
|
|
||||||
#pragma comment(lib, "hid.lib")
|
|
||||||
|
|
||||||
WinWiimoteDevice::WinWiimoteDevice(HANDLE handle, std::vector<uint8_t> identifier)
|
|
||||||
: m_handle(handle), m_identifier(std::move(identifier))
|
|
||||||
{
|
|
||||||
m_overlapped.hEvent = CreateEvent(nullptr, TRUE, TRUE, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
WinWiimoteDevice::~WinWiimoteDevice()
|
|
||||||
{
|
|
||||||
CancelIo(m_handle);
|
|
||||||
ResetEvent(m_overlapped.hEvent);
|
|
||||||
CloseHandle(m_handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WinWiimoteDevice::write_data(const std::vector<uint8>& data)
|
|
||||||
{
|
|
||||||
return HidD_SetOutputReport(m_handle, (void*)data.data(), (ULONG)data.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::vector<uint8_t>> WinWiimoteDevice::read_data()
|
|
||||||
{
|
|
||||||
DWORD read = 0;
|
|
||||||
std::array<uint8_t, 32> buffer{};
|
|
||||||
|
|
||||||
if (!ReadFile(m_handle, buffer.data(), (DWORD)buffer.size(), &read, &m_overlapped))
|
|
||||||
{
|
|
||||||
const auto error = GetLastError();
|
|
||||||
if (error == ERROR_DEVICE_NOT_CONNECTED)
|
|
||||||
return {};
|
|
||||||
else if (error == ERROR_IO_PENDING)
|
|
||||||
{
|
|
||||||
const auto wait_result = WaitForSingleObject(m_overlapped.hEvent, 100);
|
|
||||||
if (wait_result == WAIT_TIMEOUT)
|
|
||||||
{
|
|
||||||
CancelIo(m_handle);
|
|
||||||
ResetEvent(m_overlapped.hEvent);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
else if (wait_result == WAIT_FAILED)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
if (GetOverlappedResult(m_handle, &m_overlapped, &read, FALSE) == FALSE)
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
else if (error == ERROR_INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
ResetEvent(m_overlapped.hEvent);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cemu_assert_debug(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ResetEvent(m_overlapped.hEvent);
|
|
||||||
if (read == 0)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
return {{buffer.cbegin(), buffer.cbegin() + read}};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<WiimoteDevicePtr> WinWiimoteDevice::get_devices()
|
|
||||||
{
|
|
||||||
std::vector<WiimoteDevicePtr> result;
|
|
||||||
|
|
||||||
GUID hid_guid;
|
|
||||||
HidD_GetHidGuid(&hid_guid);
|
|
||||||
|
|
||||||
const auto device_info = SetupDiGetClassDevs(&hid_guid, nullptr, nullptr, (DIGCF_DEVICEINTERFACE | DIGCF_PRESENT));
|
|
||||||
|
|
||||||
for (DWORD index = 0; ; ++index)
|
|
||||||
{
|
|
||||||
SP_DEVICE_INTERFACE_DATA device_data{};
|
|
||||||
device_data.cbSize = sizeof(device_data);
|
|
||||||
if (SetupDiEnumDeviceInterfaces(device_info, nullptr, &hid_guid, index, &device_data) == FALSE)
|
|
||||||
break;
|
|
||||||
|
|
||||||
DWORD device_data_len;
|
|
||||||
if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, nullptr, 0, &device_data_len, nullptr) == FALSE
|
|
||||||
&& GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
std::vector<uint8_t> detail_data_buffer;
|
|
||||||
detail_data_buffer.resize(device_data_len);
|
|
||||||
|
|
||||||
const auto detail_data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)detail_data_buffer.data();
|
|
||||||
detail_data->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
|
|
||||||
|
|
||||||
if (SetupDiGetDeviceInterfaceDetail(device_info, &device_data, detail_data, device_data_len, nullptr, nullptr)
|
|
||||||
== FALSE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
HANDLE device_handle = CreateFile(detail_data->DevicePath, (GENERIC_READ | GENERIC_WRITE),
|
|
||||||
(FILE_SHARE_READ | FILE_SHARE_WRITE), nullptr, OPEN_EXISTING,
|
|
||||||
FILE_FLAG_OVERLAPPED, nullptr);
|
|
||||||
if (device_handle == INVALID_HANDLE_VALUE)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
HIDD_ATTRIBUTES attributes{};
|
|
||||||
attributes.Size = sizeof(attributes);
|
|
||||||
if (HidD_GetAttributes(device_handle, &attributes) == FALSE)
|
|
||||||
{
|
|
||||||
CloseHandle(device_handle);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attributes.VendorID != 0x057e || (attributes.ProductID != 0x0306 && attributes.ProductID != 0x0330))
|
|
||||||
{
|
|
||||||
CloseHandle(device_handle);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.emplace_back(std::make_shared<WinWiimoteDevice>(device_handle, detail_data_buffer));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WinWiimoteDevice::operator==(WiimoteDevice& o) const
|
|
||||||
{
|
|
||||||
return m_identifier == static_cast<WinWiimoteDevice&>(o).m_identifier;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "input/api/Wiimote/WiimoteDevice.h"
|
|
||||||
|
|
||||||
class WinWiimoteDevice : public WiimoteDevice
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
WinWiimoteDevice(HANDLE handle, std::vector<uint8_t> identifier);
|
|
||||||
~WinWiimoteDevice();
|
|
||||||
|
|
||||||
bool write_data(const std::vector<uint8>& data) override;
|
|
||||||
std::optional<std::vector<uint8_t>> read_data() override;
|
|
||||||
|
|
||||||
static std::vector<WiimoteDevicePtr> get_devices();
|
|
||||||
|
|
||||||
bool operator==(WiimoteDevice& o) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
HANDLE m_handle;
|
|
||||||
OVERLAPPED m_overlapped{};
|
|
||||||
std::vector<uint8_t> m_identifier;
|
|
||||||
};
|
|
||||||
|
|
||||||
using WiimoteDevice_t = WinWiimoteDevice;
|
|
@ -26,10 +26,7 @@
|
|||||||
"boost-static-string",
|
"boost-static-string",
|
||||||
"boost-random",
|
"boost-random",
|
||||||
"fmt",
|
"fmt",
|
||||||
{
|
"hidapi",
|
||||||
"name": "hidapi",
|
|
||||||
"platform": "!windows"
|
|
||||||
},
|
|
||||||
"libpng",
|
"libpng",
|
||||||
"glm",
|
"glm",
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user